remove dead group stats and dashboard wrapper
This commit is contained in:
@@ -29,21 +29,16 @@ type GroupRepository interface {
|
||||
ExistsByName(ctx context.Context, name string) (bool, error)
|
||||
GetAccountCount(ctx context.Context, groupID int64) (total int64, active int64, err error)
|
||||
DeleteAccountGroupsByGroupID(ctx context.Context, groupID int64) (int64, error)
|
||||
// GetAccountIDsByGroupIDs 获取多个分组的所有账号 ID(去重)
|
||||
GetAccountIDsByGroupIDs(ctx context.Context, groupIDs []int64) ([]int64, error)
|
||||
// BindAccountsToGroup 将多个账号绑定到指定分组
|
||||
BindAccountsToGroup(ctx context.Context, groupID int64, accountIDs []int64) error
|
||||
// UpdateSortOrders 批量更新分组排序
|
||||
UpdateSortOrders(ctx context.Context, updates []GroupSortOrderUpdate) error
|
||||
}
|
||||
|
||||
// GroupSortOrderUpdate 分组排序更新
|
||||
type GroupSortOrderUpdate struct {
|
||||
ID int64 `json:"id"`
|
||||
SortOrder int `json:"sort_order"`
|
||||
}
|
||||
|
||||
// CreateGroupRequest 创建分组请求
|
||||
type CreateGroupRequest struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
@@ -51,7 +46,6 @@ type CreateGroupRequest struct {
|
||||
IsExclusive bool `json:"is_exclusive"`
|
||||
}
|
||||
|
||||
// UpdateGroupRequest 更新分组请求
|
||||
type UpdateGroupRequest struct {
|
||||
Name *string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
@@ -60,13 +54,11 @@ type UpdateGroupRequest struct {
|
||||
Status *string `json:"status"`
|
||||
}
|
||||
|
||||
// GroupService 分组管理服务
|
||||
type GroupService struct {
|
||||
groupRepo GroupRepository
|
||||
authCacheInvalidator APIKeyAuthCacheInvalidator
|
||||
}
|
||||
|
||||
// NewGroupService 创建分组服务实例
|
||||
func NewGroupService(groupRepo GroupRepository, authCacheInvalidator APIKeyAuthCacheInvalidator) *GroupService {
|
||||
return &GroupService{
|
||||
groupRepo: groupRepo,
|
||||
@@ -74,9 +66,7 @@ func NewGroupService(groupRepo GroupRepository, authCacheInvalidator APIKeyAuthC
|
||||
}
|
||||
}
|
||||
|
||||
// Create 创建分组
|
||||
func (s *GroupService) Create(ctx context.Context, req CreateGroupRequest) (*Group, error) {
|
||||
// 检查名称是否已存在
|
||||
exists, err := s.groupRepo.ExistsByName(ctx, req.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("check group exists: %w", err)
|
||||
@@ -85,7 +75,6 @@ func (s *GroupService) Create(ctx context.Context, req CreateGroupRequest) (*Gro
|
||||
return nil, ErrGroupExists
|
||||
}
|
||||
|
||||
// 创建分组
|
||||
group := &Group{
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
@@ -103,7 +92,6 @@ func (s *GroupService) Create(ctx context.Context, req CreateGroupRequest) (*Gro
|
||||
return group, nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取分组
|
||||
func (s *GroupService) GetByID(ctx context.Context, id int64) (*Group, error) {
|
||||
group, err := s.groupRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
@@ -112,16 +100,14 @@ func (s *GroupService) GetByID(ctx context.Context, id int64) (*Group, error) {
|
||||
return group, nil
|
||||
}
|
||||
|
||||
// List 获取分组列表
|
||||
func (s *GroupService) List(ctx context.Context, params pagination.PaginationParams) ([]Group, *pagination.PaginationResult, error) {
|
||||
groups, pagination, err := s.groupRepo.List(ctx, params)
|
||||
groups, paginationResult, err := s.groupRepo.List(ctx, params)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("list groups: %w", err)
|
||||
}
|
||||
return groups, pagination, nil
|
||||
return groups, paginationResult, nil
|
||||
}
|
||||
|
||||
// ListActive 获取活跃分组列表
|
||||
func (s *GroupService) ListActive(ctx context.Context) ([]Group, error) {
|
||||
groups, err := s.groupRepo.ListActive(ctx)
|
||||
if err != nil {
|
||||
@@ -130,16 +116,13 @@ func (s *GroupService) ListActive(ctx context.Context) ([]Group, error) {
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
// Update 更新分组
|
||||
func (s *GroupService) Update(ctx context.Context, id int64, req UpdateGroupRequest) (*Group, error) {
|
||||
group, err := s.groupRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get group: %w", err)
|
||||
}
|
||||
|
||||
// 更新字段
|
||||
if req.Name != nil && *req.Name != group.Name {
|
||||
// 检查新名称是否已存在
|
||||
exists, err := s.groupRepo.ExistsByName(ctx, *req.Name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("check group exists: %w", err)
|
||||
@@ -176,9 +159,7 @@ func (s *GroupService) Update(ctx context.Context, id int64, req UpdateGroupRequ
|
||||
return group, nil
|
||||
}
|
||||
|
||||
// Delete 删除分组
|
||||
func (s *GroupService) Delete(ctx context.Context, id int64) error {
|
||||
// 检查分组是否存在
|
||||
_, err := s.groupRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get group: %w", err)
|
||||
@@ -193,28 +174,3 @@ func (s *GroupService) Delete(ctx context.Context, id int64) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetStats 获取分组统计信息
|
||||
func (s *GroupService) GetStats(ctx context.Context, id int64) (map[string]any, error) {
|
||||
group, err := s.groupRepo.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get group: %w", err)
|
||||
}
|
||||
|
||||
// 获取账号数量
|
||||
accountCount, _, err := s.groupRepo.GetAccountCount(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get account count: %w", err)
|
||||
}
|
||||
|
||||
stats := map[string]any{
|
||||
"id": group.ID,
|
||||
"name": group.Name,
|
||||
"rate_multiplier": group.RateMultiplier,
|
||||
"is_exclusive": group.IsExclusive,
|
||||
"status": group.Status,
|
||||
"account_count": accountCount,
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
@@ -16,15 +16,6 @@ import type {
|
||||
UsageRequestType
|
||||
} from '@/types'
|
||||
|
||||
/**
|
||||
* Get dashboard statistics
|
||||
* @returns Dashboard statistics including users, keys, accounts, and token usage
|
||||
*/
|
||||
export async function getStats(): Promise<DashboardStats> {
|
||||
const { data } = await apiClient.get<DashboardStats>('/admin/dashboard/stats')
|
||||
return data
|
||||
}
|
||||
|
||||
export interface TrendParams {
|
||||
start_date?: string
|
||||
end_date?: string
|
||||
@@ -297,7 +288,6 @@ export async function getBatchApiKeysUsage(
|
||||
}
|
||||
|
||||
export const dashboardAPI = {
|
||||
getStats,
|
||||
getUsageTrend,
|
||||
getModelStats,
|
||||
getGroupStats,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { flushPromises, mount } from '@vue/test-utils'
|
||||
|
||||
import UsageView from '../UsageView.vue'
|
||||
|
||||
const { list, getStats, getSnapshotV2, getById } = vi.hoisted(() => {
|
||||
const { list, getStats, getSnapshotV2, getModelStats, getById } = vi.hoisted(() => {
|
||||
vi.stubGlobal('localStorage', {
|
||||
getItem: vi.fn(() => null),
|
||||
setItem: vi.fn(),
|
||||
@@ -14,6 +14,7 @@ const { list, getStats, getSnapshotV2, getById } = vi.hoisted(() => {
|
||||
list: vi.fn(),
|
||||
getStats: vi.fn(),
|
||||
getSnapshotV2: vi.fn(),
|
||||
getModelStats: vi.fn(),
|
||||
getById: vi.fn(),
|
||||
}
|
||||
})
|
||||
@@ -40,6 +41,7 @@ vi.mock('@/api/admin', () => ({
|
||||
},
|
||||
dashboard: {
|
||||
getSnapshotV2,
|
||||
getModelStats,
|
||||
},
|
||||
users: {
|
||||
getById,
|
||||
@@ -111,6 +113,7 @@ describe('admin UsageView distribution metric toggles', () => {
|
||||
list.mockReset()
|
||||
getStats.mockReset()
|
||||
getSnapshotV2.mockReset()
|
||||
getModelStats.mockReset()
|
||||
getById.mockReset()
|
||||
|
||||
list.mockResolvedValue({
|
||||
@@ -133,6 +136,11 @@ describe('admin UsageView distribution metric toggles', () => {
|
||||
models: [],
|
||||
groups: [],
|
||||
})
|
||||
getModelStats.mockResolvedValue({
|
||||
models: [],
|
||||
start_date: '2026-04-19',
|
||||
end_date: '2026-04-20',
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
Reference in New Issue
Block a user