文档信息
| 版本号 | 日期 | 作者 |
|---|---|---|
| V 1.0.0 | 2026-05-16 | Hermes |
Sieta 连锁鞋店现有 5 个店铺,使用老 ERP 系统 oupu v6(基于 IE6 内核),无法实现现代 ERP 的分析功能。oupu 可设定每天 24:00 自动生成两组数据并通过邮件发送:
当前问题:这些数据以 Excel 附件形式存在邮件中,没有沉淀到数据库,无法做跨日对比、趋势分析、同比环比。手动导出到 Excel 加工效率低,手机端查看效果差。
| 问题点 | 问题描述 | 当前影响 |
|---|---|---|
| 数据孤岛 | 每日库存/销售都在邮件附件里,没有持久化存储 | 无法做历史对比和趋势分析 |
| 手动分析 | 要看对比数据需打开 Excel 手工加工 | 费时、易错、频率低 |
| 手机不可看 | 在手机上无法直观查看经营数据 | 出差/远程时无法快速掌握门店状况 |
| 新款跟进难 | 新款式上架后是否好卖、何时售罄,缺乏自动跟踪 | 换季补货决策滞后 |
核心方案:周快照 + 每日流水,SQLite 存储。
每天 01:00 → 收前一日(24:00)数据 → 推算变动流水入库(只存有变化的 SKU)
每周一 01:00 → 常规日处理 + 将周日的数据同时存入周快照(作为整周锚点)
查询任意日期库存 = 最近周日快照数量 + 该SKU从周日起到目标日的所有流水累加
设计优势: - 数据库行数不无限增长——快照固定 52 次/年,流水只存有变动的 SKU - 查询高效——SQLite 千万行级别毫秒响应 - 通过对每日库存的反推,自动产生进销存明细
| 指标 | 当前状态 | 目标状态 |
|---|---|---|
| 数据入库 | 邮件 Excel 散落在邮箱 | 每日凌晨 1:00 自动入库,无人工干预 |
| 日报产出 | 无 | 每天出 H5 报告,飞书能收到简报 |
| 历史追溯 | 无法查任意日期库存 | 输入任意日期,3 秒内返回库存台账 |
| 对比分析 | 无 | 周报可对比历史同周(数据量足够后) |
| 版本 | 时间 | 内容 |
|---|---|---|
| v1.0 MVP | 第 1-2 周 | 数据库搭建 + 每日自动入库 + 日报 H5 + 飞书推送 |
| v1.1 | 第 3-4 周 | 周报/月报 + Dashboard 顶视图 |
| v1.2 | 第 5 周起 | 同比环比深度分析 + 纯脚本化(减少 token 消耗) |
| 文档 | 说明 |
|---|---|
docs/inventory-ledger-design.md |
库存台账技术设计文档(大头哥原稿) |
docs/2026-05-15-sietadata-analytics-discussion.md |
前期讨论记录 |
~/sietadata/CONVENTIONS.md |
脚本编写规范 |
支持多粒度快照同时存入——日快照、周快照、月快照共用同一张表,通过 snapshot_date 区分。
| 字段 | 类型 | 说明 |
|---|---|---|
| snapshot_date | TEXT | 快照日期(YYYY-MM-DD),可表示日/周/月 |
| sku_id | TEXT | 商品编码 |
| qty | REAL | 该日期 24:00 的库存数量 |
主键:(snapshot_date, sku_id)
设计要点: - snapshot_date 不限制必须是周日——日快照、周快照、月快照均存入 - 查询时找目标日期之前的最近一个快照,不论粒度 - 2026 年 5 月起:每日一个全量快照(入库后即生成) - 2026 年 5 月起:每周一 01:00 将周日数据存为周快照(作为周分析锚点) - 2025 年历史数据:每周一次快照 - 2024 年历史数据:每月一次快照
为什么日快照和周快照同时存? 每日快照是入库流水推算后的副产品(已有今日全量库存 xlsx,顺手存入);周快照是正式分析锚点。二者不冲突。
| 字段 | 类型 | 说明 |
|---|---|---|
| change_date | TEXT | 变动日期(YYYY-MM-DD) |
| sku_id | TEXT | 商品编码 |
| change_type | TEXT | 变动类型枚举 |
| delta_qty | REAL | 变动数量(入库为正,出库为负) |
| ref_id | TEXT | 关联单据号(可选) |
| remark | TEXT | 备注(可选) |
主键:(change_date, sku_id, change_type) 索引:(change_date) 单独索引,加速按日期范围查询 索引:(sku_id) 单独索引,加速按商品查询
变动类型枚举:
| 类型 | 含义 | delta_qty 符号 |
|---|---|---|
| sale | 销售出库 | 负数 |
| return | 销售退货 | 正数 |
| purchase | 采购到货 | 正数 |
| adjustment_in | 盘盈 / 库存调增 | 正数 |
| adjustment_out | 盘亏 / 库存调减 | 负数 |
设计要点: - 只记录当天发生变化的 SKU,无变化不产生行 - 从 2026 年 5 月(系统启动月份)开始逐日记录 - 2025 年及以前的历史数据不在流水表中产生行——只存快照
| 字段 | 类型 | 说明 |
|---|---|---|
| sku_id | TEXT PRIMARY KEY | 商品编码 |
| name | TEXT | 商品名称 |
| category | TEXT | 分类(如"新款"旧款"凉鞋"运动鞋"等) |
| image_url | TEXT | COS 图片链接(用于飞书推送展示) |
| is_new | INTEGER | 是否新款标记(0/1,可用于后续功能) |
| created_at | TEXT | 首次在系统出现的日期 |
| 字段 | 类型 | 说明 |
|---|---|---|
| report_date | TEXT PRIMARY KEY | 报表日期 |
| summary | TEXT | 分析结论(JSON,大模型产出或脚本产出) |
| generated_at | TEXT | 生成时间戳 |
这是大头哥特别强调的部分。核心原则:时间越久远,粒度越粗。
2024年 ───────── 2025年 ───────── 2026年5月 ────── 现在(持续)
│ │ │
月粒度 周粒度 日粒度
(每月1号快照) (每周快照) (每日全量库存+销售)
| 时间段 | 粒度 | 你需导出的数据 | 我的用途 |
|---|---|---|---|
| 最近1个月(2026-05-01 ~ 启动前一日) | 日 | 每一天的全量库存 xlsx + 每一天的销售 xlsx | 跑通完整流水,生成初始的 inventory_ledger |
| 2025年全年 | 周 | 每周日 24:00 的全量库存 xlsx + 前 7 天销售汇总 xlsx(约 52 套) | 存入 inventory_snapshot(周快照),不做逐日流水。用于周同比分析 |
| 2024年全年 | 月 | 每月 1 日的全量库存 xlsx + 当月销售汇总 xlsx(约 12 套) | 存入 inventory_snapshot(月快照),用于月同比分析 |
| 2023年及更早(可选) | 月 | 每月 1 日的全量库存 + 当月销售(如果有的话) | 同上,强化历史对比基准 |
你通过网页上传入口(后续开发)或直接告诉我用终端导入。对于历史数据,处理 xlsx 的脚本自动识别粒度: - 文件名含日期,判断是日/周/月 - 日粒度:同时写入 snapshot 和 ledger - 周/月粒度:只写入 snapshot
| 分析类型 | 需要的数据量 | 何时可用 |
|---|---|---|
| 日报-昨日对比 | 2 天数据 | 上线第 2 天 |
| 日报-上周同日 | 8 天数据 | 上线第 2 周 |
| 周报-同比/环比 | 4 周 + 2025 周数据 | 上线第 1 个月(有 2025 周数据即可同比) |
| 月报-同比/环比 | 3 个月 + 2024 月数据 | 上线第 1 个月(有 2024 月数据即可同比) |
没有对比、就没有分析——所以历史数据的导入非常关键。
任务 1:建表脚本
├─ create_tables.sql → 创建 product / inventory_snapshot / inventory_ledger 三表
└─ 初始化 SQLite 数据库:~/sietadata/db/sieta.db
任务 2:核心 pipeline 脚本
├─ step1_parse_inventory.py → 读取库存 xlsx,标准化字段
├─ step2_parse_sales.py → 读取销售 xlsx,标准化字段
└─ step3_process_daily.py → 核心逻辑:
① 获取昨日库存(快照+流水推算)
② 获取今日库存 + 今日销售(从 xlsx 解析)
③ 写入 sale 流水
④ 计算非销售净变动 → 写入 adjustment_in/out
⑤ 如果是周一 → 将周日数据存为周快照
⑥ 写入今日全量库存到 inventory_snapshot(作为日快照)
步骤 1:你把 5月1日 ~ 启动前一日 的每日库存 xlsx + 销售 xlsx 给我
步骤 2:我跑导入脚本(按日期顺序),逐日演练一遍 pipeline
步骤 3:验证——查询任意一天的库存台账,确认数据正确
步骤 4:验证——检查 inventory_ledger 行数是否合理(仅含变动的 SKU)
此阶段完成后,系统已有约 20 天的完整数据,日报可以产出。
步骤 1:你把 2025 年每周数据给我(一次给几周也可,分批处理)
步骤 2:我跑导入脚本 → 只写入 inventory_snapshot(周快照)
步骤 3:你把 2024 年每月数据给我
步骤 4:跑导入脚本 → 只写入 inventory_snapshot(月快照)
步骤 5:验证——周同比和月同比的 SQL 查询正确返回结果
此阶段完成后,数据库已有 2024~2026 的完整库存全景。
任务 1:配置 oupu 每日自动发送邮件(如果你还没配好)
任务 2:写 daily_pipeline.sh 编排脚本(按顺序调 step1→2→3)
任务 3:cron 定时任务 — 每日 01:00 执行
任务 4:首次 cron 手动跑一次验证邮件接收 → 解析 → 入库全链路
任务 5:异常处理——入库失败时发飞书通知你
任务 1:写日报数据查询脚本(从 SQLite 取今日销售/库存/新款/售罄等指标)
任务 2:分析阶段(先用大模型分析数据 → 产出洞察文本)
任务 3:生成 H5 报告模板(HTML + Chart.js 图表)
任务 4:飞书推送脚本(简报内容 + H5 链接)
v1.1:
- Dashboard 顶视图(sieta.vip/sietadata/)
- 周报/月报页面
- 历史数据上传入口
v1.2:
- 同比/环比深度分析
- 分析脚本化(减少 token 消耗)
- 新款自动识别 + 售罄预警
| 模块 | 功能名称 | 功能说明 | 优先级 |
|---|---|---|---|
| 数据入库 | 每日自动入库 | 每日凌晨 1:00 cron 运行,收邮件 → 解析 xlsx → 更新 inventory_ledger + inventory_snapshot | P0 |
| 数据入库 | 历史批量导入 | 导入日粒度/周粒度/月粒度的历史 xlsx 数据到数据库 | P0 |
| 数据入库 | 数据完整性校验 | 入库后验证昨日库存推算值和今日库存值的差值是否匹配流水 | P1 |
| 日报产出 | 查询当日台账 | 查询任意一天的库存明细(按 SKU) | P0 |
| 日报产出 | 新款/售罄统计 | 统计当日新款销售数量和已售罄 SKU(下样提醒) | P0 |
| 日报产出 | 同比/环比数据 | 与上周同日、上月同日的数据对比 | P1 |
| 日报产出 | 经营建议生成 | 从数据中发现问题:哪些指标掉队、哪些商品缺货、哪些库存过剩 | P0 |
| H5 报告 | 交互式 HTML 报告 | 含图表、表格、图片的 H5 页面,手机端友好 | P0 |
| 飞书推送 | 简报推送 | 飞书群发送简报(含新款图片链接、售罄提醒、H5 链接) | P0 |
| 飞书推送 | 日报 H5 链接 | 飞书消息附带完整报告链接 | P0 |
MVP 没有独立导航页面。数据通过两条渠道触达:
├─ 飞书推送 → 点击 H5 链接 → 看到当日日报(独立页面,不依赖导航)
└─ 后续迭代 → Dashboard 顶视图(sieta.vip/sietadata/)
页面职责:用户通过飞书链接访问,在手机上看当日经营全貌
页面结构(从上到下):
| 区域 | 内容 | 显示条件 |
|---|---|---|
| 顶部标题 | 📊 SietaData 日报 — YYYY-MM-DD | 始终显示 |
| 关键指标卡 | 今日销售金额、今日销售双数、库存总量、在售 SKU 数 | 始终显示 |
| 新款销售榜 | Top N 新款 SKU 列表(含 COS 图片、售价、销量) | 当日有新款销售时 |
| 售罄下样提醒 | 已售罄 SKU 列表(含图片) | 有售罄时,否则不展示 |
| 库存变动概要 | 今日入库/出库/调整概览 | 始终显示 |
| 经营建议 | 大模型分析的洞察文字 | 始终显示(后续转脚本) |
| 底部 | 周报/月报链接(后续版本) | 有对应报告时 |
本页面不展示:店铺级数据(v1.1 加入)、同比环比图表(v1.2 加入)、全量商品列表
| 页面名称 | 触发条件 | 与主导航的关系 |
|---|---|---|
| 历史数据上传页 | 用户在 Dashboard 点击"导入数据" | 独立页面(v1.1) |
功能描述
用户无需操作,系统在每天凌晨 1:00 自动执行:接收 oupu 邮件 → 下载库存 xlsx 和销售 xlsx → 解析 → 更新 inventory_ledger 和 inventory_snapshot。
用户流程
cron 01:00 触发
↓
himlaya 收最新邮件
├─ 有附件 → 下载到 ~/sietadata/inbox/
├─ 无附件 → 跳过本次,记日志
└─ 异常(邮件服务不可用)→ 发飞书告警
↓
step1_parse_inventory.py → 解析库存 xlsx
step2_parse_sales.py → 解析销售 xlsx
↓
step3_process_daily.py
① 推算昨日库存(最近快照 + 流水累加)
② 对比今日库存 → 计算净变化
③ 写入 sale 流水(销售出库)
④ 计算非销售净变动 → 写入 adjustment_in/out
⑤ 写入今日全量库存到 inventory_snapshot(日快照)
⑥ 如果是周一 → 将周日数据存为周快照
├─ 成功 → 日志记录完成
├─ 失败(数据不匹配)→ 发飞书告警,数据保留 mbox 不丢
└─ 失败(xlsx 格式异常)→ 发飞书告警
异常场景
| 异常 | 处理方式 | 反馈 |
|---|---|---|
| 邮件未收到 | cron 跳过,日志记录,次日手动 foxmail 补跑 | 不告警(oupu 可能没发,次日补上即可) |
| xlsx 格式变 | 记录原始文件到 archive/,跳过入库 | 飞书告警:格式异常,人工核查 |
| 推算与今日库存偏差大 | 比较净变化 vs 库存差值,阈值异常时暂停 | 飞书告警:数据不匹配,人工核查 |
| 连续 3 天失败 | 熔断机制:停止 cron 自动跑 | 飞书告警:系统故障,需人工介入 |
功能描述
每日入库完成后,从 SQLite 查询当日数据,生成 H5 报告文件部署到 sieta.vip/sietadata/reports/YYYY-MM-DD-daily.html。
用户流程
每日入库成功
↓
查询当日指标脚本
├─ 总销售额、总销售双数
├─ 在售 SKU 数、库存总量
├─ 新款销售 top 10(含图片 URL)
├─ 售罄 SKU 列表(库存=0)
└─ 同比/环比:上周同日、上月同日(如有历史数据)
↓
分析阶段(大模型 v4-flash)
├─ 输入:以上指标 + 库存变动流水
├─ 输出:经营建议文字(约 200-400 字)
└─ 注:稳定后转 Python 脚本分析,零 token
↓
渲染 H5 模板
├─ HTML + Chart.js + 内联 CSS(手机端适配)
├─ 嵌入 COS 图片(新款/售罄 SKU 图片)
└─ 输出到 ~/sietadata/output/reports/
↓
部署
├─ cp 到 nginx 路径 /var/www/sieta/sietadata/reports/
└─ 记录 report_url = https://sieta.vip/sietadata/reports/YYYY-MM-DD-daily.html
异常场景
| 异常 | 处理方式 | 反馈 |
|---|---|---|
| 数据为空(刚上线) | 显示"数据收集中,明天将呈现完整日报" | 正常推送,但报告内容简版 |
| 分析大模型超时 | 降级为纯数据报告(图表 + 数字,无文字分析) | 正常推送,标注"分析生成中" |
| H5 部署失败 | 保留本地文件,次日手动验证 | 飞书告警:报告部署失败 |
空状态文案:
| 场景 | 文案 |
|---|---|
| 今日无销售 | 当日无销售数据记录 |
| 无新款销售 | 当日暂无新款售出 |
| 无售罄 SKU | 暂无售罄商品 |
| 数据不足以对比 | 历史数据仍在收集中,下周可开启同比对比 |
功能描述
日报 H5 生成后,向飞书群推送一条消息,包含: 1. 新款图片区(核心内容)——当日新款销售中销量最高的 3-5 款,每款含 COS 图片 2. 售罄提醒——已售罄商品列表 3. 关键数字简报——今日销售金额/双数、环比上周同日 4. 报告链接——点开看完整 H5 日报
消息格式
📊 5月16日 Sieta 销售日报
━━━━━━ 今日新款 TOP 3 ━━━━━━
[图片] 新款A | ¥299 | 售出 12 双
[图片] 新款B | ¥359 | 售出 8 双
[图片] 新款C | ¥199 | 售出 6 双
━━━━━━ 售罄提醒 ━━━━━━
· 款式X(¥259)已售罄 - 全部店铺下样
· 款式Y(¥189)仅剩 2 双
━━━━━━ 关键指标 ━━━━━━
今日销售:¥ 28,350(+12% vs 上周同日)
在售 SKU:3,152 款
库存总量:42,380 双
👉 查看完整日报
https://sieta.vip/sietadata/reports/2026-05-16-daily.html
异常场景
| 异常 | 处理方式 | 反馈 |
|---|---|---|
| 飞书 API 不可用 | 跳过推送,报告仍部署到 Web | 不告警(非关键路径) |
| COS 图片链接失效 | 该款不显示图片,仅展示文字 | 日志记录 |
| 连续 3 天推送失败 | 飞书机器人重启通知 | 飞书告警 |
| 阶段 | 任务 | 预估工时 | 里程碑 |
|---|---|---|---|
| A | 数据库建表 + 核心 3 个 pipeline 脚本 | 3 天 | 脚本可跑通一个日期的数据 |
| B | 导入最近 1 个月数据 | 2 天 | 数据库有初始数据,流水正确 |
| C | 导入 2025/2024 年历史数据 | 3 天 | 周/月快照就绪 |
| D | cron 自动化 | 2 天 | 每日凌晨自动跑 |
| E | H5 报告 + 飞书推送 | 5 天 | 可出首份日报 |
| F | 后续迭代(Dashboard/周报/月报) | 第 3 周起 | 持续完善 |
PRD 落地版已完成,六大盲区均已覆盖。