49 lines
4.1 KiB
Markdown
49 lines
4.1 KiB
Markdown
# Datie ERP 数据自动化项目 - 上下文与进度总结
|
||
|
||
## 1. 项目概况与架构
|
||
- **业务目标**:从 ERP 系统(云MES)自动抓取收货明细与 BOM 成本数据,进行本地清洗、持久化与二次计算,最后通过 Web UI(成本雷达图、期间对比分析表)提供极高数据密度的商业智能看板。
|
||
- **技术栈**:
|
||
- **爬虫端**:Python + DrissionPage (无头浏览器/监听API拦截)。
|
||
- **后端**:Flask + SQLite (单文件存储,`erp_data.db`)。
|
||
- **前端**:Vue 2 + ElementUI + Axios + ECharts,通过 `v-text` 避免与 Jinja2 语法冲突。
|
||
- **部署计划**:最终打包为 Windows `.exe` 单文件应用(PyInstaller),利用 `webbrowser` 开机自启,并引入 `APScheduler` 实现后台每半小时自动增量同步。
|
||
|
||
## 2. 核心业务逻辑与计算公式 (非常重要!)
|
||
|
||
### 2.1 数量字段定义(解决“件数”与“重量”冲突)
|
||
在 ERP 原始数据中,部分物料(如 `1PZJ` 开头的床身毛胚)同时存在件数和转换后的重量。为了保证所有公式正确:
|
||
- **进货数量 (purchase_qty)**:固定读取 `plannedPurchaseQuantity`(例如:8件)。**只代表件数**。
|
||
- **收货数量 (receive_qty)**:优先读取带有转换单位的 `convertGoodsQuantity`(例如:6520 KG),如果没有转换单位则回退到 `goodsQuantity`。**代表实际计价的重量/体积**。
|
||
|
||
### 2.2 核心派生字段计算逻辑
|
||
基于上述字段定义,后端在 [app.py](file:///Users/jm/workplace/Datie/web_ui/app.py) 中动态计算以下指标:
|
||
- **物料单价 (receive_price)**:
|
||
- **公式**:`ROUND(COALESCE(total_amount / NULLIF(receive_qty, 0), receive_price, 0), 2)`
|
||
- **说明**:收货总金额 ÷ 收货数量(重量)。例如:44988元 ÷ 6520 KG = 6.9 元/KG。
|
||
- **铸件重量 (casting_weight)**:
|
||
- **公式**:`receive_qty / purchase_qty`
|
||
- **说明**:收货数量(重量) ÷ 进货数量(件数)。例如:6520 KG ÷ 8 件 = 815 KG/件。该逻辑仅针对物料代码以 `1PZJ` 开头的数据生效。
|
||
- **BOM 用量合并展示**:前端将 `usage_qty` 与 `unit_name` 拼接展示(如 "2PCS")。
|
||
|
||
## 3. UI/UX 设计规范
|
||
- **极端空间压缩**:表格行高极度压缩,去除 padding,字体使用 15px/16px,数据完美居中(Flexbox `justify-content: center`)。
|
||
- **斑马纹设计**:表格行采用白/浅蓝交替背景色,增强可读性。
|
||
- **状态指示器精简**:
|
||
- 移除原先的橙色点(🟠)。
|
||
- **红点 (🔴)**:仅表示该物料在选定期间内无采购数据,当前显示的价格是**追溯至期间以前的最新历史基准价**。
|
||
- **横杠 (-)**:表示该节点(无论是父件还是底层子件)彻底没有历史采购价格,或者成本加总为 0。
|
||
|
||
## 4. 最新进度与修复记录 (2026-04)
|
||
1. **数据抓取逻辑重构**:
|
||
- 修复了爬虫脚本 [fetch_receipt_details_full.py](file:///Users/jm/workplace/Datie/browser_login/fetch_receipt_details_full.py) 和增量脚本的字段映射,确保精准提取 `convert` 系列字段。
|
||
- 优化了入库脚本 [import_to_sqlite.py](file:///Users/jm/workplace/Datie/browser_login/import_to_sqlite.py),加入了 `UPSERT` (存在即更新) 的防重复逻辑。
|
||
2. **后端查询重构**:
|
||
- 修正了 `app.py` 中所有的 SQL 查询,将 `NULLIF(purchase_qty, 0)` 替换为 `NULLIF(receive_qty, 0)`,彻底解决了 8件 vs 6520公斤的计算冲突。
|
||
3. **异步调度集成**:
|
||
- 实现了 [home.html](file:///Users/jm/workplace/Datie/web_ui/templates/home.html) 控制台,通过 `/api/sync_receipts` 等接口利用 `subprocess.run` 异步执行爬虫脚本,前端展示 Loading 状态。
|
||
|
||
## 5. 下一步开发计划 (Next Steps)
|
||
1. **本地测试与验证**:在前端完成所有 BOM 树、期间对比的价格和铸件重量的视觉核对。
|
||
2. **Windows 部署准备**:
|
||
- 配置 `PyInstaller` 的 `.spec` 文件,解决静态资源(templates, static)和数据库外部挂载路径(`sys._MEIPASS`)问题。
|
||
- 在 Flask 启动生命周期中集成 `APScheduler` 以替代目前手动点击按钮触发的增量更新。 |