添加 委外批次进数据库、委外批次入飞书

This commit is contained in:
2026-04-24 19:00:07 +08:00
parent 3e1d479643
commit 65216cd4cf
11 changed files with 1809 additions and 313 deletions
+256
View File
@@ -0,0 +1,256 @@
# Inventory Analytics 工程说明
## 项目概览
当前工程包含两条独立业务链路:
- 委外批次库存上传:通过本地网页上传 Excel/CSV 文件,保存原始文件,并逐行写入 Raw PostgreSQL 表。
- 飞书库存同步:从 Analytics PostgreSQL 查询库存、挂单量、销售和商品信息,并同步到飞书多维表格。
## 目录结构
```text
inventory_analytics/
├── .env
├── PROJECT_GUIDE.md
├── REFACTOR_PLAN.md
├── upload_inventory_page.py
├── list_feishu_base_tables.py
└── inventory_sync/
├── __init__.py
├── cli.py
├── feishu.py
├── postgres.py
├── service.py
├── settings.py
├── specs.py
└── sql.py
```
运行后会自动创建或使用:
```text
batch_inventory_data/
```
该目录保存上传的委外批次库存原始文件,不纳入业务代码结构。
## 环境变量
### 委外批次库存上传
上传页使用 `.env` 中的 Raw 数据库配置:
```text
RAW_DB_HOST
RAW_DB_PORT
RAW_DB_USER
RAW_DB_PASSWORD
RAW_DB_NAME
```
写入目标:
```text
raw_data.wangdian_batch_inventory
```
表结构由 `upload_inventory_page.py` 内的 `get_create_table_sql()` 创建:
```sql
payload JSONB NOT NULL,
start_time TIMESTAMP WITH TIME ZONE,
end_time TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
reserved_1 TEXT,
reserved_2 TEXT
```
### 飞书库存同步
飞书同步使用 `.env` 中的飞书和 Analytics 数据库配置:
```text
FEISHU_APP_ID
FEISHU_APP_SECRET
FEISHU_BASE_URL
FEISHU_APP_TOKEN
ANALYTICS_DB_HOST
ANALYTICS_DB_PORT
ANALYTICS_DB_USER
ANALYTICS_DB_PASSWORD
ANALYTICS_DB_NAME
```
`FEISHU_APP_TOKEN` 可选;当 `FEISHU_BASE_URL` 已包含 `/base/` 或 `/wiki/` 时,可以不单独配置。
## 委外批次库存上传
启动上传页:
```bash
python3 upload_inventory_page.py
```
打开页面:
```text
http://127.0.0.1:8080
```
支持文件:
- `.xlsx`
- `.xlsm`
- `.xls`
- `.csv`
单文件大小限制:
```text
200 MB
```
上传成功后会执行:
1. 保存文件到 `batch_inventory_data/`。
2. 解析 Excel/CSV 为行数据。
3. 创建 Raw schema/table 和 `created_at` 索引。
4. 每一行插入一条 JSONB payload。
payload 示例:
```json
{
"source_file": "委外批次库存.xlsx",
"stored_file": "20260423_172410_委外批次库存.xlsx",
"uploaded_at": "2026-04-23T18:20:00",
"total_count": 120,
"inventory_data": {
"货品编码": "SKU001",
"批次": "BATCH001",
"数量": 10
}
}
```
## 飞书库存同步
查看飞书 Base 表:
```bash
python3 list_feishu_base_tables.py --action feishu
```
只查询 PostgreSQL:
```bash
python3 list_feishu_base_tables.py --action postgres
```
同步品牌库存到飞书:
```bash
python3 list_feishu_base_tables.py --action sync-brand
```
执行完整流程:
```bash
python3 list_feishu_base_tables.py --action all
```
同步目标配置在 `inventory_sync/specs.py`:
```python
BRAND_SYNC_TARGETS = [
BrandSyncTarget(brand_name="羽心堂", table_name="羽心堂", warehouse_keys=(2, 3, 7, 13)),
]
```
字段映射也集中维护在 `inventory_sync/specs.py` 的 `FIELD_SPECS`。
## 日志说明
项目使用结构化事件日志,格式:
```text
YYYY-MM-DD HH:MM:SS LEVEL logger_name 事件=中文事件描述 中文字段=字段值 ...
```
上传页日志输出到 stdout,典型事件包括:
```text
事件=上传服务启动中
事件=收到上传请求
事件=已解析上传文件
事件=上传文件已保存
事件=开始解析库存文件
事件=已解析Excel工作表
事件=已加载Raw数据库配置
事件=Raw数据表确认完成
事件=Raw数据写入完成
事件=上传请求处理完成
```
飞书同步日志输出到 stderr,JSON 结果仍输出到 stdout,便于命令行管道消费。典型事件包括:
```text
事件=飞书同步入口启动
事件=飞书同步动作开始
事件=已加载环境变量文件
事件=开始读取飞书Base信息
事件=开始查询PostgreSQL
事件=开始同步品牌数据
事件=开始同步目标飞书表
事件=目标飞书表同步完成
事件=飞书同步入口完成
```
## 查看和关闭上传服务
查看 8080 端口:
```bash
lsof -nP -iTCP:8080 -sTCP:LISTEN
```
关闭服务:
```bash
kill <PID>
```
如果普通关闭失败:
```bash
kill -9 <PID>
```
## 验证命令
语法检查:
```bash
python3 -m py_compile upload_inventory_page.py list_feishu_base_tables.py inventory_sync/*.py
```
查看飞书同步帮助:
```bash
python3 list_feishu_base_tables.py --help
```
本地启动上传页:
```bash
python3 upload_inventory_page.py
```
## 维护原则
- 上传 Raw 数据保持原始粒度,每行一条 payload,不在上传阶段做复杂业务清洗。
- 飞书同步使用 `inventory_sync/specs.py` 管理品牌目标和字段映射。
- SQL 调整优先修改 `inventory_sync/sql.py`。
- 入口脚本保持稳定,便于人工执行和后续定时任务接入。
- 日志新增时优先使用 `事件=<中文描述>`,并输出足够定位问题的关键字段。