From 253aec06bbf62ff5662e7099ba3e033994eebad9 Mon Sep 17 00:00:00 2001 From: zichun Date: Mon, 1 Jun 2026 16:59:32 +0800 Subject: [PATCH] feat(fe-shell): 导航与主页 KPI 静态配置数据 REQ-USR-003 --- frontend/src/layouts/AppLayout/navConfig.ts | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/src/pages/home/HomePage/dashboardData.ts | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ frontend/tests/unit/dashboardData.test.ts | 39 +++++++++++++++++++++++++++++++++++++++ frontend/tests/unit/navConfig.test.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 279 insertions(+), 0 deletions(-) create mode 100644 frontend/src/layouts/AppLayout/navConfig.ts create mode 100644 frontend/src/pages/home/HomePage/dashboardData.ts create mode 100644 frontend/tests/unit/dashboardData.test.ts create mode 100644 frontend/tests/unit/navConfig.test.ts diff --git a/frontend/src/layouts/AppLayout/navConfig.ts b/frontend/src/layouts/AppLayout/navConfig.ts new file mode 100644 index 0000000..25106c8 --- /dev/null +++ b/frontend/src/layouts/AppLayout/navConfig.ts @@ -0,0 +1,104 @@ +// REQ-USR-003: 导航静态配置(全量复刻原型 navSide / navCols,D1/D4)。 +// 仅「用户列表」有真实路由;其余叶子无 routePath = 占位(点击提示「功能开发中」)。 + +export interface NavSideItem { + key: string; + label: string; + active?: boolean; +} + +export interface NavLeaf { + label: string; + routePath?: string; + star?: boolean; +} + +export interface NavCol { + title: string; + items: NavLeaf[]; +} + +/** 左列 20 个一级模块(复刻原型 navSide;「系统设置」默认 active) */ +export const NAV_SIDE: NavSideItem[] = [ + { key: 'sales', label: '销售管理' }, + { key: 'dcs', label: 'DCS系统' }, + { key: 'prod', label: '产品管理' }, + { key: 'ops', label: '生产运营' }, + { key: 'exec', label: '生产执行' }, + { key: 'mold', label: '模具管理' }, + { key: 'cart', label: '采购管理' }, + { key: 'mat', label: '材料库存' }, + { key: 'fg', label: '成品库存' }, + { key: 'out', label: '外协管理' }, + { key: 'logi', label: '物流管理' }, + { key: 'qa', label: '质量管理' }, + { key: 'fin', label: '财务管理' }, + { key: 'cost1', label: '成本管理(专)' }, + { key: 'cost2', label: '成本管理' }, + { key: 'eq', label: '设备管理' }, + { key: 'hr', label: '人事行政' }, + { key: 'oa', label: 'OA系统' }, + { key: 'base', label: '基础设置' }, + { key: 'sys', label: '系统设置', active: true }, +]; + +/** 右侧 7 列分组(复刻原型 navCols;仅「用户列表」routePath,「用户列表」「系统功能模块设置」带 ★) */ +export const NAV_COLS: NavCol[] = [ + { + title: '期初设置', + items: [ + { label: '客户期初' }, + { label: '供应商期初' }, + { label: '材料期初' }, + { label: '产品期初' }, + { label: '数据导入' }, + { label: '离线导出下载' }, + ], + }, + { + title: '用户管理', + items: [ + { label: '用户列表', routePath: '/usr/users', star: true }, + { label: '系统权限' }, + { label: '系统权限稽查表' }, + { label: '权限组' }, + ], + }, + { + title: '系统参数', + items: [{ label: '系统参数' }, { label: '财务结账' }, { label: '系统常量配置' }], + }, + { + title: '计算方案', + items: [{ label: '方案列表' }, { label: '计算参数' }], + }, + { + title: '日志', + items: [ + { label: '个性化模块' }, + { label: '操作日志' }, + { label: '异常清除KPI任务表' }, + { label: 'MYSQL监听器' }, + ], + }, + { + title: '开发平台', + items: [ + { label: '自定义开发范例' }, + { label: '系统功能模块设置', star: true }, + { label: 'EBC流程清单' }, + { label: '功能模块界面设置' }, + { label: '增删改存业务处理' }, + ], + }, + { + title: 'API对接管理', + items: [ + { label: '调用第三方接口(TOKEN配置)' }, + { label: '调用第三方接口(接口定义)' }, + { label: '被第三方调用(生成token)' }, + { label: '数据同步' }, + { label: '被第三方调用(API定义)' }, + ], + }, +]; diff --git a/frontend/src/pages/home/HomePage/dashboardData.ts b/frontend/src/pages/home/HomePage/dashboardData.ts new file mode 100644 index 0000000..c764815 --- /dev/null +++ b/frontend/src/pages/home/HomePage/dashboardData.ts @@ -0,0 +1,95 @@ +// REQ-USR-003: 主页静态 demo 数据(全量复刻原型内联 kpiRows / 角色树,D1/D2)。 +// 不取后端:KPI 看板、角色/流程树均为前端静态配置。 + +/** KPI 头条统计(复刻原型 .kpi-head) */ +export const KPI_STATS = { todayPending: 37428, openTotal: 56433 } as const; + +export interface GroupItem { + label: string; + count: number; +} + +/** 「按角色」分组(复刻原型左侧树第一段;「所有部门」为汇总条) */ +export const ROLE_GROUPS: GroupItem[] = [ + { label: '所有部门', count: 37428 }, + { label: '核价人员', count: 17 }, + { label: '销售人员', count: 0 }, + { label: '印前', count: 11 }, + { label: '客服部', count: 30127 }, + { label: '技术研发部', count: 47 }, + { label: '车间主管', count: 316 }, + { label: '工艺部', count: 6 }, + { label: '物控部', count: 728 }, + { label: '生产计划部', count: 225 }, + { label: '版房', count: 120 }, + { label: '生产车间', count: 596 }, + { label: '工艺技术部', count: 0 }, + { label: '品质管理部', count: 589 }, + { label: '储运部', count: 3496 }, + { label: '通用', count: 0 }, + { label: '外发组', count: 867 }, + { label: '材料仓管', count: 0 }, + { label: '机修组', count: 42 }, + { label: '应收', count: 30 }, + { label: '出纳', count: 211 }, + { label: '应付', count: 0 }, + { label: '客服', count: 0 }, +]; + +/** 「按流程」分组(复刻原型左侧树第二段) */ +export const PROCESS_GROUPS: GroupItem[] = [ + { label: '估价管理流程', count: 17 }, + { label: '设计制作流程', count: 11 }, + { label: '新品研发流程', count: 11 }, + { label: '材料测试流程', count: 51 }, + { label: '订单下达流程', count: 30118 }, +]; + +/** KPI 网格行(字段名与原型 kpiRows 一致,D2) */ +export interface KpiRow { + role: string | null; + item: string; + desc: string; + today: string; + total: string; + sub?: string; + red?: boolean; + navTypeFirst?: boolean; + roleSpan?: number; + subSpan?: number; +} + +/** KPI 网格 7 列表头(逐字复刻原型 kpiHeader) */ +export const KPI_HEADERS = [ + '导航类型', + '角色', + 'KPI待处理事项(当前行双击进入)', + 'KPI内容描述及处理结果(点击蓝色查看明细)', + '今日未处理', + '未清总数', + '子流程', +] as const; + +/** 全量复刻原型 kpiRows(17 行) */ +export const KPI_ROWS: KpiRow[] = [ + // group 1: 估价管理流程 — 5 rows, 核价人员 span 4, 销售人员 1 + { role: '核价人员', item: '01/04【新增】新报价单', desc: '报价单明细', today: '-', total: '-', sub: '估价管理流程', navTypeFirst: true, roleSpan: 4, subSpan: 5 }, + { role: null, item: '02/04 审核后报价单->客户确认价格', desc: '报价单明细', today: '16', total: '16', red: true }, + { role: null, item: '03/04 客户不认可->二次确认', desc: '报价单明细', today: '-', total: '-' }, + { role: null, item: '04/04 报价单->销售订单', desc: '销售订单明细', today: '1', total: '1', red: true }, + { role: '销售人员', item: '04/04 报价单->销售订单(标签)', desc: '销售订单明细(标签)', today: '0', total: '0', red: true }, + // group 2: 设计制作流程 — 印前 (2 rows), span 2 + { role: '印前', item: '1/2 新增设计申请单', desc: '设计申请明细', today: '-', total: '-', sub: '设计制作流程', roleSpan: 2, subSpan: 2 }, + { role: null, item: '2/2 设计申请->设计制作', desc: '根据设计申请单进行设计制作,当日16:00前审核的为今日任务,16:00后(含)顺延至次日', today: '11', total: '11', red: true }, + // group 3: 新品研发流程 + { role: '客服部', item: '1/1 研发申请->文件制作', desc: '根据研发申请单,制作电子文件,当日16:00前下达的为今日任务,16:00后(含)顺延至次日', today: '0', total: '12', red: true, sub: '新品研发流程', subSpan: 5 }, + { role: '客服部', item: '1/5 新增研发申请单', desc: '研发申请明细', today: '-', total: '-' }, + { role: '技术研发部', item: '2/5 研发申请>>研发工单', desc: '及时开立研发工单,当日16:00前审核的为今日任务,16:00后(含)顺延至次日', today: '4', total: '4', red: true, roleSpan: 2 }, + { role: null, item: '3/5 研发工单>>完工处理', desc: '计划人员在交货日期前确认工单完工', today: '7', total: '7', red: true }, + { role: '客服部', item: '4/5 研发工单->客户确认', desc: '工单完工后需在7天内和客户确认样品', today: '-', total: '2703' }, + { role: '技术研发部', item: '5/5 客户确认->工艺卡', desc: '根据客户已经确认的研发工单,生成产品工艺卡。当日16:00前确认的为今日任务,16:00后(含)顺延至次日', today: '0', total: '1632', red: true, sub: '', subSpan: 0 }, + // group 4: 材料测试流程 + { role: '车间主管', item: '1/3 工单(测试部门数)->车间反馈', desc: '车间主管在工单完工前对测试材料进行数据反馈', today: '10', total: '115', red: true, sub: '材料测试流程', subSpan: 3 }, + { role: null, item: '2/3 车间反馈->车间补充(多部门)', desc: '补充新材料测试信息,车间反馈次日16:00前的为当日任务,16:00后(含)顺延一日', today: '8', total: '8', red: true, roleSpan: 2 }, + { role: '技术研发部', item: '2/3 车间反馈->工程部反馈(单部门)', desc: '工程部对新材料的测试结果进行反馈,车间反馈次日16:00前的为当日任务,16:00后(含)顺延一日', today: '23', total: '23', red: true }, +]; diff --git a/frontend/tests/unit/dashboardData.test.ts b/frontend/tests/unit/dashboardData.test.ts new file mode 100644 index 0000000..7904ec3 --- /dev/null +++ b/frontend/tests/unit/dashboardData.test.ts @@ -0,0 +1,39 @@ +// REQ-USR-003: 主页静态 demo 数据(复刻原型 kpiRows / 角色树,D1/D2) +import { describe, it, expect } from 'vitest'; +import { + KPI_STATS, + KPI_ROWS, + ROLE_GROUPS, + PROCESS_GROUPS, +} from '../../src/pages/home/HomePage/dashboardData'; + +describe('dashboardData', () => { + it('KPI_STATS matches prototype head bar', () => { + expect(KPI_STATS.todayPending).toBe(37428); + expect(KPI_STATS.openTotal).toBe(56433); + }); + + it('KPI_ROWS first row replicates prototype kpiRows field names', () => { + const first = KPI_ROWS[0]; + expect(first.role).toBe('核价人员'); + expect(first.navTypeFirst).toBe(true); + expect(first.roleSpan).toBe(4); + expect(first.sub).toBe('估价管理流程'); + expect(first.subSpan).toBe(5); + expect(first.item).toBe('01/04【新增】新报价单'); + }); + + it('ROLE_GROUPS includes 所有部门 37428 and 客服部 30127', () => { + const all = ROLE_GROUPS.find((g) => g.label === '所有部门'); + const kf = ROLE_GROUPS.find((g) => g.label === '客服部'); + expect(all?.count).toBe(37428); + expect(kf?.count).toBe(30127); + }); + + it('PROCESS_GROUPS includes 估价管理流程 17 and 订单下达流程 30118', () => { + const est = PROCESS_GROUPS.find((g) => g.label === '估价管理流程'); + const ord = PROCESS_GROUPS.find((g) => g.label === '订单下达流程'); + expect(est?.count).toBe(17); + expect(ord?.count).toBe(30118); + }); +}); diff --git a/frontend/tests/unit/navConfig.test.ts b/frontend/tests/unit/navConfig.test.ts new file mode 100644 index 0000000..5b08c70 --- /dev/null +++ b/frontend/tests/unit/navConfig.test.ts @@ -0,0 +1,41 @@ +// REQ-USR-003: 导航静态配置(复刻原型 navSide / navCols,D1/D4) +import { describe, it, expect } from 'vitest'; +import { NAV_SIDE, NAV_COLS } from '../../src/layouts/AppLayout/navConfig'; + +describe('navConfig', () => { + it('NAV_SIDE has 20 items with 系统设置 active', () => { + expect(NAV_SIDE).toHaveLength(20); + const sys = NAV_SIDE.find((s) => s.label === '系统设置'); + expect(sys).toBeDefined(); + expect(sys!.active).toBe(true); + // 仅「系统设置」一项 active + expect(NAV_SIDE.filter((s) => s.active).length).toBe(1); + }); + + it('NAV_COLS has 7 groups with exact titles', () => { + expect(NAV_COLS).toHaveLength(7); + expect(NAV_COLS.map((c) => c.title)).toEqual([ + '期初设置', + '用户管理', + '系统参数', + '计算方案', + '日志', + '开发平台', + 'API对接管理', + ]); + }); + + it('用户列表 leaf has routePath /usr/users and star', () => { + const userMgmt = NAV_COLS.find((c) => c.title === '用户管理')!; + const userList = userMgmt.items.find((it) => it.label === '用户列表')!; + expect(userList.routePath).toBe('/usr/users'); + expect(userList.star).toBe(true); + }); + + it('系统功能模块设置 leaf has star and no routePath (placeholder)', () => { + const devCol = NAV_COLS.find((c) => c.title === '开发平台')!; + const leaf = devCol.items.find((it) => it.label === '系统功能模块设置')!; + expect(leaf.star).toBe(true); + expect(leaf.routePath).toBeUndefined(); + }); +}); -- libgit2 0.22.2