--- name: 统计卡片数据来源问题 description: 记录分页列表页面统计卡片显示不正确的原因和解决方案 type: feedback --- ## 问题现象 在管理员后台和代理后台的列表页面(如卡密管理、设备管理、用户管理、工单管理),统计卡片显示的数量不正确。例如: - 卡密管理页面显示"未使用20张",但实际数据库中有更多 - 表格只显示当前页的数据,但统计卡片应该显示全局总数 ## 根本原因 前端使用 `computed` 从当前页面数据计算统计值: ```typescript // 错误做法:只统计当前页数据 const unusedCount = computed(() => cards.value.filter(card => card.status === 'unused').length) ``` 当使用服务端分页时,`cards.value` 只包含当前页的数据(如20条),而不是全局数据。因此统计值只反映当前页的情况。 ## 解决方案 ### 后端修改 在 API 响应中添加 `stats` 字段,返回全局统计数据: ```go // 获取统计数据(无筛选条件时的全局统计) var statsUnused, statsUsed, statsBanned int64 database.DB.Model(&model.Card{}).Where("status = ?", "unused").Count(&statsUnused) // ... 其他状态 response.Success(c, gin.H{ "cards": cards, "total": total, "stats": gin.H{ "unused": statsUnused, "used": statsUsed, "banned": statsBanned, }, }) ``` ### 前端修改 1. 添加 `stats` ref 变量: ```typescript const stats = ref({ unused: 0, used: 0, banned: 0 }) ``` 2. 使用后端返回的统计数据: ```typescript const unusedCount = computed(() => stats.value.unused) const usedCount = computed(() => stats.value.used) const bannedCount = computed(() => stats.value.banned) ``` 3. 从 API 响应中提取统计: ```typescript if (data?.stats) { stats.value = data.stats } ``` ## 已修复的页面 - `frontend/src/pages/admin/cards/index.vue` - 卡密管理(管理员) - `frontend/src/pages/agent/cards/index.vue` - 卡密管理(代理) - `frontend/src/pages/admin/devices/index.vue` - 设备管理 - `frontend/src/pages/admin/users/index.vue` - 用户管理 - `frontend/src/pages/admin/tickets.vue` - 工单管理 ## 相关后端修改 - `backend/internal/router/admin/cards.go` - 添加 stats 返回 - `backend/internal/router/agent/agent.go` - handleGetCards 添加 stats 返回 - `backend/internal/router/admin/devices.go` - handleGetDevices 添加 stats 返回 - `backend/internal/router/admin/users.go` - handleGetUsers 已有统计返回 - `backend/internal/router/admin/tickets.go` - 已有 /tickets/stats 端点 ## 设计原则 **Why:** 服务端分页时,前端只能访问当前页数据,无法获取全局统计 **How to apply:** 所有需要显示全局统计的分页列表页面,都应从后端获取统计数据,而不是前端计算