From d82632414a1f4dcfd10deda3a5d0d1b5b13b3c26 Mon Sep 17 00:00:00 2001 From: eafonyang Date: Mon, 21 Sep 2026 15:55:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=96=B0=E5=A2=9E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=9E=8B=E5=8F=B7=E7=89=88=E6=9C=AC=E5=88=86=E5=B8=83?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=B8=8E=E5=B1=95=E7=A4=BA=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端新增接口,按型号统计全量设备版本分布,空版本计入“未知版本” - 前端API添加获取设备版本分布的请求方法 - 首页新增各型号版本占比的饼图展示,支持展开查看完整版本列表 - 饼图支持高亮显示前10大版本,其他版本合并显示 - 设备版本数据加载失败时提供重试功能 - 优化客服反馈状态下拉选项类型定义及默认值 - 组件重构饼图模块,增强易用性和可访问性 --- dashboard/backend/src/routes/dashboard.ts | 42 ++++ .../frontend/src/service/api/dashboard.ts | 7 + .../frontend/src/typings/api/dashboard.d.ts | 13 ++ .../customer-service/feedbacks/index.vue | 6 +- dashboard/frontend/src/views/home/index.vue | 45 +++- .../src/views/home/modules/pie-chart.vue | 213 ++++++++++-------- 6 files changed, 230 insertions(+), 96 deletions(-) diff --git a/dashboard/backend/src/routes/dashboard.ts b/dashboard/backend/src/routes/dashboard.ts index 8fe4123..9803519 100644 --- a/dashboard/backend/src/routes/dashboard.ts +++ b/dashboard/backend/src/routes/dashboard.ts @@ -268,4 +268,46 @@ router.get('/api/dashboard/active-daily', async (req: Request, res: Response) => } }); +/** + * GET /api/dashboard/device-versions + * 按型号统计全量设备的版本分布,空版本计入“未知版本” + */ +router.get('/api/dashboard/device-versions', async (_req: Request, res: Response) => { + try { + const version = sql`COALESCE(NULLIF(TRIM(${userDevices.ver}), ''), '未知版本')`; + const rows = await db + .select({ + model: userDevices.model, + ver: version.as('version'), + count: sql`COUNT(*)`.mapWith(Number).as('count'), + }) + .from(userDevices) + .groupBy(userDevices.model, version) + .orderBy(userDevices.model, desc(sql`COUNT(*)`), version); + + const modelMap = new Map; + }>(); + + for (const row of rows) { + let stats = modelMap.get(row.model); + if (!stats) { + stats = { model: row.model, total: 0, versions: [] }; + modelMap.set(row.model, stats); + } + const count = Number(row.count); + stats.total += count; + stats.versions.push({ ver: row.ver, count }); + } + + res.json(ApiResponse.success({ items: [...modelMap.values()] })); + } catch (e: unknown) { + const msg = e instanceof Error ? e.message : String(e); + logger.error(`获取设备版本分布失败:${msg}`); + res.json(ApiResponse.error(`获取设备版本分布失败:${msg}`)); + } +}); + export default router; diff --git a/dashboard/frontend/src/service/api/dashboard.ts b/dashboard/frontend/src/service/api/dashboard.ts index 2f58ac9..9215577 100644 --- a/dashboard/frontend/src/service/api/dashboard.ts +++ b/dashboard/frontend/src/service/api/dashboard.ts @@ -15,6 +15,13 @@ export function fetchGetDeviceDaily(days: number = 30) { }); } +export function fetchGetDeviceVersions() { + return request({ + url: '/dashboard/device-versions', + method: 'get' + }); +} + export function fetchGetActiveDaily(days: number = 30) { return request({ url: '/dashboard/active-daily', diff --git a/dashboard/frontend/src/typings/api/dashboard.d.ts b/dashboard/frontend/src/typings/api/dashboard.d.ts index 14d9ab0..22a084e 100644 --- a/dashboard/frontend/src/typings/api/dashboard.d.ts +++ b/dashboard/frontend/src/typings/api/dashboard.d.ts @@ -49,6 +49,19 @@ declare namespace Api { total: number; } + interface DeviceVersionModel { + model: string; + total: number; + versions: Array<{ + ver: string; + count: number; + }>; + } + + interface DeviceVersionStats { + items: DeviceVersionModel[]; + } + interface ActiveDailyStats { dates: string[]; series: DeviceDailySeries[]; diff --git a/dashboard/frontend/src/views/customer-service/feedbacks/index.vue b/dashboard/frontend/src/views/customer-service/feedbacks/index.vue index 1f05529..fd90a69 100644 --- a/dashboard/frontend/src/views/customer-service/feedbacks/index.vue +++ b/dashboard/frontend/src/views/customer-service/feedbacks/index.vue @@ -1,6 +1,6 @@ @@ -375,6 +399,25 @@ onMounted(() => { + + + + 按各型号全部设备统计,未上报版本号的设备计入“未知版本”。 + + + + + + + + + + + + + diff --git a/dashboard/frontend/src/views/home/modules/pie-chart.vue b/dashboard/frontend/src/views/home/modules/pie-chart.vue index 9ff7978..3f5ba9e 100644 --- a/dashboard/frontend/src/views/home/modules/pie-chart.vue +++ b/dashboard/frontend/src/views/home/modules/pie-chart.vue @@ -1,108 +1,137 @@