Commit 253aec06bbf62ff5662e7099ba3e033994eebad9

Authored by zichun
1 parent d0a60569

feat(fe-shell): 导航与主页 KPI 静态配置数据 REQ-USR-003

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