diff --git a/backend/internal/model/account.go b/backend/internal/model/account.go index 28e96ef9..9b09b114 100644 --- a/backend/internal/model/account.go +++ b/backend/internal/model/account.go @@ -68,7 +68,8 @@ type Account struct { AccountGroups []AccountGroup `gorm:"foreignKey:AccountID" json:"account_groups,omitempty"` // 虚拟字段 (不存储到数据库) - GroupIDs []int64 `gorm:"-" json:"group_ids,omitempty"` + GroupIDs []int64 `gorm:"-" json:"group_ids,omitempty"` + Groups []*Group `gorm:"-" json:"groups,omitempty"` } func (Account) TableName() string { diff --git a/backend/internal/repository/account_repo.go b/backend/internal/repository/account_repo.go index 639e8046..1296ef1b 100644 --- a/backend/internal/repository/account_repo.go +++ b/backend/internal/repository/account_repo.go @@ -78,15 +78,19 @@ func (r *AccountRepository) ListWithFilters(ctx context.Context, params paginati return nil, nil, err } - if err := db.Preload("Proxy").Preload("AccountGroups").Offset(params.Offset()).Limit(params.Limit()).Order("id DESC").Find(&accounts).Error; err != nil { + if err := db.Preload("Proxy").Preload("AccountGroups.Group").Offset(params.Offset()).Limit(params.Limit()).Order("id DESC").Find(&accounts).Error; err != nil { return nil, nil, err } - // 填充每个 Account 的 GroupIDs 虚拟字段 + // 填充每个 Account 的虚拟字段(GroupIDs 和 Groups) for i := range accounts { accounts[i].GroupIDs = make([]int64, 0, len(accounts[i].AccountGroups)) + accounts[i].Groups = make([]*model.Group, 0, len(accounts[i].AccountGroups)) for _, ag := range accounts[i].AccountGroups { accounts[i].GroupIDs = append(accounts[i].GroupIDs, ag.GroupID) + if ag.Group != nil { + accounts[i].Groups = append(accounts[i].Groups, ag.Group) + } } } diff --git a/frontend/src/i18n/locales/en.ts b/frontend/src/i18n/locales/en.ts index d632ea29..fd391c30 100644 --- a/frontend/src/i18n/locales/en.ts +++ b/frontend/src/i18n/locales/en.ts @@ -666,6 +666,7 @@ export default { status: 'Status', schedulable: 'Schedule', todayStats: "Today's Stats", + groups: 'Groups', usageWindows: 'Usage Windows', priority: 'Priority', lastUsed: 'Last Used', diff --git a/frontend/src/i18n/locales/zh.ts b/frontend/src/i18n/locales/zh.ts index b8859c23..d1ecc119 100644 --- a/frontend/src/i18n/locales/zh.ts +++ b/frontend/src/i18n/locales/zh.ts @@ -721,6 +721,9 @@ export default { weight: '权重', status: '状态', schedulable: '调度', + todayStats: '今日统计', + groups: '分组', + usageWindows: '用量窗口', lastUsed: '最近使用', actions: '操作', }, diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index de5ac92c..1f1ae441 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -324,6 +324,7 @@ export interface Account { updated_at: string; proxy?: Proxy; group_ids?: number[]; // Groups this account belongs to + groups?: Group[]; // Preloaded group objects // Rate limit & scheduling fields schedulable: boolean; diff --git a/frontend/src/views/admin/AccountsView.vue b/frontend/src/views/admin/AccountsView.vue index 04c6a959..6b55fe42 100644 --- a/frontend/src/views/admin/AccountsView.vue +++ b/frontend/src/views/admin/AccountsView.vue @@ -123,6 +123,21 @@ + + @@ -301,6 +316,7 @@ import AccountStatusIndicator from '@/components/account/AccountStatusIndicator. import AccountUsageCell from '@/components/account/AccountUsageCell.vue' import AccountTodayStatsCell from '@/components/account/AccountTodayStatsCell.vue' import AccountTestModal from '@/components/account/AccountTestModal.vue' +import GroupBadge from '@/components/common/GroupBadge.vue' import { formatRelativeTime } from '@/utils/format' const { t } = useI18n() @@ -314,6 +330,7 @@ const columns = computed(() => [ { key: 'status', label: t('admin.accounts.columns.status'), sortable: true }, { key: 'schedulable', label: t('admin.accounts.columns.schedulable'), sortable: true }, { key: 'today_stats', label: t('admin.accounts.columns.todayStats'), sortable: false }, + { key: 'groups', label: t('admin.accounts.columns.groups'), sortable: false }, { key: 'usage', label: t('admin.accounts.columns.usageWindows'), sortable: false }, { key: 'priority', label: t('admin.accounts.columns.priority'), sortable: true }, { key: 'last_used_at', label: t('admin.accounts.columns.lastUsed'), sortable: true },