refactor: migrate wechat to user attributes and enhance users list
Migrate the hardcoded wechat field to the new extensible user attributes system and improve the users management UI. Migration: - Add migration 019 to move wechat data to user_attribute_values - Remove wechat field from User entity, DTOs, and API contracts - Clean up wechat-related code from backend and frontend UsersView enhancements: - Add text labels to action buttons (Filter Settings, Column Settings, Attributes Config) for better UX - Change status column to show colored dot + Chinese text instead of English text - Add dynamic attribute columns support with batch loading - Add column visibility settings with localStorage persistence - Add filter settings modal for search and filter preferences - Update i18n translations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,6 @@ const (
|
||||
FieldStatus = "status"
|
||||
// FieldUsername holds the string denoting the username field in the database.
|
||||
FieldUsername = "username"
|
||||
// FieldWechat holds the string denoting the wechat field in the database.
|
||||
FieldWechat = "wechat"
|
||||
// FieldNotes holds the string denoting the notes field in the database.
|
||||
FieldNotes = "notes"
|
||||
// EdgeAPIKeys holds the string denoting the api_keys edge name in mutations.
|
||||
@@ -51,6 +49,8 @@ const (
|
||||
EdgeAllowedGroups = "allowed_groups"
|
||||
// EdgeUsageLogs holds the string denoting the usage_logs edge name in mutations.
|
||||
EdgeUsageLogs = "usage_logs"
|
||||
// EdgeAttributeValues holds the string denoting the attribute_values edge name in mutations.
|
||||
EdgeAttributeValues = "attribute_values"
|
||||
// EdgeUserAllowedGroups holds the string denoting the user_allowed_groups edge name in mutations.
|
||||
EdgeUserAllowedGroups = "user_allowed_groups"
|
||||
// Table holds the table name of the user in the database.
|
||||
@@ -95,6 +95,13 @@ const (
|
||||
UsageLogsInverseTable = "usage_logs"
|
||||
// UsageLogsColumn is the table column denoting the usage_logs relation/edge.
|
||||
UsageLogsColumn = "user_id"
|
||||
// AttributeValuesTable is the table that holds the attribute_values relation/edge.
|
||||
AttributeValuesTable = "user_attribute_values"
|
||||
// AttributeValuesInverseTable is the table name for the UserAttributeValue entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "userattributevalue" package.
|
||||
AttributeValuesInverseTable = "user_attribute_values"
|
||||
// AttributeValuesColumn is the table column denoting the attribute_values relation/edge.
|
||||
AttributeValuesColumn = "user_id"
|
||||
// UserAllowedGroupsTable is the table that holds the user_allowed_groups relation/edge.
|
||||
UserAllowedGroupsTable = "user_allowed_groups"
|
||||
// UserAllowedGroupsInverseTable is the table name for the UserAllowedGroup entity.
|
||||
@@ -117,7 +124,6 @@ var Columns = []string{
|
||||
FieldConcurrency,
|
||||
FieldStatus,
|
||||
FieldUsername,
|
||||
FieldWechat,
|
||||
FieldNotes,
|
||||
}
|
||||
|
||||
@@ -171,10 +177,6 @@ var (
|
||||
DefaultUsername string
|
||||
// UsernameValidator is a validator for the "username" field. It is called by the builders before save.
|
||||
UsernameValidator func(string) error
|
||||
// DefaultWechat holds the default value on creation for the "wechat" field.
|
||||
DefaultWechat string
|
||||
// WechatValidator is a validator for the "wechat" field. It is called by the builders before save.
|
||||
WechatValidator func(string) error
|
||||
// DefaultNotes holds the default value on creation for the "notes" field.
|
||||
DefaultNotes string
|
||||
)
|
||||
@@ -237,11 +239,6 @@ func ByUsername(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUsername, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByWechat orders the results by the wechat field.
|
||||
func ByWechat(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldWechat, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByNotes orders the results by the notes field.
|
||||
func ByNotes(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldNotes, opts...).ToFunc()
|
||||
@@ -331,6 +328,20 @@ func ByUsageLogs(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
}
|
||||
}
|
||||
|
||||
// ByAttributeValuesCount orders the results by attribute_values count.
|
||||
func ByAttributeValuesCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newAttributeValuesStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByAttributeValues orders the results by attribute_values terms.
|
||||
func ByAttributeValues(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newAttributeValuesStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByUserAllowedGroupsCount orders the results by user_allowed_groups count.
|
||||
func ByUserAllowedGroupsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
@@ -386,6 +397,13 @@ func newUsageLogsStep() *sqlgraph.Step {
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, UsageLogsTable, UsageLogsColumn),
|
||||
)
|
||||
}
|
||||
func newAttributeValuesStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(AttributeValuesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, AttributeValuesTable, AttributeValuesColumn),
|
||||
)
|
||||
}
|
||||
func newUserAllowedGroupsStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
|
||||
@@ -105,11 +105,6 @@ func Username(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldUsername, v))
|
||||
}
|
||||
|
||||
// Wechat applies equality check predicate on the "wechat" field. It's identical to WechatEQ.
|
||||
func Wechat(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldWechat, v))
|
||||
}
|
||||
|
||||
// Notes applies equality check predicate on the "notes" field. It's identical to NotesEQ.
|
||||
func Notes(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldNotes, v))
|
||||
@@ -650,71 +645,6 @@ func UsernameContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldUsername, v))
|
||||
}
|
||||
|
||||
// WechatEQ applies the EQ predicate on the "wechat" field.
|
||||
func WechatEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatNEQ applies the NEQ predicate on the "wechat" field.
|
||||
func WechatNEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldNEQ(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatIn applies the In predicate on the "wechat" field.
|
||||
func WechatIn(vs ...string) predicate.User {
|
||||
return predicate.User(sql.FieldIn(FieldWechat, vs...))
|
||||
}
|
||||
|
||||
// WechatNotIn applies the NotIn predicate on the "wechat" field.
|
||||
func WechatNotIn(vs ...string) predicate.User {
|
||||
return predicate.User(sql.FieldNotIn(FieldWechat, vs...))
|
||||
}
|
||||
|
||||
// WechatGT applies the GT predicate on the "wechat" field.
|
||||
func WechatGT(v string) predicate.User {
|
||||
return predicate.User(sql.FieldGT(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatGTE applies the GTE predicate on the "wechat" field.
|
||||
func WechatGTE(v string) predicate.User {
|
||||
return predicate.User(sql.FieldGTE(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatLT applies the LT predicate on the "wechat" field.
|
||||
func WechatLT(v string) predicate.User {
|
||||
return predicate.User(sql.FieldLT(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatLTE applies the LTE predicate on the "wechat" field.
|
||||
func WechatLTE(v string) predicate.User {
|
||||
return predicate.User(sql.FieldLTE(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatContains applies the Contains predicate on the "wechat" field.
|
||||
func WechatContains(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContains(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatHasPrefix applies the HasPrefix predicate on the "wechat" field.
|
||||
func WechatHasPrefix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasPrefix(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatHasSuffix applies the HasSuffix predicate on the "wechat" field.
|
||||
func WechatHasSuffix(v string) predicate.User {
|
||||
return predicate.User(sql.FieldHasSuffix(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatEqualFold applies the EqualFold predicate on the "wechat" field.
|
||||
func WechatEqualFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEqualFold(FieldWechat, v))
|
||||
}
|
||||
|
||||
// WechatContainsFold applies the ContainsFold predicate on the "wechat" field.
|
||||
func WechatContainsFold(v string) predicate.User {
|
||||
return predicate.User(sql.FieldContainsFold(FieldWechat, v))
|
||||
}
|
||||
|
||||
// NotesEQ applies the EQ predicate on the "notes" field.
|
||||
func NotesEQ(v string) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldNotes, v))
|
||||
@@ -918,6 +848,29 @@ func HasUsageLogsWith(preds ...predicate.UsageLog) predicate.User {
|
||||
})
|
||||
}
|
||||
|
||||
// HasAttributeValues applies the HasEdge predicate on the "attribute_values" edge.
|
||||
func HasAttributeValues() predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, AttributeValuesTable, AttributeValuesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasAttributeValuesWith applies the HasEdge predicate on the "attribute_values" edge with a given conditions (other predicates).
|
||||
func HasAttributeValuesWith(preds ...predicate.UserAttributeValue) predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
step := newAttributeValuesStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasUserAllowedGroups applies the HasEdge predicate on the "user_allowed_groups" edge.
|
||||
func HasUserAllowedGroups() predicate.User {
|
||||
return predicate.User(func(s *sql.Selector) {
|
||||
|
||||
Reference in New Issue
Block a user