Imported from Frank-zhao-junjun/ProcurementAnalysis (
AGENTS.md). Install upstream withnpx skills add Frank-zhao-junjun/ProcurementAnalysis. Copyright stays with the author.
采购经营分析大屏 (Procurement Intelligence Dashboard)
项目概览
面向采购总监的周一晨会汇报专业级数据可视化大屏 Demo,涵盖采购经营分析的 8 大模块(含首页驾驶舱)。采用深色科技风设计,基于 ECharts 5.5 实现全部图表渲染。
本项目包含两个运行单元:
- 前端静态大屏:单页
index.html+assets/js/模块,可直接用任意静态服务器托管。 - Node/Express API 代理:
server/目录,提供 Dashboard 数据接口、AI 代理(Coze LLM)和内网演示 JWT。
注意:所有业务数据均为模拟数据(Mock Data),仅用于演示交互与视觉效果,生产部署时需替换为真实 API。
技术栈
| 层级 | 技术 |
|---|---|
| 前端框架 | 原生 HTML5 / CSS3 / JavaScript,无框架依赖 |
| 图表库 | ECharts 5.5(CDN) |
| 字体 | Inter(UI) + JetBrains Mono(数据) |
| 设计风格 | 深色科技风,主色 Cyan #38bdf8 / 警示 Gold #f59e0b / 达标 Green #10b981 / 风险 Red #ef4444 |
| 后端 | Node.js 18+ + Express 4 |
| 模块格式 | 前端 ES Modules;服务端混合 ESM(.js)与 CommonJS(.cjs) |
| 测试 | Node.js 内置 node:test + supertest |
| 运行时配置 | .env 文件(服务端读取),参考 server/.env.example |
项目结构
D:/AI/采购分析驾驶舱
├── index.html # 主页面:8 个 Tab + 37 个 ECharts 实例
├── styles/main.css # 模板生成的全局样式(实际大部分样式内联在 index.html)
├── .coze # Coze 项目配置:静态入口 index.html,使用 python http.server
├── app.js # 旧版服务端入口(已废弃,请勿使用)
├── dashboard.js # 旧版 Dashboard API 路由(已废弃,请勿使用)
├── IDEA.md # 原始功能需求清单
├── README.md # 项目说明(含 WhatIf 模拟器介绍)
├── push.bat # 本地 Git 提交推送脚本(手动使用)
│
├── assets/
│ ├── js/
│ │ ├── dashboard-init.js # 首页 KPI/预警/排名数据初始化与定时刷新(IIFE)
│ │ ├── api/client.js # 前端 fetch 封装:ApiClient / dashboardAPI / whatifAPI
│ │ ├── services/data-service.js # 带 5 分钟缓存的数据服务层
│ │ ├── components/loading.js # 科技风 Loading 组件
│ │ ├── ai/ # AI 助手模块
│ │ │ ├── state-bus.js # Dashboard 状态总线(快照 + 订阅)
│ │ │ ├── context-bridge.js # 状态 → AI runtimeContext 转换
│ │ │ ├── assistant-shell.js # 悬浮 AI 助手面板(DOM 渲染、消息、建议)
│ │ │ ├── privacy-gate.js # AI 隐私同意弹窗(localStorage)
│ │ │ ├── bootstrap-jwt.js # 本地演示自动拉取 JWT
│ │ │ └── ...
│ │ └── whatif/ # WhatIf 采购比例模拟器
│ │ ├── simulation-engine.js # 核心计算引擎
│ │ ├── whatif-panel.js # 面板控制器与 DOM 渲染
│ │ ├── risk-rules.js # 参数校验与业务风险规则
│ │ ├── scenario-registry.js # 场景配置注册表
│ │ ├── formatter.js # 万元/百分比/敏感性区间格式化
│ │ └── explainers/ # 解释生成器(模板 + AI 预留)
│ └── image.png / whatif-smoke-*.png # 冒烟测试截图
│
├── data/ # 模拟数据 JSON
│ ├── suppliers.json / materials.json / price-history.json
│ ├── purchase-orders.json / inventory.json / contracts.json
│ ├── supplier-performance.json / budget-savings.json
│ └── data-report.json # 由 validate-demo-data.js 生成的数据验证报告
│
├── scripts/ # 数据生成与验证脚本(Node CommonJS)
│ ├── generate-orders.js
│ ├── generate-inventory.js
│ ├── generate-budget.js
│ ├── generate-performance.js
│ └── validate-demo-data.js
│
├── server/ # Node/Express API 服务
│ ├── package.json # type: "module",依赖 express / jsonwebtoken
│ ├── .env.example # 环境变量模板(含安全开关说明)
│ ├── src/
│ │ ├── app.js # Express 应用工厂 createApp
│ │ ├── dev.js # 开发启动入口(node --watch)
│ │ ├── config.js # 环境变量与配置读取
│ │ ├── routes/
│ │ │ ├── ai-proxy.js # /api/ai-proxy/*:LLM 代理 + 缓存 + 熔断
│ │ │ ├── dashboard.cjs # /api/dashboard/*:KPI / 预警 / 排名 / 图表数据
│ │ │ ├── dev-auth.js # /api/auth/dev-token:内网演示 JWT
│ │ │ └── health.js # /api/health
│ │ ├── middleware/
│ │ │ ├── security.js # CORS + HSTS
│ │ │ ├── auth.js # JWT Bearer 校验
│ │ │ └── request-context.js
│ │ ├── lib/
│ │ │ ├── cache-store.js # 内存缓存(TTL + 容量上限)
│ │ │ └── circuit-breaker.js
│ │ ├── services/
│ │ │ ├── coze-service.js # Coze API 调用
│ │ │ └── degrade-service.js
│ │ └── demo-data/index.cjs # 内存数据服务,加载 ../data/*.json
│ └── test/ # 后端测试(预留目录,尚未创建)
│
└── docs/ # 需求 / 设计 / 测试 / 追踪文档
├── dashboard-phase1-prd.md
├── dashboard-phase1-tech.md(当前空文件占位)
├── dashboard-phase1-prd-notes.md
├── dashboard-phase1-prd-task-plan.md
├── dashboard-phase1-e2e-checklist.md
├── dashboard-phase1-traceability-matrix.md
├── dashboard-phase1-compliance-report.md
├── ralph/
└── superpowers/
├── knowledge-base/
├── plans/
└── specs/
模块架构
Tab Home: 首页驾驶舱
- 10 个核心 KPI 卡片
- 6 条 P0 预警面板(high / medium / low 三级)
- 事业部降本排名 Top4 + 子公司降本排名 Top5
- 决策摘要 + 4 个专题下钻入口
Tab 1: 降本分析
月度降本追踪、事业部/子公司对比、品类明细、非生产品类降本、采购额趋势、降本比例趋势、全年预测降本仪表盘。
Tab 2: 支出分析
核心品类支出 Treemap、市场价格偏差度、支出 vs 市场价格、库存水位 vs 支出、VMI 覆盖率、供应商集中度雷达、TCO 成本构成、长约占比。
Tab 3: 价格趋势分析
实时价格预警 Banner、市场价格趋势、大宗商品期货、宏观经济指标、采购价 vs 市场公允价、库存水位、价格预测与置信区间、锁价策略、采购节奏建议。
Tab 4: 需求趋势分析
日均消耗量、库存保有量、周转天数、缺料预警、库存健康度、未来 4 周需求预测。
Tab 5: 材料成本率
整体成本率、多维度明细表、成本率趋势、各事业部成本率对比。
Tab 6: 其他降本机会
长尾供应商整合、分散供应商分析。
Tab 7: 供应源分析
供应商综合绩效雷达、绩效-支出匹配度、供应商过多物料、单一供应风险、行业排名与市占率。
关键前端模块说明
脚本加载顺序
index.html 中按以下顺序引入:
echarts@5.5.0(CDN)assets/js/api/client.jsassets/js/services/data-service.jsassets/js/components/loading.jsassets/js/dashboard-init.js- 页面底部
type="module"脚本:导入ai/*、whatif/*并初始化状态总线、AI 助手、WhatIf 面板。
状态管理
assets/js/ai/state-bus.js提供不可变快照状态总线。assets/js/ai/context-bridge.js将状态转换为 AI 请求的runtimeContext。
AI 助手
- 悬浮按钮 + 聊天面板。
- 默认走本地降级回复;配置
window.__AI_JWT__与window.__AI_PROXY_ENDPOINT__后可调用后端/api/ai-proxy/chat。 - 首次打开需经过
privacy-gate.js隐私同意。
WhatIf 模拟器
- 当前仅实现
purchase_ratio(采购比例调整)场景。 - 纯浏览器端计算,无需后端。
- 输入:当前/目标现货比例、现货价、长约价、月采购量。
- 输出:月度/季度成本影响、节约比例、敏感性区间、风险规则、四段式业务解释。
后端 API
启动服务后可用端点(基础路径 /api):
| 路径 | 说明 |
|---|---|
GET /api/health |
健康检查 |
GET /api/auth/dev-token |
内网演示 JWT(需 ALLOW_DEV_TOKEN=true) |
GET /api/ai-proxy/health |
AI 代理健康 |
POST /api/ai-proxy/chat |
AI 对话(需 JWT) |
GET /api/ai-proxy/rules |
支持的规则列表 |
GET /api/dashboard/kpi-cards?year=2025&month=6 |
首页 KPI |
GET /api/dashboard/alerts |
P0 预警 |
GET /api/dashboard/rankings |
组织排名 |
GET /api/dashboard/charts/:chartId |
单图表数据 |
GET /api/dashboard/home |
首页聚合数据 |
GET /api/dashboard/tab/:tabId |
指定 Tab 数据 |
GET /data/* |
静态数据文件 |
构建与运行命令
1. 安装后端依赖
cd server
npm install
2. 启动后端开发服务器
cd server
npm run dev
# 默认监听 http://localhost:3000
或使用 node --watch 的等价命令:
cd server
node --watch server.js
3. 启动前端静态服务器
.coze 配置使用 Python 内置服务器:
python -m http.server 5000 --bind 0.0.0.0
# 访问 http://localhost:5000
也可使用任意静态服务器,例如:
npx serve -l 5000
4. 数据生成与验证
scripts/ 下脚本为 CommonJS;项目根目录 package.json 已设置为 "type": "module",因此需显式按 CommonJS 运行:
# 生成采购订单(会覆盖 data/purchase-orders.json)
node --input-type=commonjs < scripts/generate-orders.js
# 验证全部 Demo 数据一致性并生成 data/data-report.json
node --input-type=commonjs < scripts/validate-demo-data.js
测试
当前测试入口:
# 前端 E2E(仓库根目录)
npm install
npx playwright install chromium
npm run test:e2e
说明:当前
server/test目录尚未创建,server/package.json中保留npm test脚本作为占位,待后续补充后端单元测试。
代码风格指南
- 注释与文档主要使用中文。
- 前端业务脚本:
- 旧版初始化逻辑使用 IIFE(
dashboard-init.js、client.js、data-service.js、loading.js)。 - 新版 AI 与 WhatIf 模块使用 ES Modules,通过
export/import组织,并在index.html底部以type="module"引入。
- 旧版初始化逻辑使用 IIFE(
- 服务端:
server/src/routes/dashboard.cjs与server/src/demo-data/index.cjs为 CommonJS,因为数据层为 CJS。- 其余服务端文件为 ES Modules。
- 命名:
- 常量:
SCENARIO_REGISTRY、DEFAULT_CACHE_TTL_MS - 类:
WhatIfEngine、ApiClient、DataService - 函数:驼峰,如
createAssistantShell、buildRuntimeContext
- 常量:
- 缩进:2 个空格。
- 尽量避免在生产配置中使用默认占位值(如
JWT_SECRET=replace-me)。
安全注意事项
- 环境变量:复制
server/.env.example为server/.env,并替换所有replace-me值。 - 开发令牌:
ALLOW_DEV_TOKEN=true仅用于本地演示,生产环境必须关闭。 - JWT 密钥:
JWT_SECRET必须设置为强随机字符串;占位值会导致/api/ai-proxy/chat返回 503。 - CORS:
CORS_ORIGIN应配置为实际前端域名;本地开发时ALLOW_DEV_TOKEN=true会允许localhost任意端口。 - AI 隐私:前端
privacy-gate.js会在首次打开 AI 助手时请求用户同意,避免未授权发送页面上下文。 - 静态沙箱部署:若部署到仅支持静态文件的平台,需要另行部署 Node API,并在
index.html顶部(早于api/client.js)设置:
<script>
window.__API_BASE_URL__ = 'https://你的后端域名/api';
window.__AI_PROXY_ENDPOINT__ = 'https://你的后端域名/api/ai-proxy/chat';
</script>
部署说明
- 前端:纯静态资源,托管
index.html、styles/、assets/、data/即可。 - 后端:部署
server/目录,启动server.js或自定义入口调用createApp()。 .coze仅负责静态页面托管;API 服务需独立部署并配置跨域。push.bat是本地 Windows 批处理,用于手动提交推送;运行前请确认 Git 状态。
数据说明
本项目为演示 Demo,全部数据由 scripts/ 生成器产生,用于展示大屏交互效果与视觉设计。关键数据规模:
- 供应商:20 家
- 物料:19 种
- 采购订单:2400 条
- 库存记录:456 条
- 长约合同:16 份
- 绩效记录:480 条
- 预算记录:96 条
实际部署时应将 server/src/demo-data/index.cjs 替换为真实数据库或上游 API 调用。
项目记忆索引
- [[code-review-2026-07-01]] — 全量代码审查记录与启动入口修复