需求文档:重构分析报告功能
简介
重构 AI 补货建议系统的分析报告功能。先清理现有分析报告相关代码(仅限分析报告模块,不涉及其他模块),再基于新结构重建。新报告涵盖库存总体概览、销量分析、库存构成健康度、补货建议生成情况四大板块。每个板块包含统计数据和 LLM 生成的分析文本。考虑使用 LangGraph 动态节点并发生成各板块统计及分析,最后汇总。涉及全栈改动:数据库表结构、数据模型、Agent 节点、LLM 提示词、API 接口、前端页面。
术语表
- Report_Generator: 分析报告生成节点(analysis_report_node),负责统计计算和调用 LLM 生成报告
- Report_API: 分析报告 API 接口,负责从数据库读取报告并返回给前端
- Report_UI: 前端报告渲染模块,负责展示报告数据和图表
- PartRatio: 配件库销比数据,包含库存、销量、成本等原始数据
- 有效库存: valid_storage_cnt = in_stock_unlocked_cnt + on_the_way_cnt + has_plan_cnt(在库未锁 + 在途 + 计划数)
- 月均销量: (90天出库数 + 未关单已锁 + 未关单出库 + 订件) / 3
- 库销比: 有效库存(valid_storage_cnt) / 月均销量
- 呆滞件: 有效库存(valid_storage_cnt) > 0 且 90天出库数 = 0 的配件
- 低频件: 月均销量 < 1 或 出库次数 < 3 或 出库间隔 >= 30天 的配件
- 缺货件: 有效库存(valid_storage_cnt) = 0 且 月均销量 >= 1 的配件
- 正常件: 不属于呆滞件、低频件、缺货件的配件
- 急需补货: 优先级 1,库销比 < 0.5 且月均销量 >= 1
- 建议补货: 优先级 2,库销比 0.5-1.0 且月均销量 >= 1
- 可选补货: 优先级 3,库销比 1.0-目标值 且月均销量 >= 1
- Result_Writer: 数据库写入服务,负责将报告持久化到 MySQL
需求
需求 1:清理现有分析报告代码
用户故事: 作为开发者,我希望先清理现有分析报告相关代码,以便在干净的基础上重构新报告功能。
验收标准
- WHEN 开始重构, THE 开发者 SHALL 清理 analysis_report_node.py 中的现有报告生成逻辑
- WHEN 开始重构, THE 开发者 SHALL 清理 analysis_report.py 中的现有数据模型
- WHEN 开始重构, THE 开发者 SHALL 清理 prompts/analysis_report.md 中的现有提示词
- WHEN 开始重构, THE 开发者 SHALL 清理前端 app.js 中的现有报告渲染代码(renderReportTab、renderOverallAssessment、renderRiskAlerts、renderStrategy、renderExpectedImpact)
- WHEN 清理代码, THE 开发者 SHALL 仅清理分析报告相关代码,保持其他模块代码不变
需求 2:库存总体概览统计
用户故事: 作为采购决策者,我希望看到库存总体概览(总数量、总金额/资金占用、库销比及库存构成明细),以便快速了解当前库存状况和资金占用情况。
验收标准
- WHEN Report_Generator 接收到 PartRatio 列表, THE Report_Generator SHALL 使用 valid_storage_cnt(in_stock_unlocked_cnt + on_the_way_cnt + has_plan_cnt)计算所有配件的有效库存总数量和总金额(有效库存 × 成本价之和)
- WHEN Report_Generator 计算库存构成, THE Report_Generator SHALL 分别统计在库未锁(in_stock_unlocked_cnt)、在途(on_the_way_cnt)、计划数(has_plan_cnt)的总数量/总金额
- WHEN Report_Generator 计算库销比, THE Report_Generator SHALL 使用有效库存总数量除以月均销量总数量得到整体库销比
- WHEN 库存概览统计完成, THE Report_Generator SHALL 将统计数据作为上下文传递给 LLM 生成库存概览分析文本
- IF 月均销量总数量为零, THEN THE Report_Generator SHALL 将库销比标记为特殊值并在分析中说明无销量数据
需求 3:销量分析统计
用户故事: 作为采购决策者,我希望看到销量分析(月均销量及各组成部分明细),以便了解销售趋势和需求分布。
验收标准
- WHEN Report_Generator 接收到 PartRatio 列表, THE Report_Generator SHALL 计算所有配件的月均销量总数量和总金额(月均销量 × 成本价之和)
- WHEN Report_Generator 计算销量构成, THE Report_Generator SHALL 分别统计90天出库数(out_stock_cnt)总量、未关单已锁(storage_locked_cnt)总量、未关单出库(out_stock_ongoing_cnt)总量、订件(buy_cnt)总量
- WHEN 销量统计完成, THE Report_Generator SHALL 将统计数据作为上下文传递给 LLM 生成销量分析文本
- WHEN Report_Generator 计算销量分布, THE Report_Generator SHALL 统计有销量配件数(月均销量 > 0)和无销量配件数(月均销量 = 0)
需求 4:库存构成健康度统计
用户故事: 作为采购决策者,我希望看到库存健康度分析(缺货/呆滞/低频/正常各类型的数量和金额占比),以便识别库存结构问题。
验收标准
- WHEN Report_Generator 分类配件, THE Report_Generator SHALL 将每个配件归类为缺货件、呆滞件、低频件或正常件中的一种
- WHEN Report_Generator 统计各类型, THE Report_Generator SHALL 计算每种类型的配件数量、占总数量的百分比、涉及金额(有效库存 × 成本价)、占总金额的百分比
- WHEN 健康度统计完成, THE Report_Generator SHALL 将统计数据作为上下文传递给 LLM 生成健康度分析文本
- WHEN Report_API 返回健康度数据, THE Report_API SHALL 返回包含各类型数量和金额的结构化数据,供前端生成图表
- WHEN Report_UI 展示健康度数据, THE Report_UI SHALL 使用图表展示各类型配件的数量占比和金额占比
需求 5:补货建议生成情况统计
用户故事: 作为采购决策者,我希望看到本次补货建议的生成情况(急需/建议/可选各优先级的配件数和金额),以便了解补货的紧迫程度和资金需求。
验收标准
- WHEN Report_Generator 统计补货建议, THE Report_Generator SHALL 按优先级(急需补货/建议补货/可选补货)分别统计配件种类数和建议补货总金额
- WHEN Report_Generator 统计补货总量, THE Report_Generator SHALL 计算所有优先级的配件总种类数和总金额
- WHEN 补货统计完成, THE Report_Generator SHALL 将统计数据作为上下文传递给 LLM 生成补货建议分析文本
需求 6:数据库表结构重构
用户故事: 作为开发者,我希望数据库表结构能够存储新的报告模块数据,以便支持四大板块的数据持久化。
验收标准
- THE ai_analysis_report 表 SHALL 包含库存概览模块的 JSON 字段(inventory_overview)存储统计数据和 LLM 分析
- THE ai_analysis_report 表 SHALL 包含销量分析模块的 JSON 字段(sales_analysis)存储统计数据和 LLM 分析
- THE ai_analysis_report 表 SHALL 包含健康度模块的 JSON 字段(inventory_health)存储统计数据和 LLM 分析
- THE ai_analysis_report 表 SHALL 包含补货建议模块的 JSON 字段(replenishment_summary)存储统计数据和 LLM 分析
- THE ai_analysis_report 表 SHALL 保留 task_no、group_id、dealer_grouping_id 等基础字段和 LLM 元数据字段
需求 7:LLM 提示词重构与并发生成
用户故事: 作为开发者,我希望使用 LangGraph 动态节点并发生成各板块的 LLM 分析,提高报告生成效率。
验收标准
- WHEN Report_Generator 生成报告, THE Report_Generator SHALL 使用 LangGraph 动态节点并发调用 LLM 生成四个板块的分析文本
- WHEN 每个板块节点调用 LLM, THE 节点 SHALL 在提示词中仅包含该板块相关的统计数据
- WHEN LLM 生成分析, THE LLM 输出 SHALL 为合法的 JSON 对象
- WHEN 所有板块分析完成, THE Report_Generator SHALL 汇总四个板块的统计数据和 LLM 分析结果为一个完整报告
- IF 某个板块的 LLM 调用失败, THEN THE Report_Generator SHALL 记录错误日志,该板块分析文本置为错误提示,其他板块继续正常生成
需求 8:API 接口重构
用户故事: 作为前端开发者,我希望 API 返回新结构的报告数据,以便前端能够渲染四大板块。
验收标准
- WHEN 前端请求分析报告, THE Report_API SHALL 返回包含四个模块(inventory_overview、sales_analysis、inventory_health、replenishment_summary)的 JSON 响应
- WHEN 报告中包含 JSON 字符串字段, THE Report_API SHALL 将其解析为 JSON 对象后返回
- IF 指定 task_no 无报告数据, THEN THE Report_API SHALL 返回 null
需求 9:前端报告页面重构
用户故事: 作为采购决策者,我希望在前端看到结构清晰的四大板块报告,包含统计数据卡片、图表和 LLM 分析文本。
验收标准
- WHEN Report_UI 渲染报告, THE Report_UI SHALL 按库存概览、销量分析、健康度、补货建议的顺序展示四个板块
- WHEN Report_UI 渲染库存概览板块, THE Report_UI SHALL 展示总库存数量、总金额(资金占用)、库销比的统计卡片,以及三项构成明细(在库未锁/在途/计划数)和 LLM 分析文本
- WHEN Report_UI 渲染销量分析板块, THE Report_UI SHALL 展示月均销量总量、销量构成明细(90天出库/未关单已锁/未关单出库/订件)和 LLM 分析文本
- WHEN Report_UI 渲染健康度板块, THE Report_UI SHALL 展示各类型配件的数量/金额占比图表和 LLM 分析文本
- WHEN Report_UI 渲染补货建议板块, THE Report_UI SHALL 展示各优先级的配件数/金额统计和 LLM 分析文本
- WHEN Report_UI 渲染健康度图表, THE Report_UI SHALL 使用 Chart.js 生成饼图或环形图展示数量占比和金额占比
需求 10:数据模型与写入服务重构
用户故事: 作为开发者,我希望 Python 数据模型和数据库写入服务能够适配新的报告结构。
验收标准
- THE AnalysisReport 数据模型 SHALL 包含 inventory_overview、sales_analysis、inventory_health、replenishment_summary 四个字典字段
- WHEN Result_Writer 保存报告, THE Result_Writer SHALL 将四个模块的字典数据序列化为 JSON 字符串写入对应数据库字段
- THE AnalysisReport 数据模型 SHALL 提供 to_dict 方法将报告转换为可序列化的字典