Files
youzan-datahub/README.md

222 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 餐饮零售数据中台 (DataHub)
> 基于有赞云 API 的连锁餐饮数据中台系统,实现订单/商品/客户/库存数据的 T+1 自动同步,并提供商品洞察、会员 RFM 分层、购物篮挖掘、智能订货建议等 BI 分析能力。
---
## 项目结构
```
AIMachineSystem/
├── server/ # Spring Boot 后端服务
│ ├── src/main/java/ # Java 源代码
│ ├── src/main/resources/application.yml # 应用配置
│ └── pom.xml # Maven 依赖管理
├── dashboard-ui/ # 前端 BI 大盘 (纯 HTML/CSS/JS)
│ ├── index.html # 主页面
│ ├── styles.css # 样式 (毛玻璃/苹果设计风格)
│ └── app.js # 数据交互 (ECharts 图表)
├── sql/ # 数据库 DDL & 补丁
│ ├── youzan_tplus1_ddl.sql # 全量建表 (一键建库)
│ └── phase4_alter_outer_item_id.sql # 增量补丁
├── docs/ # 产品需求文档 & 技术设计文档
└── prototype/ # 原型设计
```
---
## 技术栈
| 类别 | 技术 |
|------|------|
| 后端框架 | Java 17 + Spring Boot 3.2.x |
| ORM | MyBatis-Plus 3.5.x |
| 数据库 | MySQL 8.0 |
| 数据源 | 有赞云开放平台 API |
| 前端 | HTML5 + CSS3 + JavaScript + ECharts |
| 构建工具 | Maven |
---
## 安装部署
### 1. 环境要求
- **JDK 17+**
- **Maven 3.8+**
- **MySQL 8.0+**
- 有赞云自用型应用(需要 `client_id``client_secret``grant_id`
### 2. 数据库初始化
```sql
-- 1. 创建数据库
CREATE DATABASE youzandatahub DEFAULT CHARSET utf8mb4;
-- 2. 执行全量建表脚本
SOURCE sql/youzan_tplus1_ddl.sql;
```
### 3. 修改配置
编辑 `server/src/main/resources/application.yml`
```yaml
spring:
datasource:
url: jdbc:mysql://你的IP:3306/youzandatahub?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: 你的用户名
password: 你的密码
youzan:
api:
base-url: https://open.youzanyun.com
client-id: 你的client_id
client-secret: 你的client_secret
kdt-id: 你的kdt_id
```
### 4. 编译 & 启动
```bash
cd server
mvn clean compile
mvn spring-boot:run
```
服务启动后监听 `http://localhost:8080`
### 5. 前端访问
直接用浏览器打开 `dashboard-ui/index.html` 即可,无需额外构建。
> 前端默认连接 `http://localhost:8080` 后端接口,如需修改请编辑 `app.js` 中的 `API_BASE` 变量。
---
## 定时任务 (自动执行)
系统启动后,以下任务每日自动执行,**无需人工干预**
| 执行时间 | 任务名称 | Job 类 | 说明 |
|---------|---------|--------|------|
| 02:00 | 订单同步 | `TradeSyncJob` | 拉取前一天全量订单明细写入 `dwd_trade_order_detail` |
| 02:30 | 商品同步 | `ItemCustomerSyncJob` | 全量同步有赞商品目录到 `dim_item_sku` |
| 02:45 | 客户聚合 | `ItemCustomerSyncJob` | 从订单表聚合客户画像到 `dim_customer_info` |
| 03:00 | 门店同步 | `Phase3SyncJob` | 同步门店/网点信息到 `dim_offline_store` |
| 03:10 | 退款同步 | `Phase3SyncJob` | 拉取前一天退款单到 `dwd_trade_refund_detail` |
| 03:20 | 库存快照 | `Phase3SyncJob` | 采集各门店当日库存到 `dim_inventory_snapshot` |
| 04:00 | 洞察计算 | `InsightComputeJob` | 全域数据市集聚合(详见下方) |
### 04:00 洞察计算明细
| 步骤 | 计算内容 | 写入表 |
|------|---------|--------|
| 1 | 商品日销售趋势 | `adm_item_sales_trend` |
| 2 | 购物篮关联规则 (Apriori Top20) | `adm_item_basket` |
| 3 | 商品30天复购率 & 波士顿矩阵 | `adm_item_repurchase` |
| 4 | 会员 RFM 评分 & 客群分层 | `adm_customer_rfm` |
| 5 | 会员特征标签画像 | `adm_customer_tags` |
| 6 | 智能订货建议 (14天流速) | 实时计算,不落表 |
---
## 手动运行指令
### HTTP 接口 (浏览器直接访问)
| 接口地址 | 用途 |
|---------|------|
| `GET /api/insight/compute-all` | 手动触发全量洞察计算(等同于 04:00 的定时任务) |
| `GET /api/admin/backfill/january-to-now` | 补全今年1月至今全量历史订单+退款+客户(后台异步执行,按天拉取) |
### BI 查询接口 (前端调用)
| 接口地址 | 返回内容 |
|---------|---------|
| `GET /api/dashboard/overview` | 过去14天大盘概览GMV、订单数、退款额、客单价 |
| `GET /api/dashboard/trend` | 过去14天日维销售趋势 |
| `GET /api/product/repurchase` | 商品30天复购率 & 波士顿矩阵打标 |
| `GET /api/product/basket` | 购物篮关联 Top20 |
| `GET /api/product/advice` | 智能订货预测单基于14天日均流速 |
| `GET /api/customer/rfm/distribution` | RFM 客群金字塔分布 |
| `GET /api/customer/tags` | 会员标签统计 |
### 诊断测试脚本 (独立 main 方法)
`server/` 目录下执行:
```powershell
# 有赞 Token 连通性测试
mvn -q compile exec:java `-Dexec.mainClass="com.chuyishidai.datahub.YouzanTokenTest"
# 订单数据诊断 (分页、总量对比)
mvn -q compile exec:java `-Dexec.mainClass="com.chuyishidai.datahub.YouzanOrderDiagTest"
# 商品 item_id 比对诊断
mvn -q compile exec:java `-Dexec.mainClass="com.chuyishidai.datahub.ItemIdDiagTest"
# 退款数据诊断
mvn -q compile exec:java `-Dexec.mainClass="com.chuyishidai.datahub.RefundDiagTest"
```
> **注意**: 在 PowerShell 中 `-D` 前需加反引号 `` ` `` 转义。
---
## 数据分层架构
```
有赞云 API ──► DWD 明细层 (事实表) ──► DIM 维度层 ──► ADM 数据市集层 (洞察)
REST API
前端 BI 大盘
```
| 层级 | 前缀 | 表 | 说明 |
|-----|------|------|------|
| 明细层 | `dwd_` | `dwd_trade_order_detail` | 交易订单明细 |
| | | `dwd_trade_refund_detail` | 退款明细 |
| | | `dwd_inventory_flow_di` | 库存流水 |
| | | `dwd_coupon_flow` | 优惠券流水 |
| 维度层 | `dim_` | `dim_item_sku` | 商品维度 |
| | | `dim_customer_info` | 客户维度 (OneID) |
| | | `dim_offline_store` | 门店维度 |
| | | `dim_inventory_snapshot` | 库存快照 |
| 市集层 | `adm_` | `adm_item_sales_trend` | 商品日销趋势 |
| | | `adm_item_basket` | 购物篮关联 |
| | | `adm_item_repurchase` | 复购率 & 波士顿矩阵 |
| | | `adm_customer_rfm` | RFM 评分 |
| | | `adm_customer_tags` | 客户标签 |
### 重要设计决策
- **商品聚合维度**: 有赞连锁模式下同一商品在不同门店有不同 `item_id`,系统统一使用 `outer_item_id`(商家编码)作为跨门店商品唯一标识。
- **数据同步策略**: 采用 `INSERT ... ON DUPLICATE KEY UPDATE` (Upsert) 保证幂等性。
- **快照表刷新**: `adm_` 前缀的快照型表(除 `adm_item_sales_trend` 外)每次计算前先 `DELETE``INSERT`,确保全量覆盖。
- **餐具过滤**: 购物篮和复购率计算自动过滤 `title LIKE '%餐具%'` 的必选附加品。
---
## 配置参数说明
`application.yml` 中可调整的关键参数:
```yaml
sync:
trade:
cron: "0 0 2 * * ?" # 订单同步 cron 表达式
page-size: 100 # 每页拉取条数
overlap-minutes: 30 # 时间窗口重叠 (防止遗漏边界订单)
```
其他定时任务 cron 通过系统属性覆盖:
- `sync.item.cron` — 商品同步 (默认 02:30)
- `sync.customer.cron` — 客户同步 (默认 02:45)
- `sync.store.cron` — 门店同步 (默认 03:00)
- `sync.refund.cron` — 退款同步 (默认 03:10)
- `sync.inventory.cron` — 库存快照 (默认 03:20)