Merge branch 'Wei-Shaw:main' into main

This commit is contained in:
程序猿MT
2026-01-05 17:12:09 +08:00
committed by GitHub
26 changed files with 437 additions and 39 deletions

View File

@@ -27,6 +27,8 @@ type Account struct {
DeletedAt *time.Time `json:"deleted_at,omitempty"` DeletedAt *time.Time `json:"deleted_at,omitempty"`
// Name holds the value of the "name" field. // Name holds the value of the "name" field.
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
// Notes holds the value of the "notes" field.
Notes *string `json:"notes,omitempty"`
// Platform holds the value of the "platform" field. // Platform holds the value of the "platform" field.
Platform string `json:"platform,omitempty"` Platform string `json:"platform,omitempty"`
// Type holds the value of the "type" field. // Type holds the value of the "type" field.
@@ -131,7 +133,7 @@ func (*Account) scanValues(columns []string) ([]any, error) {
values[i] = new(sql.NullBool) values[i] = new(sql.NullBool)
case account.FieldID, account.FieldProxyID, account.FieldConcurrency, account.FieldPriority: case account.FieldID, account.FieldProxyID, account.FieldConcurrency, account.FieldPriority:
values[i] = new(sql.NullInt64) values[i] = new(sql.NullInt64)
case account.FieldName, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldSessionWindowStatus: case account.FieldName, account.FieldNotes, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldSessionWindowStatus:
values[i] = new(sql.NullString) values[i] = new(sql.NullString)
case account.FieldCreatedAt, account.FieldUpdatedAt, account.FieldDeletedAt, account.FieldLastUsedAt, account.FieldRateLimitedAt, account.FieldRateLimitResetAt, account.FieldOverloadUntil, account.FieldSessionWindowStart, account.FieldSessionWindowEnd: case account.FieldCreatedAt, account.FieldUpdatedAt, account.FieldDeletedAt, account.FieldLastUsedAt, account.FieldRateLimitedAt, account.FieldRateLimitResetAt, account.FieldOverloadUntil, account.FieldSessionWindowStart, account.FieldSessionWindowEnd:
values[i] = new(sql.NullTime) values[i] = new(sql.NullTime)
@@ -181,6 +183,13 @@ func (_m *Account) assignValues(columns []string, values []any) error {
} else if value.Valid { } else if value.Valid {
_m.Name = value.String _m.Name = value.String
} }
case account.FieldNotes:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field notes", values[i])
} else if value.Valid {
_m.Notes = new(string)
*_m.Notes = value.String
}
case account.FieldPlatform: case account.FieldPlatform:
if value, ok := values[i].(*sql.NullString); !ok { if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field platform", values[i]) return fmt.Errorf("unexpected type %T for field platform", values[i])
@@ -366,6 +375,11 @@ func (_m *Account) String() string {
builder.WriteString("name=") builder.WriteString("name=")
builder.WriteString(_m.Name) builder.WriteString(_m.Name)
builder.WriteString(", ") builder.WriteString(", ")
if v := _m.Notes; v != nil {
builder.WriteString("notes=")
builder.WriteString(*v)
}
builder.WriteString(", ")
builder.WriteString("platform=") builder.WriteString("platform=")
builder.WriteString(_m.Platform) builder.WriteString(_m.Platform)
builder.WriteString(", ") builder.WriteString(", ")

View File

@@ -23,6 +23,8 @@ const (
FieldDeletedAt = "deleted_at" FieldDeletedAt = "deleted_at"
// FieldName holds the string denoting the name field in the database. // FieldName holds the string denoting the name field in the database.
FieldName = "name" FieldName = "name"
// FieldNotes holds the string denoting the notes field in the database.
FieldNotes = "notes"
// FieldPlatform holds the string denoting the platform field in the database. // FieldPlatform holds the string denoting the platform field in the database.
FieldPlatform = "platform" FieldPlatform = "platform"
// FieldType holds the string denoting the type field in the database. // FieldType holds the string denoting the type field in the database.
@@ -102,6 +104,7 @@ var Columns = []string{
FieldUpdatedAt, FieldUpdatedAt,
FieldDeletedAt, FieldDeletedAt,
FieldName, FieldName,
FieldNotes,
FieldPlatform, FieldPlatform,
FieldType, FieldType,
FieldCredentials, FieldCredentials,
@@ -203,6 +206,11 @@ func ByName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldName, opts...).ToFunc() return sql.OrderByField(FieldName, opts...).ToFunc()
} }
// ByNotes orders the results by the notes field.
func ByNotes(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldNotes, opts...).ToFunc()
}
// ByPlatform orders the results by the platform field. // ByPlatform orders the results by the platform field.
func ByPlatform(opts ...sql.OrderTermOption) OrderOption { func ByPlatform(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldPlatform, opts...).ToFunc() return sql.OrderByField(FieldPlatform, opts...).ToFunc()

View File

@@ -75,6 +75,11 @@ func Name(v string) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldName, v)) return predicate.Account(sql.FieldEQ(FieldName, v))
} }
// Notes applies equality check predicate on the "notes" field. It's identical to NotesEQ.
func Notes(v string) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldNotes, v))
}
// Platform applies equality check predicate on the "platform" field. It's identical to PlatformEQ. // Platform applies equality check predicate on the "platform" field. It's identical to PlatformEQ.
func Platform(v string) predicate.Account { func Platform(v string) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldPlatform, v)) return predicate.Account(sql.FieldEQ(FieldPlatform, v))
@@ -345,6 +350,81 @@ func NameContainsFold(v string) predicate.Account {
return predicate.Account(sql.FieldContainsFold(FieldName, v)) return predicate.Account(sql.FieldContainsFold(FieldName, v))
} }
// NotesEQ applies the EQ predicate on the "notes" field.
func NotesEQ(v string) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldNotes, v))
}
// NotesNEQ applies the NEQ predicate on the "notes" field.
func NotesNEQ(v string) predicate.Account {
return predicate.Account(sql.FieldNEQ(FieldNotes, v))
}
// NotesIn applies the In predicate on the "notes" field.
func NotesIn(vs ...string) predicate.Account {
return predicate.Account(sql.FieldIn(FieldNotes, vs...))
}
// NotesNotIn applies the NotIn predicate on the "notes" field.
func NotesNotIn(vs ...string) predicate.Account {
return predicate.Account(sql.FieldNotIn(FieldNotes, vs...))
}
// NotesGT applies the GT predicate on the "notes" field.
func NotesGT(v string) predicate.Account {
return predicate.Account(sql.FieldGT(FieldNotes, v))
}
// NotesGTE applies the GTE predicate on the "notes" field.
func NotesGTE(v string) predicate.Account {
return predicate.Account(sql.FieldGTE(FieldNotes, v))
}
// NotesLT applies the LT predicate on the "notes" field.
func NotesLT(v string) predicate.Account {
return predicate.Account(sql.FieldLT(FieldNotes, v))
}
// NotesLTE applies the LTE predicate on the "notes" field.
func NotesLTE(v string) predicate.Account {
return predicate.Account(sql.FieldLTE(FieldNotes, v))
}
// NotesContains applies the Contains predicate on the "notes" field.
func NotesContains(v string) predicate.Account {
return predicate.Account(sql.FieldContains(FieldNotes, v))
}
// NotesHasPrefix applies the HasPrefix predicate on the "notes" field.
func NotesHasPrefix(v string) predicate.Account {
return predicate.Account(sql.FieldHasPrefix(FieldNotes, v))
}
// NotesHasSuffix applies the HasSuffix predicate on the "notes" field.
func NotesHasSuffix(v string) predicate.Account {
return predicate.Account(sql.FieldHasSuffix(FieldNotes, v))
}
// NotesIsNil applies the IsNil predicate on the "notes" field.
func NotesIsNil() predicate.Account {
return predicate.Account(sql.FieldIsNull(FieldNotes))
}
// NotesNotNil applies the NotNil predicate on the "notes" field.
func NotesNotNil() predicate.Account {
return predicate.Account(sql.FieldNotNull(FieldNotes))
}
// NotesEqualFold applies the EqualFold predicate on the "notes" field.
func NotesEqualFold(v string) predicate.Account {
return predicate.Account(sql.FieldEqualFold(FieldNotes, v))
}
// NotesContainsFold applies the ContainsFold predicate on the "notes" field.
func NotesContainsFold(v string) predicate.Account {
return predicate.Account(sql.FieldContainsFold(FieldNotes, v))
}
// PlatformEQ applies the EQ predicate on the "platform" field. // PlatformEQ applies the EQ predicate on the "platform" field.
func PlatformEQ(v string) predicate.Account { func PlatformEQ(v string) predicate.Account {
return predicate.Account(sql.FieldEQ(FieldPlatform, v)) return predicate.Account(sql.FieldEQ(FieldPlatform, v))

View File

@@ -73,6 +73,20 @@ func (_c *AccountCreate) SetName(v string) *AccountCreate {
return _c return _c
} }
// SetNotes sets the "notes" field.
func (_c *AccountCreate) SetNotes(v string) *AccountCreate {
_c.mutation.SetNotes(v)
return _c
}
// SetNillableNotes sets the "notes" field if the given value is not nil.
func (_c *AccountCreate) SetNillableNotes(v *string) *AccountCreate {
if v != nil {
_c.SetNotes(*v)
}
return _c
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (_c *AccountCreate) SetPlatform(v string) *AccountCreate { func (_c *AccountCreate) SetPlatform(v string) *AccountCreate {
_c.mutation.SetPlatform(v) _c.mutation.SetPlatform(v)
@@ -501,6 +515,10 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
_spec.SetField(account.FieldName, field.TypeString, value) _spec.SetField(account.FieldName, field.TypeString, value)
_node.Name = value _node.Name = value
} }
if value, ok := _c.mutation.Notes(); ok {
_spec.SetField(account.FieldNotes, field.TypeString, value)
_node.Notes = &value
}
if value, ok := _c.mutation.Platform(); ok { if value, ok := _c.mutation.Platform(); ok {
_spec.SetField(account.FieldPlatform, field.TypeString, value) _spec.SetField(account.FieldPlatform, field.TypeString, value)
_node.Platform = value _node.Platform = value
@@ -712,6 +730,24 @@ func (u *AccountUpsert) UpdateName() *AccountUpsert {
return u return u
} }
// SetNotes sets the "notes" field.
func (u *AccountUpsert) SetNotes(v string) *AccountUpsert {
u.Set(account.FieldNotes, v)
return u
}
// UpdateNotes sets the "notes" field to the value that was provided on create.
func (u *AccountUpsert) UpdateNotes() *AccountUpsert {
u.SetExcluded(account.FieldNotes)
return u
}
// ClearNotes clears the value of the "notes" field.
func (u *AccountUpsert) ClearNotes() *AccountUpsert {
u.SetNull(account.FieldNotes)
return u
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (u *AccountUpsert) SetPlatform(v string) *AccountUpsert { func (u *AccountUpsert) SetPlatform(v string) *AccountUpsert {
u.Set(account.FieldPlatform, v) u.Set(account.FieldPlatform, v)
@@ -1076,6 +1112,27 @@ func (u *AccountUpsertOne) UpdateName() *AccountUpsertOne {
}) })
} }
// SetNotes sets the "notes" field.
func (u *AccountUpsertOne) SetNotes(v string) *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.SetNotes(v)
})
}
// UpdateNotes sets the "notes" field to the value that was provided on create.
func (u *AccountUpsertOne) UpdateNotes() *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.UpdateNotes()
})
}
// ClearNotes clears the value of the "notes" field.
func (u *AccountUpsertOne) ClearNotes() *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) {
s.ClearNotes()
})
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (u *AccountUpsertOne) SetPlatform(v string) *AccountUpsertOne { func (u *AccountUpsertOne) SetPlatform(v string) *AccountUpsertOne {
return u.Update(func(s *AccountUpsert) { return u.Update(func(s *AccountUpsert) {
@@ -1651,6 +1708,27 @@ func (u *AccountUpsertBulk) UpdateName() *AccountUpsertBulk {
}) })
} }
// SetNotes sets the "notes" field.
func (u *AccountUpsertBulk) SetNotes(v string) *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.SetNotes(v)
})
}
// UpdateNotes sets the "notes" field to the value that was provided on create.
func (u *AccountUpsertBulk) UpdateNotes() *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.UpdateNotes()
})
}
// ClearNotes clears the value of the "notes" field.
func (u *AccountUpsertBulk) ClearNotes() *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) {
s.ClearNotes()
})
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (u *AccountUpsertBulk) SetPlatform(v string) *AccountUpsertBulk { func (u *AccountUpsertBulk) SetPlatform(v string) *AccountUpsertBulk {
return u.Update(func(s *AccountUpsert) { return u.Update(func(s *AccountUpsert) {

View File

@@ -71,6 +71,26 @@ func (_u *AccountUpdate) SetNillableName(v *string) *AccountUpdate {
return _u return _u
} }
// SetNotes sets the "notes" field.
func (_u *AccountUpdate) SetNotes(v string) *AccountUpdate {
_u.mutation.SetNotes(v)
return _u
}
// SetNillableNotes sets the "notes" field if the given value is not nil.
func (_u *AccountUpdate) SetNillableNotes(v *string) *AccountUpdate {
if v != nil {
_u.SetNotes(*v)
}
return _u
}
// ClearNotes clears the value of the "notes" field.
func (_u *AccountUpdate) ClearNotes() *AccountUpdate {
_u.mutation.ClearNotes()
return _u
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (_u *AccountUpdate) SetPlatform(v string) *AccountUpdate { func (_u *AccountUpdate) SetPlatform(v string) *AccountUpdate {
_u.mutation.SetPlatform(v) _u.mutation.SetPlatform(v)
@@ -545,6 +565,12 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
if value, ok := _u.mutation.Name(); ok { if value, ok := _u.mutation.Name(); ok {
_spec.SetField(account.FieldName, field.TypeString, value) _spec.SetField(account.FieldName, field.TypeString, value)
} }
if value, ok := _u.mutation.Notes(); ok {
_spec.SetField(account.FieldNotes, field.TypeString, value)
}
if _u.mutation.NotesCleared() {
_spec.ClearField(account.FieldNotes, field.TypeString)
}
if value, ok := _u.mutation.Platform(); ok { if value, ok := _u.mutation.Platform(); ok {
_spec.SetField(account.FieldPlatform, field.TypeString, value) _spec.SetField(account.FieldPlatform, field.TypeString, value)
} }
@@ -814,6 +840,26 @@ func (_u *AccountUpdateOne) SetNillableName(v *string) *AccountUpdateOne {
return _u return _u
} }
// SetNotes sets the "notes" field.
func (_u *AccountUpdateOne) SetNotes(v string) *AccountUpdateOne {
_u.mutation.SetNotes(v)
return _u
}
// SetNillableNotes sets the "notes" field if the given value is not nil.
func (_u *AccountUpdateOne) SetNillableNotes(v *string) *AccountUpdateOne {
if v != nil {
_u.SetNotes(*v)
}
return _u
}
// ClearNotes clears the value of the "notes" field.
func (_u *AccountUpdateOne) ClearNotes() *AccountUpdateOne {
_u.mutation.ClearNotes()
return _u
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (_u *AccountUpdateOne) SetPlatform(v string) *AccountUpdateOne { func (_u *AccountUpdateOne) SetPlatform(v string) *AccountUpdateOne {
_u.mutation.SetPlatform(v) _u.mutation.SetPlatform(v)
@@ -1318,6 +1364,12 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
if value, ok := _u.mutation.Name(); ok { if value, ok := _u.mutation.Name(); ok {
_spec.SetField(account.FieldName, field.TypeString, value) _spec.SetField(account.FieldName, field.TypeString, value)
} }
if value, ok := _u.mutation.Notes(); ok {
_spec.SetField(account.FieldNotes, field.TypeString, value)
}
if _u.mutation.NotesCleared() {
_spec.ClearField(account.FieldNotes, field.TypeString)
}
if value, ok := _u.mutation.Platform(); ok { if value, ok := _u.mutation.Platform(); ok {
_spec.SetField(account.FieldPlatform, field.TypeString, value) _spec.SetField(account.FieldPlatform, field.TypeString, value)
} }

View File

@@ -70,6 +70,7 @@ var (
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
{Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}}, {Name: "deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
{Name: "name", Type: field.TypeString, Size: 100}, {Name: "name", Type: field.TypeString, Size: 100},
{Name: "notes", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
{Name: "platform", Type: field.TypeString, Size: 50}, {Name: "platform", Type: field.TypeString, Size: 50},
{Name: "type", Type: field.TypeString, Size: 20}, {Name: "type", Type: field.TypeString, Size: 20},
{Name: "credentials", Type: field.TypeJSON, SchemaType: map[string]string{"postgres": "jsonb"}}, {Name: "credentials", Type: field.TypeJSON, SchemaType: map[string]string{"postgres": "jsonb"}},
@@ -96,7 +97,7 @@ var (
ForeignKeys: []*schema.ForeignKey{ ForeignKeys: []*schema.ForeignKey{
{ {
Symbol: "accounts_proxies_proxy", Symbol: "accounts_proxies_proxy",
Columns: []*schema.Column{AccountsColumns[21]}, Columns: []*schema.Column{AccountsColumns[22]},
RefColumns: []*schema.Column{ProxiesColumns[0]}, RefColumns: []*schema.Column{ProxiesColumns[0]},
OnDelete: schema.SetNull, OnDelete: schema.SetNull,
}, },
@@ -105,52 +106,52 @@ var (
{ {
Name: "account_platform", Name: "account_platform",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[5]}, Columns: []*schema.Column{AccountsColumns[6]},
}, },
{ {
Name: "account_type", Name: "account_type",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[6]}, Columns: []*schema.Column{AccountsColumns[7]},
}, },
{ {
Name: "account_status", Name: "account_status",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[11]}, Columns: []*schema.Column{AccountsColumns[12]},
}, },
{ {
Name: "account_proxy_id", Name: "account_proxy_id",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[21]}, Columns: []*schema.Column{AccountsColumns[22]},
}, },
{ {
Name: "account_priority", Name: "account_priority",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[10]}, Columns: []*schema.Column{AccountsColumns[11]},
}, },
{ {
Name: "account_last_used_at", Name: "account_last_used_at",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[13]}, Columns: []*schema.Column{AccountsColumns[14]},
}, },
{ {
Name: "account_schedulable", Name: "account_schedulable",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[14]}, Columns: []*schema.Column{AccountsColumns[15]},
}, },
{ {
Name: "account_rate_limited_at", Name: "account_rate_limited_at",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[15]}, Columns: []*schema.Column{AccountsColumns[16]},
}, },
{ {
Name: "account_rate_limit_reset_at", Name: "account_rate_limit_reset_at",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[16]}, Columns: []*schema.Column{AccountsColumns[17]},
}, },
{ {
Name: "account_overload_until", Name: "account_overload_until",
Unique: false, Unique: false,
Columns: []*schema.Column{AccountsColumns[17]}, Columns: []*schema.Column{AccountsColumns[18]},
}, },
{ {
Name: "account_deleted_at", Name: "account_deleted_at",

View File

@@ -994,6 +994,7 @@ type AccountMutation struct {
updated_at *time.Time updated_at *time.Time
deleted_at *time.Time deleted_at *time.Time
name *string name *string
notes *string
platform *string platform *string
_type *string _type *string
credentials *map[string]interface{} credentials *map[string]interface{}
@@ -1281,6 +1282,55 @@ func (m *AccountMutation) ResetName() {
m.name = nil m.name = nil
} }
// SetNotes sets the "notes" field.
func (m *AccountMutation) SetNotes(s string) {
m.notes = &s
}
// Notes returns the value of the "notes" field in the mutation.
func (m *AccountMutation) Notes() (r string, exists bool) {
v := m.notes
if v == nil {
return
}
return *v, true
}
// OldNotes returns the old "notes" field's value of the Account entity.
// If the Account object wasn't provided to the builder, the object is fetched from the database.
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
func (m *AccountMutation) OldNotes(ctx context.Context) (v *string, err error) {
if !m.op.Is(OpUpdateOne) {
return v, errors.New("OldNotes is only allowed on UpdateOne operations")
}
if m.id == nil || m.oldValue == nil {
return v, errors.New("OldNotes requires an ID field in the mutation")
}
oldValue, err := m.oldValue(ctx)
if err != nil {
return v, fmt.Errorf("querying old value for OldNotes: %w", err)
}
return oldValue.Notes, nil
}
// ClearNotes clears the value of the "notes" field.
func (m *AccountMutation) ClearNotes() {
m.notes = nil
m.clearedFields[account.FieldNotes] = struct{}{}
}
// NotesCleared returns if the "notes" field was cleared in this mutation.
func (m *AccountMutation) NotesCleared() bool {
_, ok := m.clearedFields[account.FieldNotes]
return ok
}
// ResetNotes resets all changes to the "notes" field.
func (m *AccountMutation) ResetNotes() {
m.notes = nil
delete(m.clearedFields, account.FieldNotes)
}
// SetPlatform sets the "platform" field. // SetPlatform sets the "platform" field.
func (m *AccountMutation) SetPlatform(s string) { func (m *AccountMutation) SetPlatform(s string) {
m.platform = &s m.platform = &s
@@ -2219,7 +2269,7 @@ func (m *AccountMutation) Type() string {
// order to get all numeric fields that were incremented/decremented, call // order to get all numeric fields that were incremented/decremented, call
// AddedFields(). // AddedFields().
func (m *AccountMutation) Fields() []string { func (m *AccountMutation) Fields() []string {
fields := make([]string, 0, 21) fields := make([]string, 0, 22)
if m.created_at != nil { if m.created_at != nil {
fields = append(fields, account.FieldCreatedAt) fields = append(fields, account.FieldCreatedAt)
} }
@@ -2232,6 +2282,9 @@ func (m *AccountMutation) Fields() []string {
if m.name != nil { if m.name != nil {
fields = append(fields, account.FieldName) fields = append(fields, account.FieldName)
} }
if m.notes != nil {
fields = append(fields, account.FieldNotes)
}
if m.platform != nil { if m.platform != nil {
fields = append(fields, account.FieldPlatform) fields = append(fields, account.FieldPlatform)
} }
@@ -2299,6 +2352,8 @@ func (m *AccountMutation) Field(name string) (ent.Value, bool) {
return m.DeletedAt() return m.DeletedAt()
case account.FieldName: case account.FieldName:
return m.Name() return m.Name()
case account.FieldNotes:
return m.Notes()
case account.FieldPlatform: case account.FieldPlatform:
return m.Platform() return m.Platform()
case account.FieldType: case account.FieldType:
@@ -2350,6 +2405,8 @@ func (m *AccountMutation) OldField(ctx context.Context, name string) (ent.Value,
return m.OldDeletedAt(ctx) return m.OldDeletedAt(ctx)
case account.FieldName: case account.FieldName:
return m.OldName(ctx) return m.OldName(ctx)
case account.FieldNotes:
return m.OldNotes(ctx)
case account.FieldPlatform: case account.FieldPlatform:
return m.OldPlatform(ctx) return m.OldPlatform(ctx)
case account.FieldType: case account.FieldType:
@@ -2421,6 +2478,13 @@ func (m *AccountMutation) SetField(name string, value ent.Value) error {
} }
m.SetName(v) m.SetName(v)
return nil return nil
case account.FieldNotes:
v, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected type %T for field %s", value, name)
}
m.SetNotes(v)
return nil
case account.FieldPlatform: case account.FieldPlatform:
v, ok := value.(string) v, ok := value.(string)
if !ok { if !ok {
@@ -2600,6 +2664,9 @@ func (m *AccountMutation) ClearedFields() []string {
if m.FieldCleared(account.FieldDeletedAt) { if m.FieldCleared(account.FieldDeletedAt) {
fields = append(fields, account.FieldDeletedAt) fields = append(fields, account.FieldDeletedAt)
} }
if m.FieldCleared(account.FieldNotes) {
fields = append(fields, account.FieldNotes)
}
if m.FieldCleared(account.FieldProxyID) { if m.FieldCleared(account.FieldProxyID) {
fields = append(fields, account.FieldProxyID) fields = append(fields, account.FieldProxyID)
} }
@@ -2644,6 +2711,9 @@ func (m *AccountMutation) ClearField(name string) error {
case account.FieldDeletedAt: case account.FieldDeletedAt:
m.ClearDeletedAt() m.ClearDeletedAt()
return nil return nil
case account.FieldNotes:
m.ClearNotes()
return nil
case account.FieldProxyID: case account.FieldProxyID:
m.ClearProxyID() m.ClearProxyID()
return nil return nil
@@ -2691,6 +2761,9 @@ func (m *AccountMutation) ResetField(name string) error {
case account.FieldName: case account.FieldName:
m.ResetName() m.ResetName()
return nil return nil
case account.FieldNotes:
m.ResetNotes()
return nil
case account.FieldPlatform: case account.FieldPlatform:
m.ResetPlatform() m.ResetPlatform()
return nil return nil

View File

@@ -124,7 +124,7 @@ func init() {
} }
}() }()
// accountDescPlatform is the schema descriptor for platform field. // accountDescPlatform is the schema descriptor for platform field.
accountDescPlatform := accountFields[1].Descriptor() accountDescPlatform := accountFields[2].Descriptor()
// account.PlatformValidator is a validator for the "platform" field. It is called by the builders before save. // account.PlatformValidator is a validator for the "platform" field. It is called by the builders before save.
account.PlatformValidator = func() func(string) error { account.PlatformValidator = func() func(string) error {
validators := accountDescPlatform.Validators validators := accountDescPlatform.Validators
@@ -142,7 +142,7 @@ func init() {
} }
}() }()
// accountDescType is the schema descriptor for type field. // accountDescType is the schema descriptor for type field.
accountDescType := accountFields[2].Descriptor() accountDescType := accountFields[3].Descriptor()
// account.TypeValidator is a validator for the "type" field. It is called by the builders before save. // account.TypeValidator is a validator for the "type" field. It is called by the builders before save.
account.TypeValidator = func() func(string) error { account.TypeValidator = func() func(string) error {
validators := accountDescType.Validators validators := accountDescType.Validators
@@ -160,33 +160,33 @@ func init() {
} }
}() }()
// accountDescCredentials is the schema descriptor for credentials field. // accountDescCredentials is the schema descriptor for credentials field.
accountDescCredentials := accountFields[3].Descriptor() accountDescCredentials := accountFields[4].Descriptor()
// account.DefaultCredentials holds the default value on creation for the credentials field. // account.DefaultCredentials holds the default value on creation for the credentials field.
account.DefaultCredentials = accountDescCredentials.Default.(func() map[string]interface{}) account.DefaultCredentials = accountDescCredentials.Default.(func() map[string]interface{})
// accountDescExtra is the schema descriptor for extra field. // accountDescExtra is the schema descriptor for extra field.
accountDescExtra := accountFields[4].Descriptor() accountDescExtra := accountFields[5].Descriptor()
// account.DefaultExtra holds the default value on creation for the extra field. // account.DefaultExtra holds the default value on creation for the extra field.
account.DefaultExtra = accountDescExtra.Default.(func() map[string]interface{}) account.DefaultExtra = accountDescExtra.Default.(func() map[string]interface{})
// accountDescConcurrency is the schema descriptor for concurrency field. // accountDescConcurrency is the schema descriptor for concurrency field.
accountDescConcurrency := accountFields[6].Descriptor() accountDescConcurrency := accountFields[7].Descriptor()
// account.DefaultConcurrency holds the default value on creation for the concurrency field. // account.DefaultConcurrency holds the default value on creation for the concurrency field.
account.DefaultConcurrency = accountDescConcurrency.Default.(int) account.DefaultConcurrency = accountDescConcurrency.Default.(int)
// accountDescPriority is the schema descriptor for priority field. // accountDescPriority is the schema descriptor for priority field.
accountDescPriority := accountFields[7].Descriptor() accountDescPriority := accountFields[8].Descriptor()
// account.DefaultPriority holds the default value on creation for the priority field. // account.DefaultPriority holds the default value on creation for the priority field.
account.DefaultPriority = accountDescPriority.Default.(int) account.DefaultPriority = accountDescPriority.Default.(int)
// accountDescStatus is the schema descriptor for status field. // accountDescStatus is the schema descriptor for status field.
accountDescStatus := accountFields[8].Descriptor() accountDescStatus := accountFields[9].Descriptor()
// account.DefaultStatus holds the default value on creation for the status field. // account.DefaultStatus holds the default value on creation for the status field.
account.DefaultStatus = accountDescStatus.Default.(string) account.DefaultStatus = accountDescStatus.Default.(string)
// account.StatusValidator is a validator for the "status" field. It is called by the builders before save. // account.StatusValidator is a validator for the "status" field. It is called by the builders before save.
account.StatusValidator = accountDescStatus.Validators[0].(func(string) error) account.StatusValidator = accountDescStatus.Validators[0].(func(string) error)
// accountDescSchedulable is the schema descriptor for schedulable field. // accountDescSchedulable is the schema descriptor for schedulable field.
accountDescSchedulable := accountFields[11].Descriptor() accountDescSchedulable := accountFields[12].Descriptor()
// account.DefaultSchedulable holds the default value on creation for the schedulable field. // account.DefaultSchedulable holds the default value on creation for the schedulable field.
account.DefaultSchedulable = accountDescSchedulable.Default.(bool) account.DefaultSchedulable = accountDescSchedulable.Default.(bool)
// accountDescSessionWindowStatus is the schema descriptor for session_window_status field. // accountDescSessionWindowStatus is the schema descriptor for session_window_status field.
accountDescSessionWindowStatus := accountFields[17].Descriptor() accountDescSessionWindowStatus := accountFields[18].Descriptor()
// account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save. // account.SessionWindowStatusValidator is a validator for the "session_window_status" field. It is called by the builders before save.
account.SessionWindowStatusValidator = accountDescSessionWindowStatus.Validators[0].(func(string) error) account.SessionWindowStatusValidator = accountDescSessionWindowStatus.Validators[0].(func(string) error)
accountgroupFields := schema.AccountGroup{}.Fields() accountgroupFields := schema.AccountGroup{}.Fields()

View File

@@ -54,6 +54,11 @@ func (Account) Fields() []ent.Field {
field.String("name"). field.String("name").
MaxLen(100). MaxLen(100).
NotEmpty(), NotEmpty(),
// notes: 管理员备注(可为空)
field.String("notes").
Optional().
Nillable().
SchemaType(map[string]string{dialect.Postgres: "text"}),
// platform: 所属平台,如 "claude", "gemini", "openai" 等 // platform: 所属平台,如 "claude", "gemini", "openai" 等
field.String("platform"). field.String("platform").

View File

@@ -73,6 +73,7 @@ func NewAccountHandler(
// CreateAccountRequest represents create account request // CreateAccountRequest represents create account request
type CreateAccountRequest struct { type CreateAccountRequest struct {
Name string `json:"name" binding:"required"` Name string `json:"name" binding:"required"`
Notes *string `json:"notes"`
Platform string `json:"platform" binding:"required"` Platform string `json:"platform" binding:"required"`
Type string `json:"type" binding:"required,oneof=oauth setup-token apikey"` Type string `json:"type" binding:"required,oneof=oauth setup-token apikey"`
Credentials map[string]any `json:"credentials" binding:"required"` Credentials map[string]any `json:"credentials" binding:"required"`
@@ -88,6 +89,7 @@ type CreateAccountRequest struct {
// 使用指针类型来区分"未提供"和"设置为0" // 使用指针类型来区分"未提供"和"设置为0"
type UpdateAccountRequest struct { type UpdateAccountRequest struct {
Name string `json:"name"` Name string `json:"name"`
Notes *string `json:"notes"`
Type string `json:"type" binding:"omitempty,oneof=oauth setup-token apikey"` Type string `json:"type" binding:"omitempty,oneof=oauth setup-token apikey"`
Credentials map[string]any `json:"credentials"` Credentials map[string]any `json:"credentials"`
Extra map[string]any `json:"extra"` Extra map[string]any `json:"extra"`
@@ -190,6 +192,7 @@ func (h *AccountHandler) Create(c *gin.Context) {
account, err := h.adminService.CreateAccount(c.Request.Context(), &service.CreateAccountInput{ account, err := h.adminService.CreateAccount(c.Request.Context(), &service.CreateAccountInput{
Name: req.Name, Name: req.Name,
Notes: req.Notes,
Platform: req.Platform, Platform: req.Platform,
Type: req.Type, Type: req.Type,
Credentials: req.Credentials, Credentials: req.Credentials,
@@ -246,6 +249,7 @@ func (h *AccountHandler) Update(c *gin.Context) {
account, err := h.adminService.UpdateAccount(c.Request.Context(), accountID, &service.UpdateAccountInput{ account, err := h.adminService.UpdateAccount(c.Request.Context(), accountID, &service.UpdateAccountInput{
Name: req.Name, Name: req.Name,
Notes: req.Notes,
Type: req.Type, Type: req.Type,
Credentials: req.Credentials, Credentials: req.Credentials,
Extra: req.Extra, Extra: req.Extra,

View File

@@ -106,6 +106,7 @@ func AccountFromServiceShallow(a *service.Account) *Account {
return &Account{ return &Account{
ID: a.ID, ID: a.ID,
Name: a.Name, Name: a.Name,
Notes: a.Notes,
Platform: a.Platform, Platform: a.Platform,
Type: a.Type, Type: a.Type,
Credentials: a.Credentials, Credentials: a.Credentials,

View File

@@ -57,6 +57,7 @@ type Group struct {
type Account struct { type Account struct {
ID int64 `json:"id"` ID int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Notes *string `json:"notes"`
Platform string `json:"platform"` Platform string `json:"platform"`
Type string `json:"type"` Type string `json:"type"`
Credentials map[string]any `json:"credentials"` Credentials map[string]any `json:"credentials"`

View File

@@ -67,6 +67,7 @@ func (r *accountRepository) Create(ctx context.Context, account *service.Account
builder := r.client.Account.Create(). builder := r.client.Account.Create().
SetName(account.Name). SetName(account.Name).
SetNillableNotes(account.Notes).
SetPlatform(account.Platform). SetPlatform(account.Platform).
SetType(account.Type). SetType(account.Type).
SetCredentials(normalizeJSONMap(account.Credentials)). SetCredentials(normalizeJSONMap(account.Credentials)).
@@ -270,6 +271,7 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
builder := r.client.Account.UpdateOneID(account.ID). builder := r.client.Account.UpdateOneID(account.ID).
SetName(account.Name). SetName(account.Name).
SetNillableNotes(account.Notes).
SetPlatform(account.Platform). SetPlatform(account.Platform).
SetType(account.Type). SetType(account.Type).
SetCredentials(normalizeJSONMap(account.Credentials)). SetCredentials(normalizeJSONMap(account.Credentials)).
@@ -320,6 +322,9 @@ func (r *accountRepository) Update(ctx context.Context, account *service.Account
} else { } else {
builder.ClearSessionWindowStatus() builder.ClearSessionWindowStatus()
} }
if account.Notes == nil {
builder.ClearNotes()
}
updated, err := builder.Save(ctx) updated, err := builder.Save(ctx)
if err != nil { if err != nil {
@@ -1065,6 +1070,7 @@ func accountEntityToService(m *dbent.Account) *service.Account {
return &service.Account{ return &service.Account{
ID: m.ID, ID: m.ID,
Name: m.Name, Name: m.Name,
Notes: m.Notes,
Platform: m.Platform, Platform: m.Platform,
Type: m.Type, Type: m.Type,
Credentials: copyJSONMap(m.Credentials), Credentials: copyJSONMap(m.Credentials),

View File

@@ -26,6 +26,7 @@ func TestMigrationsRunner_IsIdempotent_AndSchemaIsUpToDate(t *testing.T) {
requireColumn(t, tx, "users", "notes", "text", 0, false) requireColumn(t, tx, "users", "notes", "text", 0, false)
// accounts: schedulable and rate-limit fields // accounts: schedulable and rate-limit fields
requireColumn(t, tx, "accounts", "notes", "text", 0, true)
requireColumn(t, tx, "accounts", "schedulable", "boolean", 0, false) requireColumn(t, tx, "accounts", "schedulable", "boolean", 0, false)
requireColumn(t, tx, "accounts", "rate_limited_at", "timestamp with time zone", 0, true) requireColumn(t, tx, "accounts", "rate_limited_at", "timestamp with time zone", 0, true)
requireColumn(t, tx, "accounts", "rate_limit_reset_at", "timestamp with time zone", 0, true) requireColumn(t, tx, "accounts", "rate_limit_reset_at", "timestamp with time zone", 0, true)

View File

@@ -11,6 +11,7 @@ import (
type Account struct { type Account struct {
ID int64 ID int64
Name string Name string
Notes *string
Platform string Platform string
Type string Type string
Credentials map[string]any Credentials map[string]any
@@ -262,6 +263,17 @@ func parseTempUnschedStrings(value any) []string {
return out return out
} }
func normalizeAccountNotes(value *string) *string {
if value == nil {
return nil
}
trimmed := strings.TrimSpace(*value)
if trimmed == "" {
return nil
}
return &trimmed
}
func parseTempUnschedInt(value any) int { func parseTempUnschedInt(value any) int {
switch v := value.(type) { switch v := value.(type) {
case int: case int:

View File

@@ -72,6 +72,7 @@ type AccountBulkUpdate struct {
// CreateAccountRequest 创建账号请求 // CreateAccountRequest 创建账号请求
type CreateAccountRequest struct { type CreateAccountRequest struct {
Name string `json:"name"` Name string `json:"name"`
Notes *string `json:"notes"`
Platform string `json:"platform"` Platform string `json:"platform"`
Type string `json:"type"` Type string `json:"type"`
Credentials map[string]any `json:"credentials"` Credentials map[string]any `json:"credentials"`
@@ -85,6 +86,7 @@ type CreateAccountRequest struct {
// UpdateAccountRequest 更新账号请求 // UpdateAccountRequest 更新账号请求
type UpdateAccountRequest struct { type UpdateAccountRequest struct {
Name *string `json:"name"` Name *string `json:"name"`
Notes *string `json:"notes"`
Credentials *map[string]any `json:"credentials"` Credentials *map[string]any `json:"credentials"`
Extra *map[string]any `json:"extra"` Extra *map[string]any `json:"extra"`
ProxyID *int64 `json:"proxy_id"` ProxyID *int64 `json:"proxy_id"`
@@ -123,6 +125,7 @@ func (s *AccountService) Create(ctx context.Context, req CreateAccountRequest) (
// 创建账号 // 创建账号
account := &Account{ account := &Account{
Name: req.Name, Name: req.Name,
Notes: normalizeAccountNotes(req.Notes),
Platform: req.Platform, Platform: req.Platform,
Type: req.Type, Type: req.Type,
Credentials: req.Credentials, Credentials: req.Credentials,
@@ -194,6 +197,9 @@ func (s *AccountService) Update(ctx context.Context, id int64, req UpdateAccount
if req.Name != nil { if req.Name != nil {
account.Name = *req.Name account.Name = *req.Name
} }
if req.Notes != nil {
account.Notes = normalizeAccountNotes(req.Notes)
}
if req.Credentials != nil { if req.Credentials != nil {
account.Credentials = *req.Credentials account.Credentials = *req.Credentials

View File

@@ -115,6 +115,7 @@ type UpdateGroupInput struct {
type CreateAccountInput struct { type CreateAccountInput struct {
Name string Name string
Notes *string
Platform string Platform string
Type string Type string
Credentials map[string]any Credentials map[string]any
@@ -130,6 +131,7 @@ type CreateAccountInput struct {
type UpdateAccountInput struct { type UpdateAccountInput struct {
Name string Name string
Notes *string
Type string // Account type: oauth, setup-token, apikey Type string // Account type: oauth, setup-token, apikey
Credentials map[string]any Credentials map[string]any
Extra map[string]any Extra map[string]any
@@ -653,6 +655,7 @@ func (s *adminServiceImpl) CreateAccount(ctx context.Context, input *CreateAccou
account := &Account{ account := &Account{
Name: input.Name, Name: input.Name,
Notes: normalizeAccountNotes(input.Notes),
Platform: input.Platform, Platform: input.Platform,
Type: input.Type, Type: input.Type,
Credentials: input.Credentials, Credentials: input.Credentials,
@@ -689,6 +692,9 @@ func (s *adminServiceImpl) UpdateAccount(ctx context.Context, id int64, input *U
if input.Type != "" { if input.Type != "" {
account.Type = input.Type account.Type = input.Type
} }
if input.Notes != nil {
account.Notes = normalizeAccountNotes(input.Notes)
}
if len(input.Credentials) > 0 { if len(input.Credentials) > 0 {
account.Credentials = input.Credentials account.Credentials = input.Credentials
} }

View File

@@ -0,0 +1,7 @@
-- 028_add_account_notes.sql
-- Add optional admin notes for accounts.
ALTER TABLE accounts
ADD COLUMN IF NOT EXISTS notes TEXT;
COMMENT ON COLUMN accounts.notes IS 'Admin-only notes for account';

View File

@@ -56,6 +56,16 @@
data-tour="account-form-name" data-tour="account-form-name"
/> />
</div> </div>
<div>
<label class="input-label">{{ t('admin.accounts.notes') }}</label>
<textarea
v-model="form.notes"
rows="3"
class="input"
:placeholder="t('admin.accounts.notesPlaceholder')"
></textarea>
<p class="input-hint">{{ t('admin.accounts.notesHint') }}</p>
</div>
<!-- Platform Selection - Segmented Control Style --> <!-- Platform Selection - Segmented Control Style -->
<div> <div>
@@ -1917,6 +1927,7 @@ const tempUnschedPresets = computed(() => [
const form = reactive({ const form = reactive({
name: '', name: '',
notes: '',
platform: 'anthropic' as AccountPlatform, platform: 'anthropic' as AccountPlatform,
type: 'oauth' as AccountType, // Will be 'oauth', 'setup-token', or 'apikey' type: 'oauth' as AccountType, // Will be 'oauth', 'setup-token', or 'apikey'
credentials: {} as Record<string, unknown>, credentials: {} as Record<string, unknown>,
@@ -2175,6 +2186,7 @@ const splitTempUnschedKeywords = (value: string) => {
const resetForm = () => { const resetForm = () => {
step.value = 1 step.value = 1
form.name = '' form.name = ''
form.notes = ''
form.platform = 'anthropic' form.platform = 'anthropic'
form.type = 'oauth' form.type = 'oauth'
form.credentials = {} form.credentials = {}
@@ -2321,6 +2333,7 @@ const createAccountAndFinish = async (
} }
await adminAPI.accounts.create({ await adminAPI.accounts.create({
name: form.name, name: form.name,
notes: form.notes,
platform, platform,
type, type,
credentials, credentials,

View File

@@ -15,6 +15,16 @@
<label class="input-label">{{ t('common.name') }}</label> <label class="input-label">{{ t('common.name') }}</label>
<input v-model="form.name" type="text" required class="input" data-tour="edit-account-form-name" /> <input v-model="form.name" type="text" required class="input" data-tour="edit-account-form-name" />
</div> </div>
<div>
<label class="input-label">{{ t('admin.accounts.notes') }}</label>
<textarea
v-model="form.notes"
rows="3"
class="input"
:placeholder="t('admin.accounts.notesPlaceholder')"
></textarea>
<p class="input-hint">{{ t('admin.accounts.notesHint') }}</p>
</div>
<!-- API Key fields (only for apikey type) --> <!-- API Key fields (only for apikey type) -->
<div v-if="account.type === 'apikey'" class="space-y-4"> <div v-if="account.type === 'apikey'" class="space-y-4">
@@ -795,6 +805,7 @@ const defaultBaseUrl = computed(() => {
const form = reactive({ const form = reactive({
name: '', name: '',
notes: '',
proxy_id: null as number | null, proxy_id: null as number | null,
concurrency: 1, concurrency: 1,
priority: 1, priority: 1,
@@ -813,6 +824,7 @@ watch(
(newAccount) => { (newAccount) => {
if (newAccount) { if (newAccount) {
form.name = newAccount.name form.name = newAccount.name
form.notes = newAccount.notes || ''
form.proxy_id = newAccount.proxy_id form.proxy_id = newAccount.proxy_id
form.concurrency = newAccount.concurrency form.concurrency = newAccount.concurrency
form.priority = newAccount.priority form.priority = newAccount.priority

View File

@@ -936,6 +936,9 @@ export default {
editAccount: 'Edit Account', editAccount: 'Edit Account',
deleteAccount: 'Delete Account', deleteAccount: 'Delete Account',
searchAccounts: 'Search accounts...', searchAccounts: 'Search accounts...',
notes: 'Notes',
notesPlaceholder: 'Enter notes',
notesHint: 'Notes are optional',
allPlatforms: 'All Platforms', allPlatforms: 'All Platforms',
allTypes: 'All Types', allTypes: 'All Types',
allStatus: 'All Status', allStatus: 'All Status',
@@ -975,6 +978,23 @@ export default {
overloadedUntil: 'Overloaded until {time}', overloadedUntil: 'Overloaded until {time}',
viewTempUnschedDetails: 'View temp unschedulable details' viewTempUnschedDetails: 'View temp unschedulable details'
}, },
columns: {
name: 'Name',
platformType: 'Platform/Type',
platform: 'Platform',
type: 'Type',
concurrencyStatus: 'Concurrency',
notes: 'Notes',
priority: 'Priority',
weight: 'Weight',
status: 'Status',
schedulable: 'Schedulable',
todayStats: 'Today Stats',
groups: 'Groups',
usageWindows: 'Usage Windows',
lastUsed: 'Last Used',
actions: 'Actions'
},
tempUnschedulable: { tempUnschedulable: {
title: 'Temp Unschedulable', title: 'Temp Unschedulable',
statusTitle: 'Temp Unschedulable Status', statusTitle: 'Temp Unschedulable Status',
@@ -1018,21 +1038,6 @@ export default {
unavailableDesc: 'Unavailable - pause 30 minutes' unavailableDesc: 'Unavailable - pause 30 minutes'
} }
}, },
columns: {
name: 'Name',
platformType: 'Platform/Type',
platform: 'Platform',
type: 'Type',
concurrencyStatus: 'Concurrency',
status: 'Status',
schedulable: 'Schedule',
todayStats: "Today's Stats",
groups: 'Groups',
usageWindows: 'Usage Windows',
priority: 'Priority',
lastUsed: 'Last Used',
actions: 'Actions'
},
clearRateLimit: 'Clear Rate Limit', clearRateLimit: 'Clear Rate Limit',
testConnection: 'Test Connection', testConnection: 'Test Connection',
reAuthorize: 'Re-Authorize', reAuthorize: 'Re-Authorize',

View File

@@ -1014,6 +1014,9 @@ export default {
refreshCookie: '刷新 Cookie', refreshCookie: '刷新 Cookie',
testAccount: '测试账号', testAccount: '测试账号',
searchAccounts: '搜索账号...', searchAccounts: '搜索账号...',
notes: '备注',
notesPlaceholder: '请输入备注',
notesHint: '备注可选',
// Filter options // Filter options
allPlatforms: '全部平台', allPlatforms: '全部平台',
allTypes: '全部类型', allTypes: '全部类型',
@@ -1031,6 +1034,7 @@ export default {
platform: '平台', platform: '平台',
type: '类型', type: '类型',
concurrencyStatus: '并发', concurrencyStatus: '并发',
notes: '备注',
priority: '优先级', priority: '优先级',
weight: '权重', weight: '权重',
status: '状态', status: '状态',

View File

@@ -385,6 +385,7 @@ export interface TempUnschedulableStatus {
export interface Account { export interface Account {
id: number id: number
name: string name: string
notes?: string | null
platform: AccountPlatform platform: AccountPlatform
type: AccountType type: AccountType
credentials?: Record<string, unknown> credentials?: Record<string, unknown>
@@ -477,6 +478,7 @@ export interface CodexUsageSnapshot {
export interface CreateAccountRequest { export interface CreateAccountRequest {
name: string name: string
notes?: string | null
platform: AccountPlatform platform: AccountPlatform
type: AccountType type: AccountType
credentials: Record<string, unknown> credentials: Record<string, unknown>
@@ -490,6 +492,7 @@ export interface CreateAccountRequest {
export interface UpdateAccountRequest { export interface UpdateAccountRequest {
name?: string name?: string
notes?: string | null
type?: AccountType type?: AccountType
credentials?: Record<string, unknown> credentials?: Record<string, unknown>
extra?: Record<string, unknown> extra?: Record<string, unknown>

View File

@@ -30,6 +30,10 @@
<template #cell-name="{ value }"> <template #cell-name="{ value }">
<span class="font-medium text-gray-900 dark:text-white">{{ value }}</span> <span class="font-medium text-gray-900 dark:text-white">{{ value }}</span>
</template> </template>
<template #cell-notes="{ value }">
<span v-if="value" :title="value" class="block max-w-xs truncate text-sm text-gray-600 dark:text-gray-300">{{ value }}</span>
<span v-else class="text-sm text-gray-400 dark:text-dark-500">-</span>
</template>
<template #cell-platform_type="{ row }"> <template #cell-platform_type="{ row }">
<PlatformTypeBadge :platform="row.platform" :type="row.type" /> <PlatformTypeBadge :platform="row.platform" :type="row.type" />
</template> </template>
@@ -177,6 +181,7 @@ const cols = computed(() => {
{ key: 'usage', label: t('admin.accounts.columns.usageWindows'), sortable: false }, { key: 'usage', label: t('admin.accounts.columns.usageWindows'), sortable: false },
{ key: 'priority', label: t('admin.accounts.columns.priority'), sortable: true }, { key: 'priority', label: t('admin.accounts.columns.priority'), sortable: true },
{ key: 'last_used_at', label: t('admin.accounts.columns.lastUsed'), sortable: true }, { key: 'last_used_at', label: t('admin.accounts.columns.lastUsed'), sortable: true },
{ key: 'notes', label: t('admin.accounts.columns.notes'), sortable: false },
{ key: 'actions', label: t('admin.accounts.columns.actions'), sortable: false } { key: 'actions', label: t('admin.accounts.columns.actions'), sortable: false }
) )
return c return c

View File

@@ -669,6 +669,7 @@ const getAttributeValue = (userId: number, attrId: number): string => {
// All possible columns (for column settings) // All possible columns (for column settings)
const allColumns = computed<Column[]>(() => [ const allColumns = computed<Column[]>(() => [
{ key: 'email', label: t('admin.users.columns.user'), sortable: true }, { key: 'email', label: t('admin.users.columns.user'), sortable: true },
{ key: 'id', label: 'ID', sortable: true },
{ key: 'username', label: t('admin.users.columns.username'), sortable: true }, { key: 'username', label: t('admin.users.columns.username'), sortable: true },
{ key: 'notes', label: t('admin.users.columns.notes'), sortable: false }, { key: 'notes', label: t('admin.users.columns.notes'), sortable: false },
// Dynamic attribute columns // Dynamic attribute columns

View File

@@ -32,11 +32,11 @@ export default defineConfig({
port: 3000, port: 3000,
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:8080', target: process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:8080',
changeOrigin: true changeOrigin: true
}, },
'/setup': { '/setup': {
target: 'http://localhost:8080', target: process.env.VITE_DEV_PROXY_TARGET || 'http://localhost:8080',
changeOrigin: true changeOrigin: true
} }
} }