3803 lines
150 KiB
Markdown
3803 lines
150 KiB
Markdown
# 杜康好客 · V2 编码手册(完整规格 · 唯一事实源)
|
||
|
||
> **V3 交付提示**:当前交付验收以 [`杜康好客-v3编码手册.md`](./杜康好客-v3编码手册.md) 为准。本手册中「核销单次上限 ¥500」等规则已被 V3 替代(直接核销可达总余额 / 单据 cap)。
|
||
|
||
> **版本**:**V2**(完整四端 + 微信生态 + 真实第三方)
|
||
> **联调裁剪版**:见 [`杜康好客-preV1编码手册.md`](./杜康好客-preV1编码手册.md)(三端 H5 + Mock,同库同 API 契约)
|
||
> **用途**:V2 正式编码与 preV1 预留对齐的完整规格
|
||
> **日期**:2026-06-27
|
||
> **范围**:郑州开城 · 4 款清香型 SKU · 四端(C端小程序/门店H5/合伙人小程序/总部小程序)
|
||
> **技术栈**:Taro 3 + React + TS · NestJS 10 + Prisma 5 · MySQL 8 · Redis 7 · BullMQ
|
||
> **数据库**:v3.1(28 表,见 §五)
|
||
> **API**:v3.1(见 §六)
|
||
> **协作**:见根目录 `conventions.md`、`agent.md`、`skills.md`
|
||
|
||
---
|
||
|
||
## 文档索引
|
||
|
||
| 章节 | 内容 |
|
||
|------|------|
|
||
| §一 | 项目目标与 V1 范围 |
|
||
| §二 | 产品需求(PRD + 原型对应) |
|
||
| §三 | 原型全清单与页面流 |
|
||
| §四 | 技术架构与模块边界 |
|
||
| §五 | 数据库设计 v3.1 |
|
||
| §六 | API 列表 v3.1 |
|
||
| §七 | 开发计划与任务卡 |
|
||
| §八 | 核心业务链路 |
|
||
| §九 | 第三方集成与非功能 |
|
||
|
||
---
|
||
|
||
# §一、项目目标与 V2 范围
|
||
|
||
杜康好客是杜康酒业 O2O 平台:用户购酒获等额「好客权益」,到合作餐饮门店核销;城市合伙人拓店与履约;总部管开城、商品、结算与客服。
|
||
|
||
| 端 | 载体 | 原型目录 | 后端 Guard |
|
||
|----|------|----------|------------|
|
||
| C端 | 微信小程序 | pages/user/ | UserAuth → user_user |
|
||
| 门店 | H5 | pages/shop/ | StoreAuth → store_account |
|
||
| 合伙人 | 微信小程序 | pages/partner/ | PartnerAuth → partner_account |
|
||
| 总部 | 微信小程序 | pages/hq/ | AdminAuth → hq_account |
|
||
|
||
**V2 锁定**:郑州 · 4 款清香型 · 含退款/推广码/埋点 · 不含会员体系 · 订单 5 Tab(含待发货) · 核销单次上限 ¥500 · 门店 T+1 / 合伙人 T+30 结算。
|
||
|
||
**里程碑**:M0 骨架 → M1 IAM/开城/商品 → M2 交易 → M3 权益核销 → M4 拓店售后 → M5 结算 → M6 推广埋点 → 上线。
|
||
|
||
---
|
||
|
||
# §二、产品需求(PRD)
|
||
|
||
## 1. 项目背景与目标
|
||
|
||
### 1.1 背景
|
||
|
||
杜康好客是杜康酒业的 O2O 消费平台:用户在线购买杜康酒品,同时获得等额「好客权益」用于合作餐饮门店消费;城市合伙人负责拓展本地门店网络与订单履约;总部统一管理开城、商品、结算与客服。
|
||
|
||
### 1.2 产品目标
|
||
|
||
1. 打通「购酒 → 赠权益 → 到店核销」完整闭环
|
||
2. 支持多城市开城,同城/跨城差异化配送
|
||
3. 为城市合伙人、门店、总部提供各自工作台
|
||
4. 可追溯订单来源(推广码)与资金结算
|
||
|
||
### 1.3 产品范围(四端)
|
||
|
||
|
||
| 端 | 载体 | 用户 |
|
||
| ------ | --------- | ---------- |
|
||
| C端 | 微信小程序 | 终端消费者 |
|
||
| 门店端 | H5 | 合作餐饮门店 |
|
||
| 城市合伙人端 | 微信小程序 | 城市合伙人及子账号 |
|
||
| 总部管理端 | **微信小程序** | 总部运营、财务、客服 |
|
||
|
||
|
||
### 1.4 V1 上线范围(已锁定)
|
||
|
||
|
||
| 维度 | V1 范围 | 说明 | |
|
||
| -------- | ---------- | ---------------------- | ----------------- |
|
||
| 开城 | **郑州** | 唯一上线城市;其他城市原型仅作扩展参考 | |
|
||
| 商品 | **4 款清香型** | 酱香型/浓香型 Tab 展示但不可购(灰态) | |
|
||
| 会员体系 | **不实现** | 个人中心仅默认头像 + 昵称 + 平台 ID | |
|
||
| 退款 | | **纳入 V1** | 总部客服中心处理,见 §3.6.2 |
|
||
| 推广码 + 埋点 | **纳入 V1** | 见 §3.10 | |
|
||
| 跨城配送 | 纳入 V1 | 逻辑保留,V1 以郑州同城为主 | |
|
||
|
||
|
||
---
|
||
|
||
## 2. 核心概念
|
||
|
||
### 2.1 好客权益
|
||
|
||
- 用户购酒并支付成功后发放好客权益(餐券)
|
||
- **V1 默认规则**:权益金额 **= 商品售价**(等额)
|
||
- **可配置扩展**:总部商品管理可单独设置「权益金额」字段;未配置时自动取商品售价,便于后续营销活动灵活调整
|
||
- 系统内统一称为「好客权益」,可在合作门店核销抵扣餐饮消费
|
||
- **永久有效**,当前版本不设过期时间
|
||
- 支持部分核销:一张券可多次使用直至余额为 0
|
||
- **单次核销上限**:不超过当前券可用余额(系统校验)
|
||
|
||
### 2.2 开城与订单路由
|
||
|
||
- 总部「开城管理」配置城市及城市合伙人
|
||
- 用户定位/选城决定可见商品与配送方式
|
||
- 订单归属城市 = 收货地址所在城市(用于合伙人业绩与佣金)
|
||
|
||
### 2.3 配送模式
|
||
|
||
|
||
| 模式 | 条件 | 配送方 | 时效 | 运费 | 起购量 |
|
||
| ---- | ---------- | ------ | ------ | --- | -------- |
|
||
| 同城配送 | 地址在已开城同城范围 | 小飞侠 | 24 小时内 | ¥0 | 2 瓶 |
|
||
| 跨城物流 | 超出同城范围 | 总部物流快递 | 依物流 | 到付 | 6 瓶(1 箱) |
|
||
|
||
|
||
---
|
||
|
||
## 3. C端用户小程序
|
||
|
||
**原型目录**:`pages/user/`
|
||
**底部导航**:首页 | 门店 | 好客权益 | 我的
|
||
|
||
| 原型文件 | 页面 | PRD 模块 |
|
||
|----------|------|----------|
|
||
| `pages/user/1-登录.png` | 登录 | §3.1 |
|
||
| `pages/user/2-首页.png` | 首页 | §3.2 |
|
||
| `pages/user/3-商品详情页.png` | 商品详情 | §3.2 |
|
||
| `pages/user/4-立即购买确认订单.png` | 确认订单(同城) | §3.3 |
|
||
| `pages/user/5-订单确认-跨城配送.png` | 确认订单(跨城) | §3.3 |
|
||
| `pages/user/6-地址列表.png` | 地址列表 | §3.4 |
|
||
| `pages/user/7-新增收货地址.png` | 新增地址 | §3.4 |
|
||
| `pages/user/8-微信支付页面.png` | 微信支付 | §3.3 |
|
||
| `pages/user/9-我的订单列表.png` | 订单列表(5 Tab) | §3.5 |
|
||
| `pages/user/10-我的订单-补发状态.png` | 补发订单 | §3.5 |
|
||
| `pages/user/11-我的订单详情.png` | 订单详情 | §3.5 |
|
||
| `pages/user/12-修改地址弹窗.png` | 修改地址 | §3.5 |
|
||
| `pages/user/13-联系客服弹窗.png` | 联系客服 | §3.6 |
|
||
| `pages/user/14-联系在线客服.png` | 在线客服 | §3.6 |
|
||
| `pages/user/15-门店页面-门店列表.png` | 门店列表 | §3.7 |
|
||
| `pages/user/16-门店详情页.png` | 门店详情 | §3.7 |
|
||
| `pages/user/17-好客权益页.png` | 好客权益 | §3.8 |
|
||
| `pages/user/18-好客权益明细.png` | 权益明细 | §3.8 |
|
||
| `pages/user/19-个人中心页.png` | 个人中心 | §3.9 |
|
||
| `pages/user/20-好客权益核销.png` | 核销输入 | §3.8 |
|
||
| `pages/user/21-核销码展示.png` | 核销码 | §3.8 |
|
||
| `pages/user/22-核销成功及评价.png` | 核销成功 | §3.8 |
|
||
|
||
### 3.1 模块一:登录与城市归属
|
||
|
||
**原型**:`1-登录.png`
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ------- | ------------------- |
|
||
| 手机验证码登录 | 输入手机号 + 验证码 |
|
||
| 微信授权登录 | 需勾选用户协议与授权 |
|
||
| 定位授权 | 登录后请求定位,获取市+区(最多两级) |
|
||
| 手动选城 | 用户可手动选择城市/区域 |
|
||
|
||
|
||
**业务规则**
|
||
|
||
- 城市决定后续商品、门店、配送方式
|
||
- **V1 仅郑州开城**;非郑州用户可浏览,下单按跨城/未开通规则处理
|
||
|
||
---
|
||
|
||
### 3.2 模块二:首页与商品展示
|
||
|
||
**原型**:`2-首页.png`、`3-商品详情页.png`
|
||
|
||
#### 3.2.1 首页
|
||
|
||
|
||
| 元素 | 说明 |
|
||
| ------ | --------------------------------- |
|
||
| 品牌区 | 杜康好客 + 当前城市 |
|
||
| 香型 Tab | 清香型 / 酱香型 / 浓香型(**当前仅清香型上线**) |
|
||
| 商品卡片 | 大图 + 标题 + 规格 + 价格 + 好客权益标签 + 立即购买 |
|
||
| 商品数量 | **V1 固定 4 款**清香型,大图列表布局 |
|
||
|
||
|
||
#### 3.2.2 商品详情
|
||
|
||
|
||
| 元素 | 说明 |
|
||
| -------- | ---------------------------------------- |
|
||
| 主图轮播 | 商品主图 |
|
||
| 价格/名称/规格 | 固定展示 |
|
||
| 好客权益说明 | 标准文案:「买杜康美酒·享全城好客礼遇」,展示金额取 `权益金额`(默认同售价) |
|
||
| 图文详情 | 后台商品管理维护,支持图片+文字 |
|
||
| 操作 | 返回首页 / 立即购买 |
|
||
|
||
|
||
**业务规则**
|
||
|
||
- 权益展示/发放金额 = 商品配置的 `benefit_amount`;**未配置时默认 = 商品售价**
|
||
- 首页卡片「享 ¥X 好客权益」同步读取该字段
|
||
|
||
---
|
||
|
||
### 3.3 模块三:下单与微信支付
|
||
|
||
**原型**:`4-立即购买确认订单.png`、`5-订单确认-跨城配送.png`、`6~8`
|
||
|
||
#### 3.3.1 确认订单
|
||
|
||
|
||
| 字段 | 说明 |
|
||
| ----- | ---------------------- |
|
||
| 收货地址 | 必选;跳转地址列表 |
|
||
| 商品信息 | 图、名、规格、单价、数量 |
|
||
| 好客权益 | 本单可享权益金额 |
|
||
| 配送方式 | 同城:小飞侠(预计 24h);跨城:物流配送 |
|
||
| 运费 | 同城 ¥0;跨城显示「到付」 |
|
||
| 合计/实付 | 商品总额 + 运费(跨城不含运费) |
|
||
| 支付 | 仅微信支付 |
|
||
|
||
|
||
#### 3.3.2 跨城提示
|
||
|
||
地址超出同城范围时:
|
||
|
||
- 弹窗/横幅提示:总部物流发货,运费到付,需用户确认继续
|
||
- 配送方式变为「物流配送」,运费标记「到付」
|
||
|
||
#### 3.3.3 起购校验
|
||
|
||
|
||
| 配送类型 | 最低数量 | 不满足时 |
|
||
| ---- | ---- | ---- |
|
||
| 同城 | 2 瓶 | 拦截下单 |
|
||
| 跨城 | 6 瓶 | 拦截下单 |
|
||
|
||
|
||
#### 3.3.4 支付流程
|
||
|
||
1. 点击「微信支付」→ 锁单
|
||
2. 跳转微信支付确认页
|
||
3. 支付成功 → 微信回调 → 订单生成
|
||
4. 初始状态:**待发货**
|
||
5. 支付成功同时**发放好客权益**
|
||
|
||
---
|
||
|
||
### 3.4 模块四:地址管理
|
||
|
||
**原型**:`6-地址列表.png`、`7-新增收货地址.png`
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ---- | ---------------------- |
|
||
| 地址列表 | 历史地址,可选择 |
|
||
| 新增地址 | 收货人、手机号、地区选择、详细地址、是否默认 |
|
||
| 默认地址 | 下单时优先选中 |
|
||
|
||
|
||
---
|
||
|
||
### 3.5 模块五:订单管理
|
||
|
||
**原型**:`9-我的订单列表.png`、`10~12`、`11-我的订单详情.png`
|
||
|
||
#### 3.5.1 订单列表 Tab
|
||
|
||
**原型**:`9-我的订单列表.png`(**5 Tab:全部/待付款/待发货/待收货/已完成**)
|
||
|
||
|
||
| Tab | 包含状态 |
|
||
| ------- | ---------------- |
|
||
| 全部 | 所有(含退款中、已退款、补发单) |
|
||
| 待付款 | 待支付 |
|
||
| **待发货** | 已支付,待出库/待推配送 |
|
||
| 待收货 | 配送中 + 待签收 |
|
||
| 已完成 | 已完成 |
|
||
|
||
|
||
**完整状态机**:`待付款 → 待发货 → 配送中 → 待签收 → 已完成`
|
||
**异常分支**:`退款中 → 已退款`;`补发中`(关联原单,价格 ¥0)
|
||
|
||
> **原型改稿**:`pages/user/9` 需增补「待发货」Tab,详见 `doc/原型说明.md`。
|
||
|
||
#### 3.5.2 列表卡片字段
|
||
|
||
- 订单号、状态
|
||
- 商品图、名称、规格、数量、金额
|
||
- 好客权益使用情况 + 「去使用」按钮(未用完时)
|
||
- 补发单:标记「补发单」,价格 ¥0,提示破损免费补发
|
||
|
||
#### 3.5.3 订单详情
|
||
|
||
|
||
| 区块 | 内容 |
|
||
| ---- | --------------------------- |
|
||
| 进度条 | 下单成功 → 出库中 → 配送中 → 待签收 → 完成 |
|
||
| 商品信息 | 含好客权益引导入口 |
|
||
| 收货信息 | 姓名、地址、配送方式;**待发货/配送中可修改** |
|
||
| 订单信息 | 订单号、创建时间、支付方式 |
|
||
| 结算 | 商品总额、运费、实付 |
|
||
| 操作 | 联系客服、确认收货 |
|
||
|
||
|
||
#### 3.5.4 修改收货地址
|
||
|
||
**原型**:`12-修改地址弹窗.png`
|
||
|
||
- 弹窗提示:系统将尝试拦截配送;拦截失败需联系配送员
|
||
- 若已按原地址签收,不再二次派送
|
||
- **拦截成功**(物流返回「商品已退回」)→ 推送新订单到城市合伙人 → 二次配送
|
||
|
||
---
|
||
|
||
### 3.6 模块六:售后与客服
|
||
|
||
**原型**:`13-联系客服弹窗.png`、`14-联系在线客服.png`
|
||
|
||
|
||
| 渠道 | 说明 |
|
||
| ------ | ------ |
|
||
| 电话客服 | 调起拨号 |
|
||
| 微信图文客服 | 在线实时沟通 |
|
||
|
||
|
||
**补发流程**(破损等):
|
||
|
||
1. 用户联系总部客服,提供订单号
|
||
2. 总部客服发起补发
|
||
3. 通知用户;推送城市合伙人确认
|
||
4. 合伙人确认后进入配送;系统记录补发关联原订单
|
||
|
||
#### 3.6.2 退款流程(V1)
|
||
|
||
**原型**:`pages/hq/26-补发与退款处理.png`
|
||
|
||
|
||
| 环节 | 说明 |
|
||
| ---- | -------------------------------------------------------- |
|
||
| 发起 | 用户通过客服(电话/在线)申请退款,提供订单号与原因 |
|
||
| 受理 | 总部客服在「客服中心」创建退款工单,关联原订单 |
|
||
| 审核 | 总部客服/财务审核;可部分退款或全额退款 |
|
||
| 执行 | 调用微信退款 API;订单状态 → `退款中` → `已退款` |
|
||
| 权益回退 | 若对应好客权益**未使用**:全额退款时作废权益;**已部分核销**:按未使用余额比例退款或人工核算(客服备注) |
|
||
| 通知 | 退款结果推送用户(小程序订阅消息/客服会话) |
|
||
|
||
|
||
**可退款状态**
|
||
|
||
|
||
| 订单状态 | 是否可退 | 说明 |
|
||
| ------- | ---- | ------------------------ |
|
||
| 待付款 | 否 | 用户直接取消/超时关单 |
|
||
| 待发货 | 是 | 全额退款优先 |
|
||
| 配送中 | 是 | 需拦截配送成功后退款 |
|
||
| 待签收/已完成 | 条件可退 | 签收 7 天内且未开瓶/未核销权益,客服人工判定 |
|
||
| 补发单 | 否 | — |
|
||
|
||
|
||
---
|
||
|
||
### 3.7 模块七:门店
|
||
|
||
**原型**:`15-门店页面-门店列表.png`、`16-门店详情页.png`
|
||
|
||
#### 3.7.1 门店列表
|
||
|
||
|
||
| 元素 | 说明 |
|
||
| --- | ----------------------------------- |
|
||
| 定位 | 按用户城市/区域筛选 |
|
||
| 分类 | 火锅、地方菜、高端餐饮、烧烤烤肉等 |
|
||
| 卡片 | 招牌图、名称、评分、人均、支持核销标签、营业状态 |
|
||
| 搜索 | 店名、地址 |
|
||
| 过滤 | **永久闭店、临时闭店均不在 C 端展示**;仅「营业中」门店可见可选 |
|
||
|
||
|
||
#### 3.7.2 门店详情
|
||
|
||
- 大图、名称、状态、评分、标签
|
||
- 环境图(3 张)
|
||
- 地址、距用户距离
|
||
- 电话、导航(调起地图)
|
||
- 图文介绍(后台维护)
|
||
- 「去核销」→ 跳转核销页
|
||
|
||
---
|
||
|
||
### 3.8 模块八:好客权益
|
||
|
||
**原型**:`17-好客权益页.png`、`18-好客权益明细.png`、`20~22`
|
||
|
||
#### 3.8.1 权益首页
|
||
|
||
- 当前余额(汇总)
|
||
- 「去使用」→ 核销流程
|
||
- Tab:待使用 | 已用完/已过期(当前无过期,仅已用完)
|
||
- 券卡片:金额、来源订单、永久有效、已用/未用进度、券编号、立即核销
|
||
|
||
#### 3.8.2 权益明细
|
||
|
||
- 获取记录 + 消费记录
|
||
|
||
#### 3.8.3 核销流程
|
||
|
||
1. 选择门店(或从订单/权益页直接进入)
|
||
2. **核销页**:展示可用余额,输入本次核销金额,支持「全部核销」
|
||
- 校验:`0 < 金额 ≤ min(可用余额, ¥500)`
|
||
- 超出 ¥500 提示「单次最高可核销 ¥500.00」
|
||
3. 点击「生成核销码」→ 展示二维码
|
||
4. 核销码 **5 分钟有效**,一次性使用,可刷新
|
||
5. 门店扫码确认 → **核销成功页**
|
||
6. 快速评价:服务态度、用餐环境(五星,点击即保存)
|
||
|
||
**入口汇总**
|
||
|
||
- 底部 Tab「好客权益」
|
||
- 订单列表/详情「去使用」
|
||
- 门店详情「去核销」
|
||
- 个人中心「去使用」
|
||
|
||
---
|
||
|
||
### 3.9 模块九:个人中心
|
||
|
||
**原型**:`19-个人中心页.png`
|
||
|
||
|
||
| 区块 | 说明 |
|
||
| ---------- | -------------------------------------------- |
|
||
| 用户信息 | 全局默认头像、微信昵称、平台 ID(**V1 无会员等级**,不展示「至尊会员」等标签) |
|
||
| 我的资产 | 好客权益余额 → 明细 |
|
||
| 我的订单 | 待付款/待发货/配送中/已完成 快捷入口 |
|
||
| 地址管理 | 跳转地址列表 |
|
||
| 可用门店 | 跳转门店 Tab |
|
||
| 联系客服 | 同订单页 |
|
||
| 关于我们 / 版本号 | 展示系统版本 |
|
||
| 退出登录 | — |
|
||
|
||
|
||
---
|
||
|
||
### 3.10 模块十:推广码与埋点(V1)
|
||
|
||
**原型**:`pages/hq/16-推广码管理.png`、`17-推广码生成.png`
|
||
|
||
#### 3.10.1 推广码
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ---- | --------------------------------------------- |
|
||
| 创建 | 总部创建推广码,绑定渠道名称(如「XX 品鉴会」) |
|
||
| 扫码归因 | 用户扫码进入小程序,**首次**写入 `channel_source` 至 session |
|
||
| 订单绑定 | 下单时将 `channel_source` 写入订单;合伙人/总部订单详情可查看 |
|
||
| 统计 | 总部数据报表按渠道汇总 GMV、订单量 |
|
||
|
||
|
||
#### 3.10.2 用户行为埋点(V1 事件清单)
|
||
|
||
|
||
| 事件名 | 触发时机 | 关键参数 |
|
||
| -------------------------- | ----------- | ------------------------------- |
|
||
| `app_launch` | 小程序启动 | city, channel_source |
|
||
| `login_success` | 登录成功 | method( sms/wechat ) |
|
||
| `location_grant` | 定位授权结果 | granted, city, district |
|
||
| `home_view` | 首页曝光 | city, aroma_tab |
|
||
| `product_click` | 点击商品卡片 | product_id, price |
|
||
| `product_detail_view` | 商品详情曝光 | product_id, benefit_amount |
|
||
| `order_confirm_view` | 确认订单页曝光 | product_id, qty, delivery_type |
|
||
| `order_submit` | 点击微信支付 | order_id, amount, delivery_type |
|
||
| `pay_success` / `pay_fail` | 支付回调 | order_id, amount, fail_reason |
|
||
| `order_tab_view` | 订单列表 Tab 切换 | tab_name |
|
||
| `store_list_view` | 门店列表曝光 | city, category |
|
||
| `store_detail_view` | 门店详情 | store_id |
|
||
| `benefit_redeem_start` | 进入核销页 | store_id, available_balance |
|
||
| `benefit_qrcode_generate` | 生成核销码 | amount, coupon_id |
|
||
| `benefit_redeem_success` | 核销成功 | amount, store_id |
|
||
| `cs_contact` | 联系客服 | type( phone/chat ) |
|
||
| `promo_scan` | 扫描推广码 | promo_code, channel_name |
|
||
|
||
|
||
**技术要求**
|
||
|
||
- 统一上报 SDK,支持批量上报与失败重试
|
||
- 埋点数据可在总部「数据报表中心」查询(V1 基础统计即可)
|
||
|
||
---
|
||
|
||
## 4. 门店端 H5
|
||
|
||
**原型目录**:`pages/shop/`
|
||
**底部导航**:首页 | 核销记录 | 我的
|
||
|
||
| 原型文件 | 页面 | PRD 模块 |
|
||
|----------|------|----------|
|
||
| `pages/shop/1-登录页.png` | 登录 | §4.1 |
|
||
| `pages/shop/2-一键登录.png` | 快捷登录 | §4.1 |
|
||
| `pages/shop/3-门店管理首页-核销页.png` | 首页核销 | §4.2 |
|
||
| `pages/shop/4-核销确认.png` | 核销确认 | §4.3 |
|
||
| `pages/shop/5-核销成功.png` | 核销成功 | §4.3 |
|
||
| `pages/shop/6-核销记录.png` | 核销记录 | §4.4 |
|
||
| `pages/shop/7-门店信息.png` | 门店信息 | §4.5 |
|
||
|
||
### 4.1 登录
|
||
|
||
**原型**:`1-登录页.png`、`2-一键登录.png`
|
||
|
||
- 门店手机号 + 验证码
|
||
- 微信授权登录
|
||
- 记住登录态,二次进入快捷登录
|
||
- 展示门店名称、绑定手机号
|
||
|
||
### 4.2 首页 · 扫码核销
|
||
|
||
**原型**:`3-门店管理首页-核销页.png`
|
||
|
||
|
||
| 元素 | 说明 |
|
||
| --------------- | ------------------------ |
|
||
| 门店名称 | 当前登录门店 |
|
||
| 今日核销笔数 / 今日到账金额 | 实时统计 |
|
||
| 扫码核销 | 主操作按钮;亦支持微信扫一扫 |
|
||
| 营业状态 | 开店 / 临时闭店切换,**实时同步 C 端** |
|
||
| 最近核销 | 时间 + 金额,倒序 |
|
||
|
||
|
||
**营业规则**
|
||
|
||
- 门店端:开店 / 临时闭店
|
||
- 临时闭店 → **C 端列表隐藏**,不可核销
|
||
- 永久闭店:仅城市合伙人可操作,C 端不可见
|
||
|
||
### 4.3 核销确认
|
||
|
||
**原型**:`4-核销确认.png`、`5-核销成功.png`
|
||
|
||
|
||
| 确认页字段 | 说明 |
|
||
| ----- | -------------- |
|
||
| 当前门店 | 登录门店信息 |
|
||
| 用户手机号 | 脱敏展示 |
|
||
| 核销金额 | 用户输入的面额 |
|
||
| 券编号 | 券 ID |
|
||
| 有效期 | 永久(码本身 5 分钟有效) |
|
||
|
||
|
||
- 点击「确认核销」→ 服务端执行核销
|
||
- 成功 → 用户端更新;门店端展示成功页
|
||
- **短信通知**门店老板:到账金额 + 核销时间
|
||
- 仅**授权且营业中**的门店可核销
|
||
|
||
### 4.4 核销记录
|
||
|
||
**原型**:`6-核销记录.png`
|
||
|
||
|
||
| 筛选项 | 选项 |
|
||
| --- | ------------------- |
|
||
| 时间 | 今日 / 近 7 日 / 近 30 日 |
|
||
| 状态 | 全部 / 待打款 / 已打款 |
|
||
|
||
|
||
|
||
| 汇总 | 说明 |
|
||
| ------ | -------- |
|
||
| 期间核销总额 | 面额合计 |
|
||
| 期间到账总额 | 面额 × 60% |
|
||
| 结算比例 | 60%(6 折) |
|
||
|
||
|
||
|
||
| 明细字段 | 说明 |
|
||
| ----------- | -------------------- |
|
||
| 核销单号、时间 | — |
|
||
| 核销面额 / 到账金额 | 60% |
|
||
| 打款状态 | 待打款 / 已打款 |
|
||
| 打款时间 | 总部打款时间 |
|
||
| **打款周期** | **T+1 工作日**(核销日次日起算) |
|
||
|
||
|
||
- 待打款记录展示「预计打款:T+1 工作日」
|
||
- 账单链接亦可通过服务号/短信通知查看
|
||
|
||
### 4.5 我的 · 门店信息
|
||
|
||
**原型**:`7-门店信息.png`
|
||
|
||
- 门店名称、地址、电话:**仅查看**
|
||
- 修改需联系城市合伙人
|
||
- 营业状态切换
|
||
- 退出登录
|
||
|
||
---
|
||
|
||
## 5. 城市合伙人端小程序
|
||
|
||
**原型目录**:`pages/partner/`
|
||
**底部导航**:首页 | 门店管理 | 合伙人中心
|
||
|
||
| 原型文件 | 页面 | PRD 模块 |
|
||
|----------|------|----------|
|
||
| `pages/partner/1-登录页.png` | 登录 | §5.1 |
|
||
| `pages/partner/2-快捷登录.png` | 快捷登录 | §5.1 |
|
||
| `pages/partner/3-首页.png` | 工作台 | §5.2 |
|
||
| `pages/partner/4-拦截配送.png` | 拦截配送 | §5.6 |
|
||
| `pages/partner/5-门店管理.png` | 门店列表 | §5.3 |
|
||
| `pages/partner/6~8` | 录入门店三步 | §5.3.2 |
|
||
| `pages/partner/9-补发处理.png` | 补发 | §5.5 |
|
||
| `pages/partner/10-财务对账.png` | 财务对账 | §5.7 |
|
||
| `pages/partner/11-周报.png` | 周报 | §5.8 |
|
||
| `pages/partner/12-13` | 订单列表/详情 | §5.4 |
|
||
| `pages/partner/15~16,18` | 子账号/员工 | §5.9 |
|
||
| `pages/partner/17,20-23` | 合伙人中心/结算 | §5.10 |
|
||
|
||
### 5.1 登录与账号
|
||
|
||
**原型**:`1-登录页.png`、`2-快捷登录.png`
|
||
|
||
- 账号由**总部创建**城市合伙人入驻
|
||
- 手机验证码 / 微信授权 / 快捷登录
|
||
- 微信授权有效期 **30 天**
|
||
- 展示:企业名称、地址、入驻城市、手机号
|
||
|
||
### 5.2 工作台首页
|
||
|
||
**原型**:`3-首页.png`
|
||
|
||
|
||
| 指标 | 说明 |
|
||
| ----- | ------------------- |
|
||
| 实时营业额 | 所辖城市酒品订单 GMV |
|
||
| 预计利润 | 营业额 × 35%(30% + 5%) |
|
||
| 门店总数 | 正常运营 / 异常·闭店 |
|
||
| 今日订单量 | 待发货 / 配送中 / 已完成 |
|
||
| 拓店情况 | 下级合伙人拓店统计 |
|
||
| 贡献榜 | 按拓店数排行 |
|
||
|
||
|
||
**快捷入口**:录入新店 | 补发处理 | 财务对账 | 数据周报 | 拦截配送
|
||
|
||
> 脚本明确「今日活跃度」等字段暂不使用。
|
||
|
||
### 5.3 门店管理
|
||
|
||
**原型**:`5-门店管理.png`、`6~8`
|
||
|
||
#### 5.3.1 门店列表
|
||
|
||
- 状态:营业中 / 暂时闭店 / 已关闭(永久闭店)
|
||
- 搜索:名称、地址
|
||
|
||
#### 5.3.2 录入新门店(三步)
|
||
|
||
|
||
| 步骤 | 内容 |
|
||
| ------ | ----------------------------- |
|
||
| 1 基本信息 | 名称*、电话*、地图选址*、门牌号、简介(10~500字) |
|
||
| 2 照片上传 | 门头照、环境照(≥3 张)、签约合同副本 |
|
||
| 3 结算资质 | 银行卡姓名、卡号、开户支行 |
|
||
|
||
|
||
- 提交 → 推送**总部审核**
|
||
- 审核通过 → 门店生效,获得核销权限
|
||
- 合伙人可编辑门店;**永久闭店**仅合伙人可操作
|
||
|
||
#### 5.3.3 审核记录
|
||
|
||
- 待审核 / 已通过 / 已驳回
|
||
- 驳回可修改重新提交
|
||
|
||
### 5.4 订单管理
|
||
|
||
**原型**:`12-订单列表.png`、`13-订单详情.png`
|
||
|
||
- 仅查看**所辖城市**订单
|
||
- 时间:今天 / 近 7 天 / 近 30 天
|
||
- 状态:全部 / 待发货 / 运输中 / 已完成 / 异常(退货补发)/ 拦截
|
||
- 列表:订单号、商品、规格、赠券金额、收货地址
|
||
- 详情:物流状态、佣金(下单 + 核销两笔)、推广渠道来源
|
||
|
||
### 5.5 补发处理
|
||
|
||
**原型**:`9-补发处理.png`
|
||
|
||
- 总部下达补发工单:原订单号、状态
|
||
- 合伙人点击「开始配送」→ 推送城市配送
|
||
- 物流签收回调 或 合伙人手动确认送达
|
||
|
||
### 5.6 拦截配送
|
||
|
||
**原型**:`4-拦截配送.png`
|
||
|
||
- 用户改地址触发拦截通知
|
||
- 合伙人查看详情,发起拦截
|
||
- **拦截成功** → 新地址二次配送(等同正常订单流转)
|
||
- 待配送状态:直接撤回原单
|
||
|
||
### 5.7 财务对账与结算
|
||
|
||
**原型**:`10-财务对账.png`、`22-确认账单.png`、`23-申请打款.png`
|
||
|
||
|
||
| 概念 | 规则 |
|
||
| ---- | --------------------- |
|
||
| 账期 | T+30 天 |
|
||
| 流程 | 总部发起账单 → 合伙人确认 → 总部打款 |
|
||
| 账单状态 | 待结算 / 审核中 / 已结算 |
|
||
| 佣金构成 | 酒品下单佣金 + 权益核销佣金 |
|
||
| 佣金比例 | 总部在开城/合伙人配置处设置 |
|
||
|
||
|
||
**确认账单页**
|
||
|
||
- 展示账期、应结总金额
|
||
- 拆分:订单分佣 + 核销分佣
|
||
- 勾选确认 → 申请打款
|
||
- 仅**主账号**(签约账号)可收账单确认通知;子账号不可
|
||
|
||
### 5.8 经营周报
|
||
|
||
**原型**:`11-周报.png`
|
||
|
||
- 默认近 7 天,可回溯
|
||
- GMV、活跃门店数(有核销即活跃)、购酒订单量
|
||
- 本周新签门店、每日 GMV 趋势、门店核销排行
|
||
|
||
### 5.9 子账号管理
|
||
|
||
**原型**:`15~16`、`18`
|
||
|
||
|
||
| 角色 | 说明 |
|
||
| ----- | ----- |
|
||
| 城市合伙人 | 子级合伙人 |
|
||
| 内部员工 | 拓店人员 |
|
||
| 推广员 | 线下推广 |
|
||
|
||
|
||
- 创建:姓名、手机号(验证码校验)、角色
|
||
- 默认**禁用**,需手动启用
|
||
- 可编辑、禁用、删除
|
||
- 贡献榜按拓店数排名
|
||
|
||
### 5.10 合伙人中心
|
||
|
||
**原型**:`17`、`20-21`
|
||
|
||
- 所在城市、账户余额(待结算 / 已提现)
|
||
- 发起提现 → 总部财务审核
|
||
- 资产明细、合同管理(PDF、编号、签约/到期日期)
|
||
- 门店审核记录、员工管理入口
|
||
|
||
---
|
||
|
||
## 6. 总部管理端(微信小程序)
|
||
|
||
**原型目录**:`pages/hq/`
|
||
**载体**:微信小程序
|
||
**底部导航**:管理中心 | 门店审核 | 结算中心 | 客服中心
|
||
|
||
| 原型文件 | 页面 | PRD 模块 |
|
||
|----------|------|----------|
|
||
| `pages/hq/1-2` | 登录 | §6 |
|
||
| `pages/hq/3-5` | 首页/预警 | §6.1, §6.10 |
|
||
| `pages/hq/6-9` | 开城管理 | §6.2 |
|
||
| `pages/hq/10-11,13,24-25` | 订单中心 | §6.4 |
|
||
| `pages/hq/12,14` | 商品管理 | §6.3 |
|
||
| `pages/hq/15` | 数据报表 | §6.9 |
|
||
| `pages/hq/16-17` | 推广码 | §6.6 |
|
||
| `pages/hq/19-20` | 门店审核 | §6.5 |
|
||
| `pages/hq/21-23` | 结算中心 | §6.7 |
|
||
| `pages/hq/26-27` | 补发退款 | §6.8 |
|
||
|
||
### 6.1 管理中心首页
|
||
|
||
**原型**:`3-数据聚合与预警.png`
|
||
|
||
**今日概况**:订单数、新增用户、核销笔数、新增门店、今日 GMV、累计 GMV、核销金额
|
||
|
||
**待办预警**:超时订单等异常,可跳转处理
|
||
|
||
**核心管理入口**
|
||
|
||
- 开城管理
|
||
- 订单中心
|
||
- 商品管理
|
||
- 推广码
|
||
- 数据报表
|
||
|
||
### 6.2 开城管理
|
||
|
||
**原型**:`6-开城管理.png`、`7-新增城市.png`、`8`、`9-配置佣金比例.png`
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ---- | --------------- |
|
||
| 城市列表 | 运营中 / 暂停 / 待开城 |
|
||
| 城市卡片 | 合伙人、门店数、累计 GMV |
|
||
| 操作 | 编辑、暂停/恢复、配置 |
|
||
| 新增城市 | 基本信息 + 开户行 + 附件 |
|
||
| 佣金配置 | 下单佣金比例、核销佣金比例 |
|
||
|
||
|
||
### 6.3 商品管理
|
||
|
||
**原型**:`12-商品列表.png`、`14-商品添加.png`
|
||
|
||
- 杜康系列酒品 CRUD
|
||
- 字段:名称、规格、价格、香型、主图、图文详情、**权益金额(可选)**
|
||
- **权益金额规则**:留空 = 默认等于售价;填写 = 按配置值发放与展示
|
||
- V1 上架 **4 款清香型**;上下架控制
|
||
|
||
### 6.4 订单中心
|
||
|
||
**原型**:`10-11`、`13-1~4`、`24-跨城订单处理.png`、`25-发货处理.png`
|
||
|
||
- 全链路订单监控
|
||
- 搜索:订单号、手机号、城市;时间筛选
|
||
- 状态筛选:待发货 / 配送中 / 已完成 / 异常
|
||
- 跨城订单:总部物流发货处理
|
||
- 订单详情:完整履约信息、佣金拆分、推广来源
|
||
|
||
### 6.5 门店审核
|
||
|
||
**原型**:`19-门店审核管理.png`、`20-门店详情页面.png`
|
||
|
||
|
||
| Tab | 说明 |
|
||
| -------------------- | --- |
|
||
| 全部 / 待审核 / 已通过 / 已驳回 | — |
|
||
|
||
|
||
- 审核类型:首次入驻 / 信息修改
|
||
- 操作:查看详情、修改、通过、驳回
|
||
- 总部也可编辑门店信息
|
||
|
||
### 6.6 推广码管理
|
||
|
||
**原型**:`16-推广码管理.png`、`17-推广码生成.png`
|
||
|
||
- 创建推广码(品鉴会等场景)
|
||
- 关联渠道名称
|
||
- 订单归因统计
|
||
|
||
### 6.7 结算中心
|
||
|
||
**原型**:`21-结算中心.png`、`22-23`
|
||
|
||
**Tab**:城市合伙人结算 | 门店结算
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ----- | --------------------------- |
|
||
| 待结算总额 | 汇总 |
|
||
| 待处理记录 | 发送账单 / 确认打款 |
|
||
| 门店结算 | 核销打款给门店(60%),周期 **T+1 工作日** |
|
||
|
||
|
||
**结算周期对比**
|
||
|
||
|
||
| 对象 | 周期 | 流程 |
|
||
| ----- | -------- | --------------------- |
|
||
| 门店 | **T+1** | 总部按日/批打款,门店核销记录标记已打款 |
|
||
| 城市合伙人 | **T+30** | 账期 → 发账单 → 合伙人确认 → 打款 |
|
||
|
||
|
||
### 6.8 客服中心 · 补发与退款
|
||
|
||
**原型**:`26-补发与退款处理.png`、`27-补发详情页面.png`
|
||
|
||
|
||
| 功能 | 说明 |
|
||
| ---- | --------------------------------- |
|
||
| 补发 | 输入订单号 → 创建补发单 → 推送合伙人 → 跟踪配送 |
|
||
| 退款 | 输入订单号 → 创建退款工单 → 审核 → 微信退款 → 权益回退 |
|
||
| 工单列表 | 待处理 / 已完成;类型:补发 / 退款 |
|
||
| 关联查询 | 原订单、补发单、退款单互相关联 |
|
||
|
||
|
||
### 6.9 数据报表
|
||
|
||
**原型**:`15-数据报表中心.png`
|
||
|
||
- 全链路经营数据看板
|
||
|
||
### 6.10 预警
|
||
|
||
**原型**:`4-预警详情.png`、`5-超时订单详情.png`
|
||
|
||
- 超时未处理订单预警
|
||
- 跳转订单处理
|
||
|
||
---
|
||
|
||
## 7. 关键业务流程
|
||
|
||
### 7.1 购酒履约
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as C端用户
|
||
participant S as 系统
|
||
participant W as 微信支付
|
||
participant D as 小飞侠/物流
|
||
participant P as 城市合伙人
|
||
|
||
U->>S: 选商品、地址、数量
|
||
S->>S: 校验起购量、配送方式
|
||
U->>W: 微信支付
|
||
W->>S: 支付回调
|
||
S->>S: 订单待发货 + 发放好客权益
|
||
S->>D: 推送配送
|
||
D->>S: 状态回调(出库/配送中/签收)
|
||
S->>U: 更新订单进度
|
||
Note over P: 同城由合伙人辖区履约
|
||
```
|
||
|
||
|
||
|
||
### 7.2 好客权益核销
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as C端用户
|
||
participant S as 系统
|
||
participant M as 门店H5
|
||
|
||
U->>S: 选门店、输入核销金额
|
||
S->>U: 生成二维码(5min有效)
|
||
M->>S: 扫码
|
||
S->>M: 展示确认页(金额/用户/券)
|
||
M->>S: 确认核销
|
||
S->>U: 核销成功 + 评价
|
||
S->>M: 更新记录 + 短信通知老板
|
||
```
|
||
|
||
|
||
|
||
### 7.3 门店入驻
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[合伙人录入门店] --> B[总部审核]
|
||
B -->|通过| C[门店生效可核销]
|
||
B -->|驳回| D[合伙人修改重提]
|
||
C --> E[C端可见可选]
|
||
```
|
||
|
||
|
||
|
||
### 7.4 合伙人结算
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[T+30 账期到期] --> B[总部发起账单]
|
||
B --> C[合伙人确认]
|
||
C --> D[总部打款]
|
||
D --> E[已结算]
|
||
```
|
||
|
||
|
||
|
||
### 7.5 门店核销打款(T+1)
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[门店确认核销] --> B[记录待打款]
|
||
B --> C[T+1 工作日]
|
||
C --> D[总部批量打款]
|
||
D --> E[门店记录已打款]
|
||
```
|
||
|
||
|
||
|
||
### 7.6 退款流程
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant U as C端用户
|
||
participant CS as 总部客服
|
||
participant S as 系统
|
||
participant W as 微信退款
|
||
|
||
U->>CS: 申请退款(订单号)
|
||
CS->>S: 创建退款工单
|
||
CS->>S: 审核通过
|
||
S->>W: 发起退款
|
||
W->>S: 退款回调
|
||
S->>S: 回退未使用权益
|
||
S->>U: 通知退款结果
|
||
```
|
||
|
||
|
||
|
||
---
|
||
|
||
## 8. 非功能需求(初稿)
|
||
|
||
|
||
| 类别 | 要求 |
|
||
| --- | --------------------------- |
|
||
| 安全 | 手机号脱敏;核销码一次性+短时效 |
|
||
| 性能 | 首页/列表首屏 < 2s(目标,待压测确认) |
|
||
| 兼容 | 微信小程序基础库版本 **待确认** |
|
||
| 通知 | 短信(核销到账、账单链接);微信服务号 **待确认** |
|
||
|
||
|
||
---
|
||
|
||
## 9. V1 决策记录(已确认)
|
||
|
||
|
||
| # | 决策项 | 结论 |
|
||
| --- | ------ | -------------------------- |
|
||
| 1 | 好客权益金额 | 默认 = 酒价;商品管理支持单独配置 |
|
||
| 2 | 暂停营业门店 | C 端完全隐藏 |
|
||
| 3 | 订单 Tab | 增加「待发货」:全部/待付款/待发货/待收货/已完成 |
|
||
| 4 | V1 范围 | 含退款、推广码、埋点;不含会员体系 |
|
||
| 5 | 上线范围 | 郑州 + 4 款清香型 |
|
||
| 6 | 总部端载体 | 微信小程序 |
|
||
| 7 | 核销单次上限 | ¥500 |
|
||
| 8 | 门店打款 | T+1 工作日 |
|
||
|
||
|
||
---
|
||
|
||
## 10. 待技术对接事项
|
||
|
||
|
||
| # | 事项 | 说明 |
|
||
| --- | ----------- | -------------------- |
|
||
| 1 | 小飞侠 API | 出库/配送中/签收状态枚举与回调格式 |
|
||
| 2 | 跨城物流 API | 发货、轨迹、签收回调 |
|
||
| 3 | 微信退款 API | 退款时效、部分退款能力 |
|
||
| 4 | 小程序基础库版本 | 四端最低兼容版本 |
|
||
| 5 | 服务费 | V1 结算不扣除服务费;后续版本预留字段 |
|
||
| 6 | 总部小程序 appId | 独立应用 or 子包方案 |
|
||
|
||
|
||
---
|
||
|
||
## 11. V1 里程碑
|
||
|
||
|
||
| 阶段 | 范围 | 交付 |
|
||
| ----- | -------------------------- | --------- |
|
||
| M1 基础 | 郑州开城、4 SKU、账号、总部小程序 | 可配置商品与开城 |
|
||
| M2 交易 | C端下单支付、待发货 Tab、同城配送 | 完整购酒履约 |
|
||
| M3 权益 | 权益发放(可配置金额)、门店、核销(¥500 上限) | O2O 闭环 |
|
||
| M4 运营 | 合伙人门店录入、补发/拦截、退款工单 | 城市运营 + 售后 |
|
||
| M5 结算 | 门店 T+1 打款、合伙人 T+30 对账 | 资金闭环 |
|
||
| M6 增长 | 推广码归因、行为埋点、数据报表 | 渠道可追溯 |
|
||
|
||
|
||
---
|
||
|
||
|
||
---
|
||
|
||
# §三、原型全清单与页面流
|
||
|
||
## C端用户 `pages/user/`
|
||
|
||
| 文件 | 页面 | 关联模块 |
|
||
|------|------|----------|
|
||
| 1-登录.png | 登录 | 账号 |
|
||
| 2-首页.png | 首页 | 商品展示、城市定位 |
|
||
| 3-商品详情页.png | 商品详情 | 商品、好客权益说明 |
|
||
| 4-立即购买确认订单.png | 确认订单(同城) | 下单 |
|
||
| 5-订单确认-跨城配送.png | 确认订单(跨城到付) | 下单、配送规则 |
|
||
| 6-地址列表.png | 地址列表 | 地址管理 |
|
||
| 7-新增收货地址.png | 新增地址 | 地址管理 |
|
||
| 8-微信支付页面.png | 微信支付 | 支付 |
|
||
| 9-我的订单列表.png | 订单列表 | 订单 | **5 Tab(含待发货)** |
|
||
| 10-我的订单-补发状态.png | 补发订单 | 售后 |
|
||
| 11-我的订单详情.png | 订单详情 | 订单履约 |
|
||
| 12-修改地址弹窗.png | 修改地址 | 订单 |
|
||
| 13-联系客服弹窗.png | 联系客服 | 客服 |
|
||
| 14-联系在线客服.png | 在线客服 | 客服 |
|
||
| 15-门店页面-门店列表.png | 门店列表 | 门店 |
|
||
| 16-门店详情页.png | 门店详情 | 门店 |
|
||
| 17-好客权益页.png | 好客权益 | 权益 |
|
||
| 18-好客权益明细.png | 权益明细 | 权益 |
|
||
| 19-个人中心页.png | 个人中心 | 我的 | V1 移除「至尊会员」标签 |
|
||
| 20-好客权益核销.png | 核销输入 | 核销 |
|
||
| 21-核销码展示.png | 核销码 | 核销 |
|
||
| 22-核销成功及评价.png | 核销成功 | 核销、评价 |
|
||
|
||
**底部导航**:首页 | 门店 | 好客权益 | 我的
|
||
|
||
## 门店端 H5 `pages/shop/`
|
||
|
||
| 文件 | 页面 | 关联模块 |
|
||
|------|------|----------|
|
||
| 1-登录页.png | 登录 | 账号 |
|
||
| 2-一键登录.png | 快捷登录 | 账号 |
|
||
| 3-门店管理首页-核销页.png | 首页 | 核销、营业状态 |
|
||
| 4-核销确认.png | 核销确认 | 核销 |
|
||
| 5-核销成功.png | 核销成功 | 核销 |
|
||
| 6-核销记录.png | 核销记录 | 账单 |
|
||
| 7-门店信息.png | 门店信息 | 门店 |
|
||
|
||
**底部导航**:首页 | 核销记录 | 我的
|
||
|
||
## 城市合伙人 `pages/partner/`
|
||
|
||
| 文件 | 页面 | 关联模块 |
|
||
|------|------|----------|
|
||
| 1-登录页.png | 登录 | 账号 |
|
||
| 2-快捷登录.png | 快捷登录 | 账号 |
|
||
| 3-首页.png | 工作台首页 | 概览 |
|
||
| 4-拦截配送.png | 拦截配送 | 订单拦截 |
|
||
| 5-门店管理.png | 门店管理 | 门店 |
|
||
| 6-录入门店.png | 录入门店-基本信息 | 门店入驻 |
|
||
| 7-录入门店-合同.png | 录入门店-照片合同 | 门店入驻 |
|
||
| 8-录入门店银行卡号.png | 录入门店-结算信息 | 门店入驻 |
|
||
| 9-补发处理.png | 补发处理 | 售后 |
|
||
| 10-财务对账.png | 财务对账 | 结算 |
|
||
| 11-周报.png | 经营周报 | 数据 |
|
||
| 12-订单列表.png | 订单列表 | 订单 |
|
||
| 13-订单详情.png | 订单详情 | 订单 |
|
||
| 14-贡献榜.png | 合伙人贡献榜 | 拓店 |
|
||
| 15-子账号管理.png | 子账号管理 | 账号 |
|
||
| 16-添加子账号.png | 添加子账号 | 账号 |
|
||
| 17-合伙人中心.png | 合伙人中心 | 我的 |
|
||
| 18-员工管理.png | 员工管理 | 账号 |
|
||
| 19-门店核销列表.png | 门店核销列表 | 权益 |
|
||
| 20-资产列表.png | 资产明细 | 佣金 |
|
||
| 21-合同管理.png | 合同管理 | 合同 |
|
||
| 22-确认账单.png | 确认账单 | 结算 |
|
||
| 23-申请打款.png | 申请打款 | 结算 |
|
||
|
||
**底部导航**:首页 | 门店管理 | 合伙人中心
|
||
|
||
## 总部管理 `pages/hq/`
|
||
|
||
| 文件 | 页面 | 关联模块 |
|
||
|------|------|----------|
|
||
| 1-登录.png | 登录 | 账号 |
|
||
| 2-快捷登录.png | 快捷登录 | 账号 |
|
||
| 3-数据聚合与预警.png | 管理中心首页 | 概览 |
|
||
| 4-预警详情.png | 预警详情 | 预警 |
|
||
| 5-超时订单详情.png | 超时订单 | 订单 |
|
||
| 6-开城管理.png | 开城管理 | 开城 |
|
||
| 7-新增城市.png | 新增城市 | 开城 |
|
||
| 8-完善开户行与附件上传.png | 开城-银行信息 | 开城 |
|
||
| 9-配置佣金比例.png | 配置佣金比例 | 开城/佣金 |
|
||
| 10-订单中心.png | 订单中心搜索 | 订单 |
|
||
| 11-订单中心管理页.png | 订单中心列表 | 订单 |
|
||
| 12-商品列表.png | 商品列表 | 商品 |
|
||
| 13-订单详情-1~4.png | 订单详情 | 订单 |
|
||
| 14-商品添加.png | 商品添加 | 商品 |
|
||
| 15-数据报表中心.png | 数据报表 | 数据 |
|
||
| 16-推广码管理.png | 推广码管理 | 营销 |
|
||
| 17-推广码生成.png | 推广码生成 | 营销 |
|
||
| 18-佣金拆分和订单.png | 佣金拆分 | 佣金 |
|
||
| 19-门店审核管理.png | 门店审核 | 门店 |
|
||
| 20-门店详情页面.png | 门店详情 | 门店 |
|
||
| 21-结算中心.png | 结算中心 | 结算 |
|
||
| 22-账单明细.png | 账单明细 | 结算 |
|
||
| 23-门店结算明细.png | 门店结算 | 结算 |
|
||
| 24-跨城订单处理.png | 跨城订单 | 订单 |
|
||
| 25-发货处理.png | 发货处理 | 订单 |
|
||
| 26-补发与退款处理.png | 补发退款 | 售后 |
|
||
| 27-补发详情页面.png | 补发详情 | 售后 |
|
||
|
||
**底部导航**:管理中心 | 门店审核 | 结算中心 | 客服中心
|
||
|
||
## 第三方集成清单
|
||
|
||
| 系统 | 用途 | 触发场景 |
|
||
|------|------|----------|
|
||
| 微信登录/支付 | 登录、下单支付 | C端、门店、合伙人 |
|
||
| 微信客服 | 图文客服 | C端联系客服 |
|
||
| 小飞侠 | 同城配送状态回调 | 出库、配送中、签收 |
|
||
| 物流快递 | 跨城配送状态 | 跨城订单 |
|
||
| 微信地图 | 选址、导航 | 地址、门店 |
|
||
| 短信 | 核销到账通知、账单链接 | 门店老板 |
|
||
| 微信扫一扫 | 门店核销(H5 外) | 门店端 |
|
||
|
||
|
||
### C 端页面流
|
||
|
||
`
|
||
登录(1) → 首页(2) → 商品详情(3) → 确认订单(4/5) → 支付(8)
|
||
订单列表(9) → 订单详情(11) → 修改地址(12)
|
||
门店列表(15) → 门店详情(16) → 核销(20) → 核销码(21) → 成功(22)
|
||
好客权益(17) → 明细(18) → 个人中心(19) → 地址(6/7)
|
||
`
|
||
|
||
### 原型与 PRD 差异(实现以 PRD 为准)
|
||
|
||
| 原型 | 说明 |
|
||
|------|------|
|
||
| pages/user/9 | Tab 必须为 5 个:全部/待付款/**待发货**/待收货/已完成 |
|
||
| pages/user/19 | 移除「至尊会员」标签 |
|
||
| 各端城市示例 | 原型多为洛阳,V1 上线城市为**郑州** |
|
||
|
||
---
|
||
|
||
# §四、技术架构
|
||
|
||
|
||
|
||
### 1.1 建设目标
|
||
|
||
在 V1 范围内(郑州开城、4 SKU、四端协同)交付可运营的生产系统,支撑:
|
||
|
||
- 购酒交易与微信支付的可靠闭环
|
||
- 好客权益发放、核销与门店 T+1 结算
|
||
- 城市合伙人拓店、履约、T+30 分佣结算
|
||
- 总部开城/商品/审核/客服/数据运营
|
||
- 推广码归因与用户行为埋点
|
||
|
||
### 1.2 架构原则
|
||
|
||
| 原则 | 说明 |
|
||
|------|------|
|
||
| **方案三:统一后端 + 模块归属** | 一个 NestJS 进程;全栈按「端 + 后端模块」分工,禁止多端各自起服务、仅共库 |
|
||
| **单体优先、模块化拆分** | V1 单进程部署;模块间通过 **Exported Service** 协作,禁止跨模块直写表 |
|
||
| **多端复用、统一 API** | 四端共用 REST API;契约见本手册 §六 |
|
||
| **事件驱动异步** | 支付/配送回调、埋点、T+1 结算走 BullMQ,保证幂等 |
|
||
| **开城可扩展** | 城市、佣金、配送规则配置化 |
|
||
| **财务可追溯** | 订单、权益、核销、打款全链路留痕 |
|
||
| **共享类型优先** | 枚举/DTO 放 `packages/shared-types`,禁止各端复制业务常量 |
|
||
|
||
### 1.3 推荐技术栈(总览)
|
||
|
||
| 层次 | 推荐选型 | 备选 |
|
||
|------|----------|------|
|
||
| C端 / 合伙人 / 总部小程序 | **Taro 3 + React + TypeScript** | 原生微信小程序 ×3 |
|
||
| 门店 H5 | **Taro H5**(与小程序同 monorepo) | Vue3 + Vite 独立 H5 |
|
||
| 后端 API | **Node.js 20 LTS + NestJS 10** | Express / Koa(需自建分层) |
|
||
| ORM | **Prisma** | TypeORM |
|
||
| 主库 | **MySQL 8.0** | — |
|
||
| 缓存 / 锁 / 队列 | **Redis 7** + **BullMQ** | ioredis 直连 |
|
||
| 对象存储 | 阿里云 OSS / 腾讯云 COS | — |
|
||
| 定时任务 | **@nestjs/schedule** + BullMQ 延时队列 | node-cron |
|
||
| 埋点 | 自建 `log_user_analytics` + BullMQ 异步入库 | — |
|
||
| 部署 | Docker + PM2 或 Node 单进程 + Nginx | K8s(二期) |
|
||
| CI/CD | GitHub Actions / GitLab CI | — |
|
||
|
||
**选型理由(NestJS + Taro 全栈 TypeScript)**
|
||
|
||
- **与前端同语言**:Taro 与 NestJS 共用 TypeScript,DTO/枚举可抽到 `packages/shared-types`,减少联调成本
|
||
- **NestJS 模块化**:Module/Controller/Service 分层清晰,接近 Spring 结构,适合订单/结算等复杂域
|
||
- **微信生态**:`wechatpay-node-v3`、小程序 code2session 等 Node SDK 成熟,满足 V1 支付/退款
|
||
- **异步友好**:支付回调、埋点、短信等 I/O 密集场景 Node 表现良好
|
||
- V1 仍为**模块化单体**,无需微服务
|
||
|
||
---
|
||
|
||
## 2. 系统架构
|
||
|
||
### 2.1 逻辑架构
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph clients [客户端]
|
||
U[C端小程序]
|
||
P[合伙人小程序]
|
||
H[总部小程序]
|
||
S[门店 H5]
|
||
end
|
||
|
||
subgraph gateway [接入层]
|
||
NG[Nginx / HTTPS]
|
||
end
|
||
|
||
subgraph app [dukang-api 单体服务]
|
||
direction TB
|
||
M1[iam 身份认证]
|
||
M2[catalog 商品开城]
|
||
M3[trade 交易订单]
|
||
M4[benefit 好客权益]
|
||
M5[store 门店]
|
||
M6[redeem 核销]
|
||
M7[settlement 结算]
|
||
M8[ops 总部运营]
|
||
M9[notify 通知集成]
|
||
M10[analytics 埋点报表]
|
||
end
|
||
|
||
subgraph infra [基础设施]
|
||
DB[(MySQL)]
|
||
RD[(Redis)]
|
||
OSS[对象存储]
|
||
end
|
||
|
||
subgraph ext [外部系统]
|
||
WX[微信登录/支付/退款/客服]
|
||
XFX[小飞侠配送]
|
||
LOG[物流快递]
|
||
SMS[短信]
|
||
end
|
||
|
||
U & P & H & S --> NG --> app
|
||
app --> DB & RD & OSS
|
||
app --> WX & XFX & LOG & SMS
|
||
```
|
||
|
||
### 2.2 部署架构(V1)
|
||
|
||
```
|
||
┌──────────────┐
|
||
│ CDN/OSS │ 静态资源、图片
|
||
└──────────────┘
|
||
┌─────────┐ ┌──────────────┐ ┌─────────┐
|
||
│ 微信小程序 │ ──────►│ Nginx + SSL │────────►│ MySQL │
|
||
│ ×3 + H5 │ │ NestJS :3000 │ │ 主从可选 │
|
||
└─────────┘ └──────┬───────┘ └─────────┘
|
||
│
|
||
└────────────────► Redis + BullMQ
|
||
```
|
||
|
||
- **环境**:dev / staging / prod 三套
|
||
- **配置**:敏感项走环境变量(`.env` 不入库);生产用 Docker secrets
|
||
- **日志**:Pino 结构化 JSON + 请求 traceId(nestjs-pino)
|
||
- **进程**:PM2 cluster 或 Docker 单副本;V1 单实例即可
|
||
|
||
### 2.3 仓库结构(Monorepo 建议)
|
||
|
||
```
|
||
dukang/
|
||
├── apps/
|
||
│ ├── mini-user/ # C端 Taro 小程序
|
||
│ ├── mini-partner/ # 合伙人 Taro 小程序
|
||
│ ├── mini-hq/ # 总部 Taro 小程序
|
||
│ └── h5-shop/ # 门店 H5(Taro 或独立)
|
||
├── packages/
|
||
│ ├── shared-ui/ # 公共组件(前端)
|
||
│ ├── shared-utils/ # 工具、常量
|
||
│ ├── shared-types/ # API DTO、枚举、错误码(前后端共用)
|
||
│ └── domain/ # 纯函数领域规则(起购/核销上限/权益计算,无 IO)
|
||
├── server/
|
||
│ └── dukang-api/ # 唯一后端进程(NestJS 单体)
|
||
│ ├── prisma/ # schema 按模块 OWNER 分区注释,迁移需 OWNER Review
|
||
│ └── src/
|
||
│ ├── common/ # 全局:Guard、Filter、PrismaModule
|
||
│ ├── modules/ # 见 §2.4 模块归属
|
||
│ ├── callbacks/ # 微信/配送回调(薄层,转调各 Module Service)
|
||
│ └── jobs/ # BullMQ 消费者、定时任务
|
||
├── doc/
|
||
└── deploy/
|
||
```
|
||
|
||
---
|
||
|
||
## 2.4 多人协作架构(方案三)
|
||
|
||
### 2.4.1 方案定义
|
||
|
||
| 项 | 结论 |
|
||
|----|------|
|
||
| 选定方案 | **方案三**:Monorepo + **一个** NestJS 后端 + 模块 OWNER + 全栈负责「端 + 模块」 |
|
||
| 明确不做 | 多端各自独立后端、仅数据库对齐;多个微信支付回调入口 |
|
||
| 协作单元 | **后端 Module**(领域边界)+ **前端 App**(交互边界) |
|
||
| 集成契约 | HTTP API(`doc/API列表-杜康好客.md`)+ `shared-types` + Prisma schema(OWNER Review) |
|
||
|
||
### 2.4.2 分工模型
|
||
|
||
```
|
||
全栈开发者 A ──► apps/mini-user + modules/{iam,trade,benefit} Controller
|
||
全栈开发者 B ──► apps/mini-partner + modules/{store} + 部分 partner 接口
|
||
全栈开发者 C ──► apps/mini-hq + modules/{catalog,ops,settlement} 总部侧
|
||
全栈开发者 D ──► apps/h5-shop + modules/{redeem} + 门店侧接口
|
||
公共 ──► packages/* , callbacks/, jobs/ , prisma 迁移(架构师/轮值 Review)
|
||
```
|
||
|
||
> OWNER 为**主责**(改代码、Review PR、负责迁移),非 OWNER 提需求走 Issue + 跨模块 PR。
|
||
|
||
### 2.4.3 模块与端归属表
|
||
|
||
| 后端模块 | 职责摘要 | 主 OWNER 建议 | 关联前端 App | 关联 API 前缀 |
|
||
|----------|----------|---------------|--------------|---------------|
|
||
| **iam** | 登录、JWT、四端鉴权、用户身份 U1~U5 | 全栈 A | 四端共用 | `/auth`, `/user` |
|
||
| **catalog** | 开城、商品、推广码、佣金配置 | 全栈 C | mini-hq | `/catalog`, `/admin/cities`, `/admin/products`, `/admin/promo-codes` |
|
||
| **trade** | 订单、支付、退款、拦截、补发单 | 全栈 A | mini-user, mini-partner, mini-hq | `/trade`, `/admin/orders`, `/partner/orders` |
|
||
| **benefit** | 权益券、流水、发放/作废 | 全栈 A | mini-user | `/benefit` |
|
||
| **store** | 门店 CRUD、审核、营业状态 | 全栈 B | mini-partner, mini-user, mini-hq | `/stores`, `/partner/stores`, `/admin/store-audits` |
|
||
| **redeem** | 核销码、确认核销、评价 | 全栈 D | h5-shop, mini-user | `/redeem`, `/shop/redeem` |
|
||
| **settlement** | 门店 T+1、合伙人 T+30、提现 | 全栈 C | mini-partner, h5-shop, mini-hq | `/settlement`, `/partner/settlement`, `/admin/settlement` |
|
||
| **ops** | 总部看板、预警、报表聚合 | 全栈 C | mini-hq | `/admin/dashboard`, `/admin/reports`, `/admin/alerts` |
|
||
| **notify** | 短信、订阅消息(被各模块调用) | 轮值 / 架构 | — | 内部 Service |
|
||
| **analytics** | 埋点入库、渠道统计 | 全栈 A | mini-user + 总部报表 | `/analytics`, `/promo/touch` |
|
||
| **callbacks** | 微信/小飞侠/物流回调入口 | 架构师 + trade OWNER | — | `/callbacks/*` |
|
||
| **jobs** | 超时关单、T+1 打款、出账 | settlement + trade OWNER | — | 内部 |
|
||
|
||
### 2.4.4 协作规则(强制)
|
||
|
||
| # | 规则 |
|
||
|---|------|
|
||
| R1 | **禁止** Module A 直接使用 `PrismaService` 读写 Module B 拥有的表;只调用 B 导出的 `XxxService` |
|
||
| R2 | 每个 Module 通过 `xxx.module.ts` 的 `exports: [XxxService]` 暴露能力;禁止 export Repository/Prisma 裸访问 |
|
||
| R3 | 改 `schema.prisma` 中某表 → 必须对应模块 OWNER Review |
|
||
| R4 | 新增/变更 API → 同步更新 `doc/API列表-杜康好客.md` + `shared-types` |
|
||
| R5 | 跨模块写操作走 **Service 调用** 或 **Domain Event + BullMQ**;禁止分布式「各写各的」 |
|
||
| R6 | 微信支付/退款/配送回调 **仅** `callbacks/` 入口,内部转调 `TradeService` 等 |
|
||
| R7 | 集成测试必须覆盖横切链路:购酒→发券→核销→门店打款(CI 门禁) |
|
||
| R8 | 前端 App **禁止** import `server/` 代码;只通过 HTTP + `shared-types` |
|
||
|
||
### 2.4.5 全栈闭环定义
|
||
|
||
「独立闭环」指 **在模块依赖规则内** 端到端交付,而非单独部署:
|
||
|
||
| 开发者 | 闭环范围(示例) |
|
||
|--------|------------------|
|
||
| A | C端下单支付 → 发券 → 权益页(trade + benefit + mini-user) |
|
||
| B | 合伙人录店 → 总部审核 → C端可见(store + mini-partner + 配合 C 审核 API) |
|
||
| D | C端出码 → 门店扫码核销 → 短信通知(redeem + h5-shop + notify 调用) |
|
||
| C | 总部退款/结算/报表(trade 回调 + settlement + ops + mini-hq) |
|
||
|
||
---
|
||
|
||
## 2.5 模块依赖:允许 / 禁止
|
||
|
||
### 2.5.1 分层与允许依赖(模块图)
|
||
|
||
**规则**:只能 **向下** 或 **同层通过 exported Service** 依赖;箭头表示「允许 import / inject」。
|
||
|
||
```mermaid
|
||
flowchart TB
|
||
subgraph L6 [L6 接入与编排]
|
||
CB[callbacks 回调入口]
|
||
JB[jobs 定时与队列]
|
||
OP[ops 运营报表]
|
||
end
|
||
|
||
subgraph L5 [L5 结算域]
|
||
ST[settlement 结算]
|
||
end
|
||
|
||
subgraph L4 [L4 核销域]
|
||
RD[redeem 核销]
|
||
end
|
||
|
||
subgraph L3 [L3 交易域]
|
||
TR[trade 订单支付]
|
||
BF[benefit 好客权益]
|
||
end
|
||
|
||
subgraph L2 [L2 主数据]
|
||
CT[catalog 开城商品]
|
||
SO[store 门店]
|
||
end
|
||
|
||
subgraph L1 [L1 基础域]
|
||
IM[iam 身份]
|
||
AN[analytics 埋点]
|
||
NT[notify 通知]
|
||
end
|
||
|
||
subgraph L0 [L0 基础设施]
|
||
CM[common 公共]
|
||
PR[(prisma)]
|
||
PK[packages/domain]
|
||
end
|
||
|
||
CB --> TR
|
||
CB --> ST
|
||
JB --> ST
|
||
JB --> TR
|
||
|
||
OP --> TR
|
||
OP --> ST
|
||
OP --> SO
|
||
OP --> AN
|
||
|
||
ST --> TR
|
||
ST --> RD
|
||
ST --> SO
|
||
ST --> CT
|
||
|
||
RD --> BF
|
||
RD --> SO
|
||
RD --> ST
|
||
RD --> IM
|
||
RD --> NT
|
||
|
||
TR --> BF
|
||
TR --> CT
|
||
TR --> IM
|
||
TR --> SO
|
||
TR --> NT
|
||
|
||
BF --> IM
|
||
|
||
SO --> CT
|
||
SO --> IM
|
||
|
||
CT --> IM
|
||
|
||
AN --> IM
|
||
|
||
IM --> CM
|
||
TR --> CM
|
||
BF --> CM
|
||
RD --> CM
|
||
ST --> CM
|
||
SO --> CM
|
||
CT --> CM
|
||
OP --> CM
|
||
AN --> CM
|
||
NT --> CM
|
||
CB --> CM
|
||
JB --> CM
|
||
|
||
TR -.-> PK
|
||
BF -.-> PK
|
||
RD -.-> PK
|
||
ST -.-> PK
|
||
```
|
||
|
||
**图例**
|
||
|
||
- 实线箭头:允许 **NestJS Module imports + Service 注入**
|
||
- 虚线:允许引用 `packages/domain` **纯函数**(无 DB/Redis)
|
||
|
||
### 2.5.2 允许依赖矩阵(✅ = 可调 Service)
|
||
|
||
| 调用方 ↓ / 被调方 → | iam | catalog | store | trade | benefit | redeem | settlement | notify | analytics | domain |
|
||
|---------------------|:---:|:-------:|:-----:|:-----:|:-------:|:------:|:----------:|:------:|:---------:|:------:|
|
||
| **catalog** | ✅ | — | | | | | | | | ✅ |
|
||
| **store** | ✅ | ✅ | — | | | | | | | ✅ |
|
||
| **trade** | ✅ | ✅ | ✅ | — | ✅ | | | ✅ | | ✅ |
|
||
| **benefit** | ✅ | | | — | — | | | | | ✅ |
|
||
| **redeem** | ✅ | | ✅ | | ✅ | — | ✅ | ✅ | | ✅ |
|
||
| **settlement** | ✅ | ✅ | ✅ | ✅ | | ✅ | — | ✅ | | ✅ |
|
||
| **ops** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | ✅ | |
|
||
| **callbacks** | | | | ✅ | ✅ | | ✅ | | | |
|
||
| **jobs** | | | | ✅ | | | ✅ | ✅ | | |
|
||
| **analytics** | ✅ | | | | | | | | — | |
|
||
|
||
### 2.5.3 禁止依赖(❌ 违反即 PR 拒绝)
|
||
|
||
| # | 禁止项 | 原因 | 正确做法 |
|
||
|---|--------|------|----------|
|
||
| F1 | `redeem` → 直接 `prisma.order.update` | 订单归 trade | 调 `TradeService` |
|
||
| F2 | `store` → `trade` / `benefit` | 门店域不处理交易 | 由 redeem/trade 回调 |
|
||
| F3 | `benefit` → `trade` / `redeem` | 防止循环依赖 | trade 调 `BenefitService.grant(dto)`,benefit 不反向查 trade |
|
||
| F4 | `trade` → `redeem` | 交易不感知核销细节 | 仅通过 benefit 关联 |
|
||
| F5 | `benefit` → `redeem` | 权益不依赖核销 | redeem 调 benefit 扣券 |
|
||
| F6 | `catalog` → `trade` / `settlement` | 主数据不依赖业务 | 反向调用 |
|
||
| F7 | 任意 Module → 另一 Module 的 `*.controller.ts` | Controller 不可跨模块引 | 只 inject Service |
|
||
| F8 | 任意 Module → 另一 Module 未 export 的 Provider | 破坏封装 | 在 `module.ts` 显式 exports |
|
||
| F9 | `apps/*` → `server/*` 源码 import | 前后端物理隔离 | HTTP + shared-types |
|
||
| F10 | 多个 Module 各自注册 `/callbacks/wechat/pay` | 重复回调 | 仅 `callbacks` 模块 |
|
||
| F11 | 复制粘贴起购/核销/权益规则到 Controller | 规则漂移 | 用 `packages/domain` |
|
||
|
||
### 2.5.4 跨模块典型调用链(允许)
|
||
|
||
**支付成功发券**
|
||
|
||
```
|
||
callbacks/wechat/pay → TradeService.handlePaySuccess()
|
||
→ BenefitService.grantOnOrderPaid(orderId)
|
||
→ NotifyService(可选)
|
||
```
|
||
|
||
**核销确认**
|
||
|
||
```
|
||
ShopRedeemController → RedeemService.confirm()
|
||
→ BenefitService.deduct(couponId)
|
||
→ SettlementService.createStorePayout(redeemRecordId)
|
||
→ NotifyService.sendSms(storeOwner)
|
||
```
|
||
|
||
**退款**
|
||
|
||
```
|
||
AdminRefundController → TradeService.createRefund()
|
||
→ BenefitService.voidUnused(orderId)
|
||
→ WechatPayService.refund()
|
||
```
|
||
|
||
### 2.5.5 Module 文件约定
|
||
|
||
每个模块目录结构统一,便于 CODEOWNERS:
|
||
|
||
```
|
||
modules/trade/
|
||
├── trade.module.ts # imports / exports 唯一入口
|
||
├── trade.controller.ts # 仅本域路由
|
||
├── trade.service.ts # 业务 + 本域表 Prisma
|
||
├── dto/
|
||
├── events/ # 可选:BullMQ producer
|
||
└── __tests__/
|
||
```
|
||
|
||
`trade.module.ts` 示例:
|
||
|
||
```typescript
|
||
@Module({
|
||
imports: [CatalogModule, BenefitModule, IamModule, NotifyModule],
|
||
controllers: [TradeController, PartnerOrderController, AdminOrderController],
|
||
providers: [TradeService, WechatPayService],
|
||
exports: [TradeService], // 仅导出 Service
|
||
})
|
||
export class TradeModule {}
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 后端模块设计
|
||
|
||
### 3.1 模块职责
|
||
|
||
| 模块 | 职责 | 主要实体 |
|
||
|------|------|----------|
|
||
| **iam** | 四端登录、Token、角色权限、子账号 | User, Account, Role, Session |
|
||
| **catalog** | 商品、开城、推广码、佣金配置 | Product, City, PromoCode, CommissionRule |
|
||
| **trade** | 订单、支付、退款、补发、地址改派 | Order, OrderItem, Payment, Refund, Reshipment |
|
||
| **benefit** | 权益券发放、余额、明细 | BenefitCoupon, BenefitLedger |
|
||
| **store** | 门店 CRUD、审核、营业状态 | Store, StoreAudit, StoreMedia |
|
||
| **redeem** | 核销码生成、门店扫码核销、评价 | RedeemToken, RedeemRecord, StoreRating |
|
||
| **settlement** | 门店 T+1、合伙人 T+30 账单 | StorePayout, PartnerBill, Withdrawal |
|
||
| **ops** | 总部首页统计、预警、报表 | Alert, ReportSnapshot |
|
||
| **notify** | 微信/短信/订阅消息封装 | NotificationLog |
|
||
| **analytics** | 埋点接收、渠道归因 | EventLog, ChannelAttribution |
|
||
|
||
### 3.2 核心领域模型(简化 ER)
|
||
|
||
```mermaid
|
||
erDiagram
|
||
USER ||--o{ ORDER : places
|
||
ORDER ||--|{ ORDER_ITEM : contains
|
||
ORDER ||--o| PAYMENT : has
|
||
ORDER ||--o{ BENEFIT_COUPON : grants
|
||
BENEFIT_COUPON ||--o{ REDEEM_RECORD : redeemed_at
|
||
STORE ||--o{ REDEEM_RECORD : receives
|
||
STORE }o--|| CITY : belongs
|
||
CITY }o--|| PARTNER : managed_by
|
||
ORDER }o--o| PROMO_CODE : attributed
|
||
REDEEM_RECORD ||--o| STORE_PAYOUT : settles
|
||
PARTNER ||--o{ PARTNER_BILL : billed
|
||
```
|
||
|
||
### 3.3 订单状态机(后端枚举)
|
||
|
||
```
|
||
PENDING_PAY 待付款
|
||
PENDING_SHIP 待发货
|
||
SHIPPING 配送中
|
||
PENDING_RECEIVE 待签收
|
||
COMPLETED 已完成
|
||
REFUNDING 退款中
|
||
REFUNDED 已退款
|
||
```
|
||
|
||
补发单:`RESHIPMENT`,关联 `origin_order_id`,金额 0。
|
||
|
||
### 3.4 好客权益规则(实现要点)
|
||
|
||
```typescript
|
||
// 发放金额
|
||
const benefitAmount = product.benefitAmount ?? product.price;
|
||
|
||
// 核销校验
|
||
if (amount <= 0 || amount > coupon.balance || amount > 500) {
|
||
throw new BusinessException('INVALID_REDEEM_AMOUNT');
|
||
}
|
||
```
|
||
|
||
- 核销 Token:Redis `SET redeem:token:{id} JSON EX 300`
|
||
- 核销事务:Prisma `$transaction` 内完成「扣券余额 → 写 redeem_record → 写 store_payout 待打款」
|
||
- 并发:券表 `version` 字段乐观锁,或 `UPDATE ... WHERE balance >= amount`
|
||
|
||
### 3.5 NestJS 模块与依赖
|
||
|
||
> **模块边界与允许/禁止依赖见 §2.5。** 下表为各 Module 技术要点。
|
||
|
||
| NestJS Module | 主要 Providers | 外部依赖 |
|
||
|---------------|----------------|----------|
|
||
| `IamModule` | AuthService, JwtStrategy | Redis(session) |
|
||
| `TradeModule` | OrderService, WechatPayService | BenefitModule, CatalogModule |
|
||
| `RedeemModule` | RedeemService | BenefitModule, SettlementModule, Redis |
|
||
| `SettlementModule` | PayoutService, BillService | BullMQ(T+1 任务) |
|
||
| `NotifyModule` | SmsService, WxSubscribeService | 短信 SDK(被各模块 inject) |
|
||
|
||
**常用 Nest 生态**
|
||
|
||
| 能力 | 包 |
|
||
|------|-----|
|
||
| 配置 | `@nestjs/config` |
|
||
| 校验 | `class-validator` + `class-transformer` |
|
||
| JWT | `@nestjs/jwt` + `@nestjs/passport` |
|
||
| 定时 | `@nestjs/schedule` |
|
||
| 队列 | `@nestjs/bullmq` |
|
||
| 微信支付的 | `wechatpay-node-v3` |
|
||
| API 文档 | `@nestjs/swagger` |
|
||
|
||
### 3.6 鉴权与多租户
|
||
|
||
| 端 | 标识 | 数据隔离 |
|
||
|----|------|----------|
|
||
| C端 | `user_id` | 仅本人订单/权益/地址 |
|
||
| 门店 | `store_id` | 仅本店核销记录 |
|
||
| 合伙人 | `partner_id` + `city_id` | 仅辖城市订单/门店 |
|
||
| 总部 | `admin_role` | 全局;操作审计日志 |
|
||
|
||
**Token**:JWT(access 2h)+ Redis refresh;小程序登录走 `wx.login` → code2session。
|
||
|
||
---
|
||
|
||
## 4. 接口设计规范
|
||
|
||
### 4.1 约定
|
||
|
||
- Base URL:`https://api.example.com/api/v1`
|
||
- 认证:`Authorization: Bearer <token>`
|
||
- 响应:`{ "code": 0, "message": "ok", "data": {} }`
|
||
- 分页:`page`, `pageSize`;列表统一 `{ list, total }`
|
||
- 幂等:支付回调、核销、退款用 **业务幂等键**(`idempotency_key` / 微信 `transaction_id`)
|
||
|
||
### 4.2 核心 API 分组(V1)
|
||
|
||
#### 认证 ` /auth`
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/auth/sms/send` | 发送验证码 |
|
||
| POST | `/auth/login/sms` | 手机号登录 |
|
||
| POST | `/auth/login/wechat` | 微信登录(含 appId 区分端) |
|
||
| POST | `/auth/refresh` | 刷新 Token |
|
||
|
||
#### 商品与开城 ` /catalog`
|
||
|
||
| GET | `/products` | 商品列表(按城市/香型) |
|
||
| GET | `/products/{id}` | 商品详情 |
|
||
| GET | `/cities/current` | 当前开城信息 |
|
||
|
||
#### 交易 ` /trade`
|
||
|
||
| POST | `/orders/preview` | 下单预览(配送方式、起购校验、运费) |
|
||
| POST | `/orders` | 创建订单 |
|
||
| POST | `/orders/{id}/pay` | 发起微信支付 |
|
||
| POST | `/callbacks/wechat/pay` | 支付回调(内部) |
|
||
| GET | `/orders` | 订单列表(tab 参数) |
|
||
| GET | `/orders/{id}` | 订单详情 |
|
||
| PUT | `/orders/{id}/address` | 修改地址(触发拦截工单) |
|
||
| POST | `/orders/{id}/confirm-receive` | 确认收货 |
|
||
|
||
#### 权益与核销 ` /benefit`, `/redeem`
|
||
|
||
| GET | `/benefit/summary` | 权益余额汇总 |
|
||
| GET | `/benefit/coupons` | 券列表 |
|
||
| POST | `/redeem/token` | 生成核销码 |
|
||
| POST | `/redeem/confirm` | 门店确认核销 |
|
||
| POST | `/redeem/rating` | 核销后评价 |
|
||
|
||
#### 门店 ` /stores`
|
||
|
||
| GET | `/stores` | C端门店列表(仅营业中) |
|
||
| GET | `/stores/{id}` | 门店详情 |
|
||
| PUT | `/stores/{id}/status` | 门店切换营业状态(门店端) |
|
||
| POST | `/stores` | 合伙人录入门店 |
|
||
| POST | `/stores/{id}/audit` | 总部审核 |
|
||
|
||
#### 结算 ` /settlement`
|
||
|
||
| GET | `/settlement/store/records` | 门店核销记录 |
|
||
| GET | `/settlement/partner/bills` | 合伙人账单 |
|
||
| POST | `/settlement/partner/bills/{id}/confirm` | 确认账单 |
|
||
|
||
#### 总部运营 ` /admin`
|
||
|
||
| GET | `/admin/dashboard` | 今日概况 |
|
||
| GET | `/admin/alerts` | 待办预警 |
|
||
| POST | `/admin/refunds` | 创建退款工单 |
|
||
| POST | `/admin/reshipments` | 创建补发单 |
|
||
| POST | `/admin/promo-codes` | 创建推广码 |
|
||
|
||
#### 埋点 ` /analytics`
|
||
|
||
| POST | `/analytics/events` | 批量上报(可异步队列) |
|
||
|
||
---
|
||
|
||
## 5. 第三方集成
|
||
|
||
### 5.1 微信支付
|
||
|
||
| 场景 | 接口 | 要点 |
|
||
|------|------|------|
|
||
| 下单支付 | JSAPI 统一下单 | `wechatpay-node-v3`,按 appId 多商户配置 |
|
||
| 支付回调 | notify_url | 验签 → BullMQ 异步入队 → 幂等更新订单 → 发券 |
|
||
| 退款 | 退款 API | RefundService;失败重试队列 |
|
||
|
||
### 5.2 小飞侠(同城配送)
|
||
|
||
- 下单成功后推送配送单
|
||
- 回调状态映射:`OUT_WAREHOUSE → SHIPPING → DELIVERED`
|
||
- 超时未回调 → 总部预警(`admin/alerts`)
|
||
|
||
### 5.3 跨城物流
|
||
|
||
- 总部手动/半自动发货;对接物流查询 API(V1 可人工录入运单号 + 状态手动更新,API 对接并行)
|
||
|
||
### 5.4 短信
|
||
|
||
- 核销成功通知门店老板
|
||
- 账单链接(短链跳转 H5/小程序页)
|
||
|
||
### 5.5 推广码
|
||
|
||
- 小程序码参数:`scene=promo_{code}`
|
||
- 启动时写入 Redis `user:{id}:channel`,下单时落库 `order.channel_source`
|
||
|
||
---
|
||
|
||
---
|
||
|
||
# §五、数据库设计 v3.1
|
||
|
||
## 1. 命名规范
|
||
|
||
| 前缀 | 含义 | 示例 |
|
||
|------|------|------|
|
||
| `user_` | C 端用户域 | `user_order` |
|
||
| `partner_` | 城市合伙人域 | `partner_bill` |
|
||
| `store_` | 门店域 | `store_store` |
|
||
| `hq_` | 总部域 | `hq_account` |
|
||
| `common_` | 跨域公共 | `common_resource`、`common_event` |
|
||
| `log_` | 日志/审计(只追加) | `log_third_party` |
|
||
|
||
---
|
||
|
||
## 2. 公共抽象设计
|
||
|
||
### 2.1 `common_resource`(资源表 · OSS)
|
||
|
||
所有图片、视频、合同文件统一入库,文件实体在**阿里云 OSS**。
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `owner_type` | 归属类型:`PRODUCT` / `STORE` / `PARTNER` / `USER` / `ORDER` / `HQ` |
|
||
| `owner_id` | 归属业务 ID |
|
||
| `biz_type` | 业务用途:`COVER` / `ENV` / `CONTRACT` / `CAROUSEL` / `DETAIL` / `AVATAR` / `QRCODE` / `SIGN_PHOTO` / `VIDEO` |
|
||
| `media_type` | `IMAGE` / `VIDEO` / `FILE` |
|
||
| `oss_bucket` / `oss_key` | OSS 定位 |
|
||
| `url` | 访问 URL(CDN) |
|
||
| `sort_order` | 同 owner 下排序 |
|
||
|
||
**替代关系**
|
||
|
||
| 原表/字段 | v3 做法 |
|
||
|-----------|---------|
|
||
| `store_media` | `owner_type=STORE`, `biz_type=COVER/ENV/CONTRACT` |
|
||
| `partner_contracts.file_url` | `owner_type=PARTNER`, `biz_type=CONTRACT` + `partner` 表存 contract_no |
|
||
| `products.main_image_url` / `carousel_urls` | `owner_type=PRODUCT`, `biz_type=COVER/CAROUSEL` |
|
||
| `stores.cover_url` | `cover_resource_id` → `common_resource.id` |
|
||
| `promo_codes.wx_qrcode_url` | `owner_type=PROMO`, `biz_type=QRCODE` |
|
||
| 用户头像 | `owner_type=USER`, `biz_type=AVATAR` |
|
||
| 签收照片 | `owner_type=ORDER`, `biz_type=SIGN_PHOTO` |
|
||
|
||
### 2.2 `common_event`(统一业务事件表)
|
||
|
||
**定位**:仅记录**有业务语义、需审计/追溯**的后端事件(审核、状态流转、权益变动、总部操作、推广触达统计)。**用户行为埋点**写入 `log_user_analytics`,不写入本表。
|
||
|
||
查询:`ref_type + ref_id + event_type`。
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `event_type` | 事件类型(见 §5.1) |
|
||
| `ref_type` / `ref_id` | 关联业务实体 |
|
||
| `actor_type` / `actor_id` | 操作人(USER/STORE/PARTNER/HQ/SYSTEM) |
|
||
| `status` | 部分事件有状态(如审核 PENDING/APPROVED) |
|
||
| `param1` ~ `param3` | 参数值(状态码、ID、类型等) |
|
||
| `param1_desc` ~ `param3_desc` | 参数含义说明(文档化,便于 UI 展示) |
|
||
| `amount1` / `amount2` | **仅 `BENEFIT_LEDGER` 使用**(变动额、变动后余额);其余类型为 NULL |
|
||
| `remark` | 备注/驳回原因 |
|
||
| `extra_json` | 扩展快照(原 submit_data、操作 detail 等) |
|
||
|
||
### 2.3 `common_ticket`(通用工单表)
|
||
|
||
原 `after_sale_tickets`、部分 `alerts` 等工单类事务统一抽象。
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `ticket_type` | `REFUND` / `RESHIPMENT` / `ALERT` |
|
||
| `ticket_no` | 对外工单号 |
|
||
| `ref_type` / `ref_id` | 关联订单/门店等 |
|
||
| `operator_type` / `operator_id` | 处理人 |
|
||
| `param1` ~ `param3` + desc | 类型相关参数(金额、关联单号等) |
|
||
| `status` | 工单状态 |
|
||
|
||
### 2.4 `log_third_party`(第三方交互记录)
|
||
|
||
原 `payments` 及所有外部调用统一记录。
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `provider` | `WECHAT_PAY` / `WECHAT_REFUND` / `WECHAT_AUTH` / `WECHAT_MAP` / `XFX` / `SMS` / `LOGISTICS` |
|
||
| `scene` | 业务场景:`ORDER_PAY` / `ORDER_REFUND` / `LOGIN` / `DELIVERY_CALLBACK` / `SMS_VERIFY` … |
|
||
| `ref_type` / `ref_id` | 关联订单/用户等 |
|
||
| `request_url` | 请求 URL |
|
||
| `request_body` | 发送参数 JSON |
|
||
| `response_body` | 响应 JSON |
|
||
| `external_no` | 第三方单号(微信 transaction_id 等) |
|
||
| `amount` | 涉及金额 |
|
||
| `status` | `PENDING` / `SUCCESS` / `FAILED` |
|
||
|
||
**订单支付**:不再建 `payments` 表;`user_order` 保留 `pay_status` / `paid_at` / `pay_external_no` 冗余字段,明细查 `log_third_party`。
|
||
|
||
**核销码**:删除 `redeem_tokens` 表,**仅存 Redis**(5 分钟);`user_redeem_record` 不再存 token_id。
|
||
|
||
### 2.5 `log_user_analytics`(用户埋点日志)
|
||
|
||
C 端行为埋点专用表,与 `common_event` 分离(见 §4.1 探讨)。
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `user_id` | 用户 ID;未登录上报可为 NULL |
|
||
| `session_id` | 会话 ID,用于漏斗串联 |
|
||
| `event_name` | 事件名(与 PRD §3.10.2 对齐,见 §4.1) |
|
||
| `ref_type` / `ref_id` | 关联商品/门店/订单等 |
|
||
| `keyword` | 搜索类事件关键词 |
|
||
| `source_type` / `source_ref_id` | 注册类事件来源快照 |
|
||
| `extra_json` | 其余埋点参数 |
|
||
|
||
---
|
||
|
||
## 3. 表清单(28 张)
|
||
|
||
| 前缀 | 表名 | 说明 |
|
||
|------|------|------|
|
||
| common | `common_wx_app_config` | 四端微信配置 |
|
||
| common | `common_resource` | 统一资源(OSS) |
|
||
| common | `common_event` | 统一业务事件(非埋点) |
|
||
| common | `common_ticket` | 通用工单 |
|
||
| common | `common_product_item` | 商品 SKU(含 69 码) |
|
||
| common | `common_store_category` | 门店餐饮分类 |
|
||
| common | `common_city` | 开城 |
|
||
| common | `common_city_commission_rule` | 城市佣金规则 |
|
||
| common | `common_promo_code` | 推广码 |
|
||
| user | `user_user` | C 端用户(含注册来源) |
|
||
| user | `user_address` | 收货地址 |
|
||
| user | `user_city_preference` | 城市偏好 |
|
||
| user | `user_promo_attribution` | 推广首次触达(统计用) |
|
||
| user | `user_order` | 订单(含商品快照冗余,无明细子表) |
|
||
| user | `user_order_delivery` | 配送(含签收照,与订单 1:1) |
|
||
| user | `user_benefit_coupon` | 权益券 |
|
||
| user | `user_redeem_record` | 核销记录 |
|
||
| user | `user_store_rating` | 核销评价 |
|
||
| partner | `partner_partner` | 合伙人主体 |
|
||
| partner | `partner_account` | 合伙人账号 |
|
||
| partner | `partner_bill` | T+30 账单(汇总金额,无 commission 明细表) |
|
||
| store | `store_store` | 门店 |
|
||
| store | `store_account` | 门店登录账号 |
|
||
| store | `store_payout` | 门店 T+1 打款 |
|
||
| hq | `hq_account` | 总部账号 |
|
||
| log | `log_third_party` | 第三方交互日志 |
|
||
| log | `log_user_analytics` | 用户行为埋点日志 |
|
||
|
||
---
|
||
|
||
## 5. 枚举与事件/工单参数映射
|
||
|
||
### 5.1 `common_event.event_type`(写入逻辑)
|
||
|
||
| event_type | 中文 | 原表 | 触发逻辑 | param 约定 | amount |
|
||
|------------|------|------|----------|------------|--------|
|
||
| `STORE_AUDIT` | 门店审核 | store_audits | 门店提交入驻/资料变更;总部审核通过或驳回 | p1=audit_type(NEW/UPDATE), p2=status, p3=reviewer_id;remark=驳回原因;extra=submit_data | — |
|
||
| `ORDER_STATUS` | 订单状态变更 | order_status_logs | 状态机每次 transition(含 SYSTEM/回调) | p1=from_status, p2=to_status, p3=operator 标识 | — |
|
||
| `BENEFIT_LEDGER` | 权益流水 | benefit_ledgers | 发券/核销/退款作废/人工调整,与券余额变更同事务 | p1=ledger_type(GRANT/REDEEM/VOID/ADJUST), p2=coupon_id, p3=ref_id;ref_type=关联类型 | **amount1=变动额, amount2=balance_after** |
|
||
| `HQ_OPERATION` | 总部操作审计 | operation_logs | 总部后台写操作(非查询) | p1=action, p2=ref_type, p3=ref_id;extra=detail | — |
|
||
| `PROMO_TOUCH` | 推广触达 | — | 用户扫码/带参进入(可选,与 scan_count++ 同事务) | p1=promo_code_id, p2=触达类型(SCAN/LINK) | — |
|
||
|
||
### 5.2 `common_ticket.ticket_type`
|
||
|
||
| ticket_type | 中文 | 原场景 | param 约定 |
|
||
|-------------|------|--------|------------|
|
||
| `REFUND` | 退款工单 | 客服发起退款 | p1=refund_amount, p2=wx_refund_id, p3=benefit_adjust |
|
||
| `RESHIPMENT` | 补发工单 | 漏发/错发补发 | p1=origin_order_id, p2=reshipment_order_id |
|
||
| `ALERT` | 运营预警 | 超时未发货等 | p1=alert_type, p2=severity;extra=content |
|
||
|
||
### 5.3 枚举值(含中文释义)
|
||
|
||
#### 订单 `user_order`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `status` | `PENDING_PAY` | 待付款 |
|
||
| | `PENDING_SHIP` | 待发货 |
|
||
| | `OUT_WAREHOUSE` | 已出库 |
|
||
| | `SHIPPING` | 配送中 |
|
||
| | `PENDING_RECEIVE` | 待签收 |
|
||
| | `COMPLETED` | 已完成 |
|
||
| | `CANCELLED` | 已取消 |
|
||
| | `REFUNDING` | 退款中 |
|
||
| | `REFUNDED` | 已退款 |
|
||
| `pay_status` | `UNPAID` | 未支付 |
|
||
| | `PAYING` | 支付中 |
|
||
| | `PAID` | 已支付 |
|
||
| | `REFUNDING` | 退款中 |
|
||
| | `REFUNDED` | 已退款 |
|
||
| `order_type` | `NORMAL` | 普通订单 |
|
||
| | `RESHIPMENT` | 补发订单 |
|
||
| `delivery_type` | `LOCAL` | 同城配送 |
|
||
| | `CROSS_CITY` | 跨城配送 |
|
||
| `freight_pay_type` | `FREE` | 包邮 |
|
||
| | `COD` | 运费到付 |
|
||
|
||
#### 权益 `user_benefit_coupon`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `status` | `ACTIVE` | 可用 |
|
||
| | `USED_UP` | 已用完 |
|
||
| | `VOID` | 已作废 |
|
||
|
||
#### 门店 `store_store`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `status` | `OPEN` | 营业中 |
|
||
| | `PAUSED` | 临时闭店 |
|
||
| | `CLOSED` | 永久关闭 |
|
||
|
||
#### 结算
|
||
|
||
| 表.字段 | 枚举值 | 中文释义 |
|
||
|---------|--------|----------|
|
||
| `store_payout.status` | `PENDING` | 待打款 |
|
||
| | `PAID` | 已打款 |
|
||
| `partner_bill.status` | `DRAFT` | 草稿 |
|
||
| | `PENDING_CONFIRM` | 待合伙人确认 |
|
||
| | `CONFIRMED` | 已确认 |
|
||
| | `PAID` | 已打款 |
|
||
| | `REJECTED` | 已驳回 |
|
||
|
||
#### 用户来源 `user_user.source_type`
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `ORGANIC` | 自然流量(无渠道参数) |
|
||
| `PROMO_CODE` | 推广码/渠道码 |
|
||
| `SHARE_LINK` | 分享链接(好友/群分享带参) |
|
||
| `FRIEND_REFERRAL` | 好友推荐(referrer_user_id) |
|
||
| `OFFLINE_EVENT` | 线下活动 |
|
||
| `OTHER` | 其他 |
|
||
|
||
#### 商品 `common_product_item`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `aroma_type` | `QINGXIANG` | 清香型 |
|
||
| | `JIANGXIANG` | 酱香型 |
|
||
| | `NONGXIANG` | 浓香型 |
|
||
| `status` | `DRAFT` | 草稿 |
|
||
| | `ON_SALE` | 在售 |
|
||
| | `OFF_SALE` | 下架 |
|
||
|
||
#### 开城 `common_city.status`
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `PENDING` | 待开城 |
|
||
| `ACTIVE` | 已开城 |
|
||
| `PAUSED` | 暂停 |
|
||
|
||
#### 资源 `common_resource`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `media_type` | `IMAGE` | 图片 |
|
||
| | `VIDEO` | 视频 |
|
||
| | `FILE` | 文件 |
|
||
| `status` | `ACTIVE` | 有效 |
|
||
| | `DELETED` | 已删除 |
|
||
|
||
#### 账号状态(`store_account` / `partner_account` / `hq_account`)
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `ACTIVE` | 正常 |
|
||
| `DISABLED` | 禁用 |
|
||
|
||
#### 合伙人子账号 `partner_account.staff_role`
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `PARTNER` | 合伙人 |
|
||
| `INTERNAL` | 内部员工 |
|
||
| `PROMOTER` | 推广员 |
|
||
|
||
#### 总部职能 `hq_account.admin_role`
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `SUPER_ADMIN` | 超级管理员 |
|
||
| `OPS` | 运营 |
|
||
| `FINANCE` | 财务 |
|
||
| `CUSTOMER_SERVICE` | 客服 |
|
||
|
||
#### 配送 `user_order_delivery.provider`
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `XFX` | 小飞侠同城 |
|
||
| `LOGISTICS` | 传统物流 |
|
||
| `MANUAL` | 人工配送 |
|
||
|
||
#### 第三方 `log_third_party`
|
||
|
||
| 字段 | 枚举值 | 中文释义 |
|
||
|------|--------|----------|
|
||
| `provider` | `WECHAT_PAY` | 微信支付 |
|
||
| | `WECHAT_REFUND` | 微信退款 |
|
||
| | `WECHAT_AUTH` | 微信授权 |
|
||
| | `WECHAT_MAP` | 微信地图 |
|
||
| | `XFX` | 小飞侠 |
|
||
| | `SMS` | 短信 |
|
||
| | `LOGISTICS` | 物流查询 |
|
||
| `status` | `PENDING` | 处理中 |
|
||
| | `SUCCESS` | 成功 |
|
||
| | `FAILED` | 失败 |
|
||
|
||
#### 权益流水 `BENEFIT_LEDGER` param1(ledger_type)
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `GRANT` | 发放 |
|
||
| `REDEEM` | 核销扣减 |
|
||
| `VOID` | 退款作废 |
|
||
| `ADJUST` | 人工调整 |
|
||
|
||
#### 工单 `common_ticket.status`(通用)
|
||
|
||
| 枚举值 | 中文释义 |
|
||
|--------|----------|
|
||
| `PENDING` | 待处理 |
|
||
| `PROCESSING` | 处理中 |
|
||
| `COMPLETED` | 已完成 |
|
||
| `REJECTED` | 已驳回 |
|
||
| `CANCELLED` | 已取消 |
|
||
|
||
---
|
||
|
||
## 6. ER 图(核心)
|
||
|
||
```mermaid
|
||
erDiagram
|
||
user_user ||--o{ user_address : has
|
||
user_user ||--o| user_city_preference : has
|
||
user_user ||--o{ user_order : places
|
||
user_user ||--o{ user_benefit_coupon : owns
|
||
user_user ||--o{ user_redeem_record : redeems
|
||
user_user ||--o{ log_user_analytics : tracks
|
||
|
||
common_city ||--o{ store_store : contains
|
||
common_city ||--o{ user_order : routes
|
||
partner_partner ||--o{ common_city : manages
|
||
partner_partner ||--o{ store_store : owns
|
||
partner_partner ||--o{ partner_account : has
|
||
partner_partner ||--o{ partner_bill : billed
|
||
|
||
common_product_item ||--o{ user_order : sold_in
|
||
common_promo_code ||--o{ user_order : source
|
||
|
||
user_order ||--o| user_order_delivery : "1:1 delivered"
|
||
user_order ||--o{ user_benefit_coupon : grants
|
||
user_order ||--o{ common_ticket : tickets
|
||
user_order ||--o{ log_third_party : third_party
|
||
|
||
user_benefit_coupon ||--o{ user_redeem_record : redeemed
|
||
store_store ||--o{ user_redeem_record : receives
|
||
store_store ||--|| store_account : login
|
||
store_store ||--o{ store_payout : payout
|
||
|
||
common_resource }o--|| store_store : cover
|
||
common_resource }o--|| common_product_item : images
|
||
common_resource }o--|| user_order : product_image
|
||
common_resource }o--|| user_order_delivery : sign_photo
|
||
|
||
common_event }o--|| user_order : logs
|
||
common_event }o--|| store_store : audits
|
||
common_event }o--|| user_benefit_coupon : ledger
|
||
|
||
common_ticket }o--|| user_order : after_sale
|
||
hq_account ||--o{ common_ticket : handles
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 公共 API(common 模块)
|
||
|
||
> 详见本手册 §六;以下为 v3 新增/调整接口。
|
||
|
||
### 7.1 资源 `common_resource`
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| POST | `/common/resources/upload-token` | * | 获取 OSS 直传凭证 `{ bizType, mediaType, fileName }` |
|
||
| POST | `/common/resources` | * | 上传确认/登记 `{ ownerType, ownerId, bizType, ossKey, url, ... }` |
|
||
| GET | `/common/resources` | * | 列表 `?ownerType=&ownerId=&bizType=` |
|
||
| GET | `/common/resources/:id` | * | 详情 |
|
||
| PUT | `/common/resources/:id` | * | 更新排序/状态 |
|
||
| DELETE | `/common/resources/:id` | * | 删除(OSS 异步删) |
|
||
|
||
### 7.2 事件 `common_event`
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| POST | `/common/events` | Internal/各端 | 写入事件(业务 Service 调用) |
|
||
| GET | `/common/events` | * | 查询 `?refType=&refId=&eventType=&page=` |
|
||
| GET | `/common/events/timeline` | * | 聚合时间线(订单/门店详情页) |
|
||
|
||
### 7.3 工单 `common_ticket`
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| POST | `/common/tickets` | AdminAuth 等 | 创建工单 |
|
||
| GET | `/common/tickets` | * | 列表 `?ticketType=&status=&refType=&refId=` |
|
||
| GET | `/common/tickets/:id` | * | 详情 |
|
||
| PUT | `/common/tickets/:id/status` | * | 更新状态/处理 |
|
||
| PUT | `/common/tickets/:id/assign` | AdminAuth | 指派处理人 |
|
||
|
||
### 7.4 第三方日志 `log_third_party`(只读,内部写入)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| GET | `/common/third-party-logs` | AdminAuth | 查询 `?provider=&scene=&refType=&refId=` |
|
||
| GET | `/common/third-party-logs/:id` | AdminAuth | 详情(对账/排错) |
|
||
|
||
### 7.5 用户埋点 `log_user_analytics`
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| POST | `/log/analytics/batch` | UserAuth 可选 | 客户端批量上报 `{ events: [...] }` |
|
||
| GET | `/admin/analytics/events` | AdminAuth | 总部报表 `?eventName=&userId=&from=&to=` |
|
||
| GET | `/admin/analytics/funnel` | AdminAuth | 漏斗统计(V1 基础) |
|
||
|
||
---
|
||
|
||
## 8. 核心业务链路(v3)
|
||
|
||
### 8.1 购酒 → 发券
|
||
|
||
```
|
||
user_user
|
||
→ user_order(含 product 快照 + 价格冗余)
|
||
→ log_third_party (WECHAT_PAY, scene=ORDER_PAY) → user_order.pay_status=PAID
|
||
→ log_user_analytics (pay_success)
|
||
→ common_event (ORDER_STATUS → PENDING_SHIP)
|
||
→ user_order_delivery(预创建,待发货)
|
||
→ user_benefit_coupon
|
||
→ common_event (BENEFIT_LEDGER, GRANT)
|
||
```
|
||
|
||
### 8.2 核销 → 门店打款
|
||
|
||
```
|
||
Redis redeem:token (5min,无 DB 表)
|
||
→ user_redeem_record
|
||
→ common_event (BENEFIT_LEDGER, REDEEM)
|
||
→ store_payout (T+1)
|
||
→ user_store_rating
|
||
→ log_third_party (SMS, 通知门店)
|
||
```
|
||
|
||
### 8.3 门店入驻
|
||
|
||
```
|
||
partner_partner
|
||
→ store_store + common_resource (COVER/ENV/CONTRACT)
|
||
→ common_event (STORE_AUDIT, PENDING)
|
||
→ hq_account 审核 → common_event (APPROVED)
|
||
→ store_account
|
||
```
|
||
|
||
### 8.4 退款
|
||
|
||
```
|
||
common_ticket (REFUND)
|
||
→ log_third_party (WECHAT_REFUND)
|
||
→ user_benefit_coupon VOID
|
||
→ common_event (BENEFIT_LEDGER, VOID)
|
||
→ common_event (ORDER_STATUS, REFUNDED)
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 可执行 SQL(完整建表脚本)
|
||
|
||
> `mysql -u root -p dukang_haoke < init_v3.sql`
|
||
|
||
```sql
|
||
-- ============================================================
|
||
-- 杜康好客 V3.1 数据库初始化脚本
|
||
-- MySQL 8.0+ utf8mb4_unicode_ci InnoDB
|
||
-- ============================================================
|
||
|
||
SET NAMES utf8mb4;
|
||
SET FOREIGN_KEY_CHECKS = 0;
|
||
|
||
CREATE DATABASE IF NOT EXISTS dukang_haoke
|
||
DEFAULT CHARACTER SET utf8mb4
|
||
DEFAULT COLLATE utf8mb4_unicode_ci;
|
||
|
||
USE dukang_haoke;
|
||
|
||
-- ===================== COMMON =============================
|
||
|
||
DROP TABLE IF EXISTS common_wx_app_config;
|
||
CREATE TABLE common_wx_app_config (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
client_app VARCHAR(32) NOT NULL COMMENT 'USER_MINI|PARTNER_MINI|HQ_MINI|SHOP_H5',
|
||
app_id VARCHAR(64) NOT NULL,
|
||
app_secret VARCHAR(128) NOT NULL,
|
||
mch_id VARCHAR(32) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_wx_app_config_client (client_app)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='四端微信配置';
|
||
|
||
DROP TABLE IF EXISTS common_resource;
|
||
CREATE TABLE common_resource (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
owner_type VARCHAR(32) NOT NULL COMMENT 'PRODUCT|STORE|PARTNER|USER|ORDER|PROMO|HQ',
|
||
owner_id BIGINT UNSIGNED NOT NULL COMMENT '归属业务ID',
|
||
biz_type VARCHAR(32) NOT NULL COMMENT 'COVER|ENV|CONTRACT|CAROUSEL|DETAIL|AVATAR|QRCODE|SIGN_PHOTO|VIDEO',
|
||
media_type VARCHAR(16) NOT NULL DEFAULT 'IMAGE' COMMENT 'IMAGE|VIDEO|FILE',
|
||
oss_bucket VARCHAR(64) NOT NULL COMMENT 'OSS Bucket',
|
||
oss_key VARCHAR(256) NOT NULL COMMENT 'OSS Object Key',
|
||
url VARCHAR(512) NOT NULL COMMENT 'CDN访问URL',
|
||
file_name VARCHAR(128) DEFAULT NULL,
|
||
file_size BIGINT UNSIGNED DEFAULT NULL COMMENT '字节',
|
||
mime_type VARCHAR(64) DEFAULT NULL,
|
||
sort_order INT NOT NULL DEFAULT 0,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE' COMMENT 'ACTIVE|DELETED',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_common_resource_owner (owner_type, owner_id, biz_type),
|
||
KEY idx_common_resource_status (status)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一资源表(OSS)';
|
||
|
||
DROP TABLE IF EXISTS common_event;
|
||
CREATE TABLE common_event (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
event_type VARCHAR(32) NOT NULL COMMENT 'STORE_AUDIT|ORDER_STATUS|BENEFIT_LEDGER|HQ_OPERATION|PROMO_TOUCH',
|
||
ref_type VARCHAR(32) NOT NULL COMMENT 'ORDER|STORE|BENEFIT_COUPON|USER|PRODUCT|...',
|
||
ref_id BIGINT UNSIGNED NOT NULL,
|
||
actor_type VARCHAR(16) DEFAULT NULL COMMENT 'USER|STORE|PARTNER|HQ|SYSTEM',
|
||
actor_id BIGINT UNSIGNED DEFAULT NULL,
|
||
status VARCHAR(32) DEFAULT NULL COMMENT '事件子状态(如审核PENDING/APPROVED)',
|
||
param1 VARCHAR(128) DEFAULT NULL,
|
||
param1_desc VARCHAR(64) DEFAULT NULL,
|
||
param2 VARCHAR(128) DEFAULT NULL,
|
||
param2_desc VARCHAR(64) DEFAULT NULL,
|
||
param3 VARCHAR(128) DEFAULT NULL,
|
||
param3_desc VARCHAR(64) DEFAULT NULL,
|
||
amount1 DECIMAL(10,2) DEFAULT NULL COMMENT '仅BENEFIT_LEDGER:变动额',
|
||
amount2 DECIMAL(10,2) DEFAULT NULL COMMENT '仅BENEFIT_LEDGER:变动后余额',
|
||
remark VARCHAR(512) DEFAULT NULL,
|
||
extra_json JSON DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_common_event_ref (ref_type, ref_id, event_type),
|
||
KEY idx_common_event_type_created (event_type, created_at),
|
||
KEY idx_common_event_actor (actor_type, actor_id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='统一事件表';
|
||
|
||
DROP TABLE IF EXISTS common_ticket;
|
||
CREATE TABLE common_ticket (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
ticket_no VARCHAR(32) NOT NULL,
|
||
ticket_type VARCHAR(32) NOT NULL COMMENT 'REFUND|RESHIPMENT|ALERT',
|
||
status VARCHAR(32) NOT NULL DEFAULT 'PENDING',
|
||
ref_type VARCHAR(32) NOT NULL COMMENT 'ORDER|STORE|PARTNER|...',
|
||
ref_id BIGINT UNSIGNED NOT NULL,
|
||
operator_type VARCHAR(16) DEFAULT NULL COMMENT 'HQ|PARTNER|SYSTEM',
|
||
operator_id BIGINT UNSIGNED DEFAULT NULL,
|
||
param1 VARCHAR(128) DEFAULT NULL,
|
||
param1_desc VARCHAR(64) DEFAULT NULL,
|
||
param2 VARCHAR(128) DEFAULT NULL,
|
||
param2_desc VARCHAR(64) DEFAULT NULL,
|
||
param3 VARCHAR(128) DEFAULT NULL,
|
||
param3_desc VARCHAR(64) DEFAULT NULL,
|
||
remark VARCHAR(512) DEFAULT NULL,
|
||
extra_json JSON DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
completed_at DATETIME(3) DEFAULT NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_ticket_no (ticket_no),
|
||
KEY idx_common_ticket_ref (ref_type, ref_id),
|
||
KEY idx_common_ticket_type_status (ticket_type, status)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='通用工单表';
|
||
|
||
DROP TABLE IF EXISTS common_product_item;
|
||
CREATE TABLE common_product_item (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
sku_code VARCHAR(32) NOT NULL COMMENT 'SKU编码',
|
||
barcode_69 VARCHAR(32) NOT NULL COMMENT '69码(商品条码)',
|
||
name VARCHAR(128) NOT NULL,
|
||
subtitle VARCHAR(256) DEFAULT NULL,
|
||
aroma_type VARCHAR(16) NOT NULL COMMENT 'QINGXIANG|JIANGXIANG|NONGXIANG',
|
||
spec VARCHAR(128) NOT NULL,
|
||
price DECIMAL(10,2) NOT NULL,
|
||
benefit_amount DECIMAL(10,2) DEFAULT NULL COMMENT 'NULL=等同售价',
|
||
status VARCHAR(16) NOT NULL DEFAULT 'DRAFT' COMMENT 'DRAFT|ON_SALE|OFF_SALE',
|
||
sort_order INT NOT NULL DEFAULT 0,
|
||
cover_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '主图 common_resource.id',
|
||
detail_content JSON DEFAULT NULL COMMENT '图文详情(纯文本结构)',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_product_item_sku (sku_code),
|
||
UNIQUE KEY uk_common_product_item_barcode (barcode_69),
|
||
KEY idx_common_product_item_status (status, aroma_type)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='商品SKU';
|
||
|
||
DROP TABLE IF EXISTS common_store_category;
|
||
CREATE TABLE common_store_category (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
code VARCHAR(32) NOT NULL,
|
||
name VARCHAR(64) NOT NULL,
|
||
sort INT NOT NULL DEFAULT 0,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_store_category_code (code)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店餐饮分类';
|
||
|
||
DROP TABLE IF EXISTS common_promo_code;
|
||
CREATE TABLE common_promo_code (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
code VARCHAR(32) NOT NULL,
|
||
name VARCHAR(128) NOT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
||
qrcode_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '小程序码 common_resource.id',
|
||
scan_count INT NOT NULL DEFAULT 0,
|
||
order_count INT NOT NULL DEFAULT 0,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_promo_code_code (code)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推广码';
|
||
|
||
-- ===================== PARTNER(先于 city/store) =============================
|
||
|
||
DROP TABLE IF EXISTS partner_partner;
|
||
CREATE TABLE partner_partner (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
company_name VARCHAR(128) NOT NULL,
|
||
address VARCHAR(256) NOT NULL,
|
||
contact_phone VARCHAR(20) NOT NULL,
|
||
contract_no VARCHAR(64) DEFAULT NULL COMMENT '合同编号',
|
||
contract_signed_at DATETIME(3) DEFAULT NULL,
|
||
contract_expire_at DATETIME(3) DEFAULT NULL,
|
||
bank_account_name VARCHAR(64) DEFAULT NULL,
|
||
bank_account_no VARCHAR(32) DEFAULT NULL,
|
||
bank_branch VARCHAR(128) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_partner_partner_phone (contact_phone)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='城市合伙人主体';
|
||
|
||
DROP TABLE IF EXISTS common_city;
|
||
CREATE TABLE common_city (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
code VARCHAR(16) NOT NULL,
|
||
name VARCHAR(64) NOT NULL,
|
||
province VARCHAR(32) NOT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'PENDING',
|
||
partner_id BIGINT UNSIGNED DEFAULT NULL,
|
||
local_min_qty INT NOT NULL DEFAULT 2,
|
||
cross_min_qty INT NOT NULL DEFAULT 6,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_city_code (code),
|
||
KEY idx_common_city_partner (partner_id),
|
||
CONSTRAINT fk_common_city_partner FOREIGN KEY (partner_id) REFERENCES partner_partner(id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='开城配置';
|
||
|
||
DROP TABLE IF EXISTS common_city_commission_rule;
|
||
CREATE TABLE common_city_commission_rule (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
city_id BIGINT UNSIGNED NOT NULL,
|
||
order_commission_rate DECIMAL(5,4) NOT NULL DEFAULT 0.0000,
|
||
redeem_commission_rate DECIMAL(5,4) NOT NULL DEFAULT 0.0000,
|
||
partner_profit_rate DECIMAL(5,4) NOT NULL DEFAULT 0.3500,
|
||
store_settlement_rate DECIMAL(5,4) NOT NULL DEFAULT 0.6000,
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_common_city_commission_city (city_id),
|
||
CONSTRAINT fk_common_city_commission_city FOREIGN KEY (city_id) REFERENCES common_city(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='城市佣金规则';
|
||
|
||
DROP TABLE IF EXISTS partner_account;
|
||
CREATE TABLE partner_account (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
partner_id BIGINT UNSIGNED NOT NULL,
|
||
phone VARCHAR(20) NOT NULL,
|
||
name VARCHAR(64) NOT NULL,
|
||
wx_open_id VARCHAR(64) DEFAULT NULL,
|
||
wx_union_id VARCHAR(64) DEFAULT NULL,
|
||
is_primary TINYINT NOT NULL DEFAULT 0,
|
||
parent_account_id BIGINT UNSIGNED DEFAULT NULL,
|
||
staff_role VARCHAR(16) DEFAULT NULL COMMENT 'PARTNER|INTERNAL|PROMOTER',
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
||
last_login_at DATETIME(3) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_partner_account_phone (phone),
|
||
KEY idx_partner_account_partner (partner_id),
|
||
CONSTRAINT fk_partner_account_partner FOREIGN KEY (partner_id) REFERENCES partner_partner(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_partner_account_parent FOREIGN KEY (parent_account_id) REFERENCES partner_account(id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合伙人账号';
|
||
|
||
DROP TABLE IF EXISTS partner_bill;
|
||
CREATE TABLE partner_bill (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
bill_no VARCHAR(32) NOT NULL,
|
||
partner_id BIGINT UNSIGNED NOT NULL,
|
||
period_start DATETIME(3) NOT NULL,
|
||
period_end DATETIME(3) NOT NULL,
|
||
order_commission DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '下单佣金汇总',
|
||
redeem_commission DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '核销佣金汇总',
|
||
total_amount DECIMAL(10,2) NOT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'DRAFT',
|
||
confirmed_at DATETIME(3) DEFAULT NULL,
|
||
paid_at DATETIME(3) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_partner_bill_no (bill_no),
|
||
KEY idx_partner_bill_partner_status (partner_id, status),
|
||
CONSTRAINT fk_partner_bill_partner FOREIGN KEY (partner_id) REFERENCES partner_partner(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合伙人T+30账单';
|
||
|
||
-- ===================== HQ =============================
|
||
|
||
DROP TABLE IF EXISTS hq_account;
|
||
CREATE TABLE hq_account (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
phone VARCHAR(20) NOT NULL,
|
||
name VARCHAR(64) NOT NULL,
|
||
admin_role VARCHAR(32) NOT NULL DEFAULT 'OPS',
|
||
wx_open_id VARCHAR(64) DEFAULT NULL,
|
||
wx_union_id VARCHAR(64) DEFAULT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
||
last_login_at DATETIME(3) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_hq_account_phone (phone)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='总部账号';
|
||
|
||
-- ===================== USER =============================
|
||
|
||
DROP TABLE IF EXISTS user_user;
|
||
CREATE TABLE user_user (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_no VARCHAR(20) NOT NULL,
|
||
phone VARCHAR(20) NOT NULL,
|
||
wx_open_id VARCHAR(64) DEFAULT NULL,
|
||
wx_union_id VARCHAR(64) DEFAULT NULL,
|
||
nickname VARCHAR(64) DEFAULT NULL,
|
||
avatar_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '头像 common_resource.id',
|
||
status TINYINT NOT NULL DEFAULT 1,
|
||
source_type VARCHAR(32) NOT NULL DEFAULT 'ORGANIC' COMMENT 'ORGANIC|PROMO_CODE|SHARE_LINK|FRIEND_REFERRAL|OFFLINE_EVENT|OTHER',
|
||
source_ref_id BIGINT UNSIGNED DEFAULT NULL COMMENT 'promo_code_id 或 referrer_user_id',
|
||
source_label VARCHAR(128) DEFAULT NULL COMMENT '渠道名称快照',
|
||
referrer_user_id BIGINT UNSIGNED DEFAULT NULL COMMENT '好友推荐人 user_user.id',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_user_phone (phone),
|
||
UNIQUE KEY uk_user_user_no (user_no),
|
||
KEY idx_user_user_source (source_type, source_ref_id),
|
||
KEY idx_user_user_referrer (referrer_user_id),
|
||
KEY idx_user_user_wx_open (wx_open_id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='C端用户';
|
||
|
||
DROP TABLE IF EXISTS user_address;
|
||
CREATE TABLE user_address (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
receiver_name VARCHAR(32) NOT NULL,
|
||
phone VARCHAR(20) NOT NULL,
|
||
province VARCHAR(32) NOT NULL,
|
||
city VARCHAR(32) NOT NULL,
|
||
district VARCHAR(32) NOT NULL,
|
||
detail VARCHAR(256) NOT NULL,
|
||
latitude DECIMAL(10,7) DEFAULT NULL,
|
||
longitude DECIMAL(10,7) DEFAULT NULL,
|
||
is_default TINYINT NOT NULL DEFAULT 0,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_user_address_user (user_id),
|
||
CONSTRAINT fk_user_address_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户收货地址';
|
||
|
||
DROP TABLE IF EXISTS user_city_preference;
|
||
CREATE TABLE user_city_preference (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
selected_city_code VARCHAR(16) DEFAULT NULL,
|
||
selected_district VARCHAR(32) DEFAULT NULL,
|
||
locate_city_code VARCHAR(16) DEFAULT NULL,
|
||
locate_district VARCHAR(32) DEFAULT NULL,
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_city_preference_user (user_id),
|
||
CONSTRAINT fk_user_city_preference_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户城市偏好';
|
||
|
||
DROP TABLE IF EXISTS user_promo_attribution;
|
||
CREATE TABLE user_promo_attribution (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
promo_code_id BIGINT UNSIGNED NOT NULL,
|
||
channel_name VARCHAR(128) NOT NULL,
|
||
first_touch_at DATETIME(3) NOT NULL,
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_promo_attribution_user (user_id),
|
||
KEY idx_user_promo_attribution_promo (promo_code_id),
|
||
CONSTRAINT fk_user_promo_attribution_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE CASCADE,
|
||
CONSTRAINT fk_user_promo_attribution_promo FOREIGN KEY (promo_code_id) REFERENCES common_promo_code(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='推广首次触达(统计)';
|
||
|
||
-- ===================== STORE =============================
|
||
|
||
DROP TABLE IF EXISTS store_store;
|
||
CREATE TABLE store_store (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
city_id BIGINT UNSIGNED NOT NULL,
|
||
partner_id BIGINT UNSIGNED NOT NULL,
|
||
category_id BIGINT UNSIGNED DEFAULT NULL,
|
||
name VARCHAR(128) NOT NULL,
|
||
phone VARCHAR(20) NOT NULL,
|
||
province VARCHAR(32) NOT NULL,
|
||
city_name VARCHAR(32) NOT NULL COMMENT '市(冗余)',
|
||
district VARCHAR(32) NOT NULL,
|
||
address VARCHAR(256) NOT NULL,
|
||
latitude DECIMAL(10,7) DEFAULT NULL,
|
||
longitude DECIMAL(10,7) DEFAULT NULL,
|
||
intro TEXT DEFAULT NULL,
|
||
cover_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '门头图',
|
||
avg_price DECIMAL(10,2) DEFAULT NULL,
|
||
rating DECIMAL(3,2) DEFAULT NULL,
|
||
tags JSON DEFAULT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'PAUSED',
|
||
open_time VARCHAR(8) DEFAULT NULL,
|
||
close_time VARCHAR(8) DEFAULT NULL,
|
||
bank_account_name VARCHAR(64) DEFAULT NULL,
|
||
bank_account_no VARCHAR(32) DEFAULT NULL,
|
||
bank_branch VARCHAR(128) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_store_store_city_status (city_id, status),
|
||
KEY idx_store_store_partner (partner_id),
|
||
CONSTRAINT fk_store_store_city FOREIGN KEY (city_id) REFERENCES common_city(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_store_store_partner FOREIGN KEY (partner_id) REFERENCES partner_partner(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_store_store_category FOREIGN KEY (category_id) REFERENCES common_store_category(id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='餐饮门店';
|
||
|
||
DROP TABLE IF EXISTS store_account;
|
||
CREATE TABLE store_account (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
store_id BIGINT UNSIGNED NOT NULL,
|
||
phone VARCHAR(20) NOT NULL,
|
||
name VARCHAR(64) NOT NULL,
|
||
wx_open_id VARCHAR(64) DEFAULT NULL,
|
||
wx_union_id VARCHAR(64) DEFAULT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
||
last_login_at DATETIME(3) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_store_account_store (store_id),
|
||
UNIQUE KEY uk_store_account_phone (phone),
|
||
CONSTRAINT fk_store_account_store FOREIGN KEY (store_id) REFERENCES store_store(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店H5账号';
|
||
|
||
-- ===================== USER ORDER =============================
|
||
|
||
DROP TABLE IF EXISTS user_order_item;
|
||
DROP TABLE IF EXISTS user_order_delivery;
|
||
DROP TABLE IF EXISTS user_order;
|
||
CREATE TABLE user_order (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
order_no VARCHAR(32) NOT NULL,
|
||
order_type VARCHAR(16) NOT NULL DEFAULT 'NORMAL' COMMENT 'NORMAL|RESHIPMENT',
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
city_id BIGINT UNSIGNED NOT NULL,
|
||
status VARCHAR(32) NOT NULL DEFAULT 'PENDING_PAY',
|
||
pay_status VARCHAR(16) NOT NULL DEFAULT 'UNPAID' COMMENT 'UNPAID|PAYING|PAID|REFUNDING|REFUNDED',
|
||
delivery_type VARCHAR(16) NOT NULL COMMENT 'LOCAL|CROSS_CITY',
|
||
origin_order_id BIGINT UNSIGNED DEFAULT NULL,
|
||
promo_code_id BIGINT UNSIGNED DEFAULT NULL,
|
||
channel_source VARCHAR(128) DEFAULT NULL,
|
||
product_id BIGINT UNSIGNED NOT NULL COMMENT '商品 common_product_item.id',
|
||
barcode_69 VARCHAR(32) NOT NULL COMMENT '69码快照',
|
||
product_name VARCHAR(128) NOT NULL COMMENT '商品名称快照',
|
||
product_spec VARCHAR(128) NOT NULL COMMENT '规格快照',
|
||
image_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '商品图快照 common_resource.id',
|
||
quantity INT NOT NULL COMMENT '购买数量',
|
||
list_unit_price DECIMAL(10,2) NOT NULL COMMENT '标价单价',
|
||
list_amount DECIMAL(10,2) NOT NULL COMMENT '标价总额',
|
||
discount_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '优惠金额',
|
||
product_amount DECIMAL(10,2) NOT NULL COMMENT '商品应付',
|
||
freight_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '运费',
|
||
freight_pay_type VARCHAR(8) DEFAULT NULL COMMENT 'FREE|COD',
|
||
pay_amount DECIMAL(10,2) NOT NULL COMMENT '实付总额',
|
||
benefit_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '本单发放权益',
|
||
receiver_name VARCHAR(32) NOT NULL,
|
||
receiver_phone VARCHAR(20) NOT NULL,
|
||
receiver_address TEXT NOT NULL,
|
||
receiver_province VARCHAR(32) NOT NULL,
|
||
receiver_city VARCHAR(32) NOT NULL,
|
||
receiver_district VARCHAR(32) NOT NULL,
|
||
pay_external_no VARCHAR(64) DEFAULT NULL COMMENT '微信交易号(冗余)',
|
||
paid_at DATETIME(3) DEFAULT NULL COMMENT '支付时间',
|
||
shipped_at DATETIME(3) DEFAULT NULL COMMENT '发货时间(冗余=user_order_delivery.shipping_at)',
|
||
completed_at DATETIME(3) DEFAULT NULL COMMENT '完成时间',
|
||
cancelled_at DATETIME(3) DEFAULT NULL COMMENT '取消时间',
|
||
pay_expire_at DATETIME(3) DEFAULT NULL COMMENT '待付款过期时间',
|
||
remark VARCHAR(512) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_order_no (order_no),
|
||
KEY idx_user_order_user_status (user_id, status),
|
||
KEY idx_user_order_city_created (city_id, created_at),
|
||
KEY idx_user_order_product (product_id),
|
||
KEY idx_user_order_barcode (barcode_69),
|
||
KEY idx_user_order_pay_external (pay_external_no),
|
||
CONSTRAINT fk_user_order_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_user_order_city FOREIGN KEY (city_id) REFERENCES common_city(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_user_order_origin FOREIGN KEY (origin_order_id) REFERENCES user_order(id) ON DELETE SET NULL,
|
||
CONSTRAINT fk_user_order_promo FOREIGN KEY (promo_code_id) REFERENCES common_promo_code(id) ON DELETE SET NULL,
|
||
CONSTRAINT fk_user_order_product FOREIGN KEY (product_id) REFERENCES common_product_item(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单(含商品快照,V1单SKU)';
|
||
|
||
DROP TABLE IF EXISTS user_order_delivery;
|
||
CREATE TABLE user_order_delivery (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
order_id BIGINT UNSIGNED NOT NULL,
|
||
provider VARCHAR(16) NOT NULL COMMENT 'XFX|LOGISTICS|MANUAL',
|
||
provider_order_no VARCHAR(64) DEFAULT NULL,
|
||
tracking_no VARCHAR(64) DEFAULT NULL,
|
||
out_warehouse_at DATETIME(3) DEFAULT NULL,
|
||
shipping_at DATETIME(3) DEFAULT NULL,
|
||
delivered_at DATETIME(3) DEFAULT NULL,
|
||
sign_photo_resource_id BIGINT UNSIGNED DEFAULT NULL COMMENT '签收照片 common_resource.id',
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_order_delivery_order (order_id),
|
||
CONSTRAINT fk_user_order_delivery_order FOREIGN KEY (order_id) REFERENCES user_order(id) ON DELETE CASCADE
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单配送(与user_order 1:1)';
|
||
|
||
-- ===================== BENEFIT & REDEEM =============================
|
||
|
||
DROP TABLE IF EXISTS user_benefit_coupon;
|
||
CREATE TABLE user_benefit_coupon (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
coupon_no VARCHAR(32) NOT NULL,
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
order_id BIGINT UNSIGNED NOT NULL,
|
||
total_amount DECIMAL(10,2) NOT NULL,
|
||
used_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||
balance DECIMAL(10,2) NOT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
||
source_product VARCHAR(128) NOT NULL,
|
||
version INT NOT NULL DEFAULT 0 COMMENT '乐观锁',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_benefit_coupon_no (coupon_no),
|
||
KEY idx_user_benefit_coupon_user (user_id, status),
|
||
CONSTRAINT fk_user_benefit_coupon_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_user_benefit_coupon_order FOREIGN KEY (order_id) REFERENCES user_order(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='好客权益券';
|
||
|
||
DROP TABLE IF EXISTS user_redeem_record;
|
||
CREATE TABLE user_redeem_record (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
redeem_no VARCHAR(32) NOT NULL,
|
||
user_id BIGINT UNSIGNED NOT NULL,
|
||
coupon_id BIGINT UNSIGNED NOT NULL,
|
||
store_id BIGINT UNSIGNED NOT NULL,
|
||
amount DECIMAL(10,2) NOT NULL,
|
||
settle_amount DECIMAL(10,2) NOT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_redeem_record_no (redeem_no),
|
||
KEY idx_user_redeem_record_store (store_id, created_at),
|
||
CONSTRAINT fk_user_redeem_record_user FOREIGN KEY (user_id) REFERENCES user_user(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_user_redeem_record_coupon FOREIGN KEY (coupon_id) REFERENCES user_benefit_coupon(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_user_redeem_record_store FOREIGN KEY (store_id) REFERENCES store_store(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='核销记录';
|
||
|
||
DROP TABLE IF EXISTS user_store_rating;
|
||
CREATE TABLE user_store_rating (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
redeem_record_id BIGINT UNSIGNED NOT NULL,
|
||
store_id BIGINT UNSIGNED NOT NULL,
|
||
service_score TINYINT NOT NULL,
|
||
env_score TINYINT NOT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_user_store_rating_redeem (redeem_record_id),
|
||
CONSTRAINT fk_user_store_rating_redeem FOREIGN KEY (redeem_record_id) REFERENCES user_redeem_record(id) ON DELETE CASCADE,
|
||
CONSTRAINT fk_user_store_rating_store FOREIGN KEY (store_id) REFERENCES store_store(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='核销评价';
|
||
|
||
DROP TABLE IF EXISTS store_payout;
|
||
CREATE TABLE store_payout (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
redeem_record_id BIGINT UNSIGNED NOT NULL,
|
||
store_id BIGINT UNSIGNED NOT NULL,
|
||
redeem_amount DECIMAL(10,2) NOT NULL,
|
||
payout_amount DECIMAL(10,2) NOT NULL,
|
||
settlement_rate DECIMAL(5,4) NOT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'PENDING',
|
||
expected_pay_at DATETIME(3) NOT NULL,
|
||
paid_at DATETIME(3) DEFAULT NULL,
|
||
batch_no VARCHAR(32) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
UNIQUE KEY uk_store_payout_redeem (redeem_record_id),
|
||
KEY idx_store_payout_store_status (store_id, status),
|
||
CONSTRAINT fk_store_payout_redeem FOREIGN KEY (redeem_record_id) REFERENCES user_redeem_record(id) ON DELETE RESTRICT,
|
||
CONSTRAINT fk_store_payout_store FOREIGN KEY (store_id) REFERENCES store_store(id) ON DELETE RESTRICT
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='门店T+1打款';
|
||
|
||
-- ===================== LOG =============================
|
||
|
||
DROP TABLE IF EXISTS log_third_party;
|
||
CREATE TABLE log_third_party (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
provider VARCHAR(32) NOT NULL COMMENT 'WECHAT_PAY|WECHAT_REFUND|WECHAT_AUTH|WECHAT_MAP|XFX|SMS|LOGISTICS',
|
||
scene VARCHAR(64) NOT NULL COMMENT '业务场景',
|
||
ref_type VARCHAR(32) DEFAULT NULL COMMENT 'ORDER|USER|STORE|...',
|
||
ref_id BIGINT UNSIGNED DEFAULT NULL,
|
||
request_url VARCHAR(512) DEFAULT NULL,
|
||
request_body JSON DEFAULT NULL COMMENT '发送参数',
|
||
response_body JSON DEFAULT NULL COMMENT '响应数据',
|
||
external_no VARCHAR(128) DEFAULT NULL COMMENT '第三方单号',
|
||
amount DECIMAL(10,2) DEFAULT NULL,
|
||
status VARCHAR(16) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING|SUCCESS|FAILED',
|
||
error_message VARCHAR(512) DEFAULT NULL,
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_log_third_party_ref (ref_type, ref_id),
|
||
KEY idx_log_third_party_provider_scene (provider, scene, created_at),
|
||
KEY idx_log_third_party_external (external_no)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='第三方交互记录';
|
||
|
||
DROP TABLE IF EXISTS log_user_analytics;
|
||
CREATE TABLE log_user_analytics (
|
||
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||
user_id BIGINT UNSIGNED DEFAULT NULL COMMENT '未登录可为NULL',
|
||
session_id VARCHAR(64) DEFAULT NULL COMMENT '会话ID',
|
||
event_name VARCHAR(64) NOT NULL COMMENT '见§4.1 event_name 清单',
|
||
client_app VARCHAR(32) DEFAULT NULL COMMENT 'USER_MINI|PARTNER_MINI|HQ_MINI|SHOP_H5',
|
||
page_path VARCHAR(128) DEFAULT NULL COMMENT '页面路径',
|
||
ref_type VARCHAR(32) DEFAULT NULL COMMENT 'PRODUCT|STORE|ORDER|TAB|ADDRESS|PROMO|...',
|
||
ref_id BIGINT UNSIGNED DEFAULT NULL,
|
||
keyword VARCHAR(128) DEFAULT NULL COMMENT '搜索关键词',
|
||
source_type VARCHAR(32) DEFAULT NULL COMMENT 'register事件:来源类型快照',
|
||
source_ref_id BIGINT UNSIGNED DEFAULT NULL COMMENT 'register事件:来源ID',
|
||
extra_json JSON DEFAULT NULL COMMENT 'PRD埋点参数',
|
||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||
PRIMARY KEY (id),
|
||
KEY idx_log_user_analytics_user_created (user_id, created_at),
|
||
KEY idx_log_user_analytics_event_created (event_name, created_at),
|
||
KEY idx_log_user_analytics_session (session_id),
|
||
KEY idx_log_user_analytics_ref (ref_type, ref_id)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户行为埋点日志';
|
||
|
||
SET FOREIGN_KEY_CHECKS = 1;
|
||
```
|
||
|
||
---
|
||
|
||
# §六、API 列表 v3.1
|
||
|
||
## 1. 通用约定
|
||
|
||
### 1.1 请求头
|
||
|
||
| Header | 说明 |
|
||
|--------|------|
|
||
| `Authorization` | `Bearer <access_token>`(除公开接口与回调) |
|
||
| `X-Client-App` | `USER_MINI` / `PARTNER_MINI` / `HQ_MINI` / `SHOP_H5` |
|
||
| `X-Request-Id` | 可选,链路追踪 |
|
||
|
||
### 1.2 响应格式
|
||
|
||
```json
|
||
{
|
||
"code": 0,
|
||
"message": "ok",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
### 1.3 分页参数
|
||
|
||
`page`(从 1)、`pageSize`(默认 20,最大 100)→ `data: { list, total, page, pageSize }`
|
||
|
||
### 1.4 鉴权角色
|
||
|
||
| Guard | 适用端 | 数据表 |
|
||
|-------|--------|--------|
|
||
| `UserAuth` | C端 | `user_user` |
|
||
| `StoreAuth` | 门店 H5 | `store_account` |
|
||
| `PartnerAuth` | 合伙人(含子账号) | `partner_account` |
|
||
| `PartnerPrimaryAuth` | 仅主账号(账单确认、提现) | `partner_account`(`is_primary=1`) |
|
||
| `AdminAuth` | 总部 | `hq_account` |
|
||
| `Public` | 无需登录 | — |
|
||
| `WxCallback` | 微信/配送回调验签 | — |
|
||
|
||
### 1.5 JWT Payload(四端统一)
|
||
|
||
```json
|
||
{
|
||
"sub": "12345",
|
||
"actorType": "USER",
|
||
"actorId": "12345",
|
||
"clientApp": "USER_MINI"
|
||
}
|
||
```
|
||
|
||
| `actorType` | 含义 | `actorId` 指向 |
|
||
|-------------|------|----------------|
|
||
| `USER` | C端消费者 | `user_user.id` |
|
||
| `STORE` | 门店登录账号 | `store_account.id` |
|
||
| `PARTNER` | 合伙人/子账号 | `partner_account.id` |
|
||
| `HQ` | 总部管理员 | `hq_account.id` |
|
||
|
||
> 鉴权时须同时校验 `clientApp` 与 `actorType` 一致,禁止仅用数字 ID 跨表匹配。
|
||
|
||
---
|
||
|
||
## 2. 认证 Auth
|
||
|
||
### 2.1 通用接口
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/auth/sms/send` | Public | 发送短信验证码 `{ phone, scene }` | §3.1 |
|
||
| POST | `/auth/refresh` | Public | 刷新 Token | — |
|
||
| POST | `/auth/logout` | * | 退出,失效 refresh | §3.9 |
|
||
| GET | `/auth/me` | * | 当前登录身份摘要(按 `actorType` 返回不同结构) | — |
|
||
|
||
**`scene` 枚举**:`USER_LOGIN` / `STORE_LOGIN` / `PARTNER_LOGIN` / `HQ_LOGIN` / `BIND_PHONE` / `PARTNER_STAFF_ADD`
|
||
|
||
### 2.2 C端(`clientApp: USER_MINI` → `user_user`)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/auth/login/sms` | Public | 手机号登录 `{ phone, code }` → 查/建 `user_user` | §3.1 |
|
||
| POST | `/auth/login/wechat` | Public | 微信登录 `{ code }` → 换 openId;**已绑定 phone 则直接登录,否则返回 `needBindPhone: true`** | §3.1 |
|
||
| POST | `/auth/wechat/bind-phone` | Public | 微信首登补绑手机 `{ wxSessionKey, phone, code }` → 写 `user_user.phone` + `wx_open_id` | U4 |
|
||
|
||
**`POST /auth/login/sms` 响应要点**
|
||
|
||
```json
|
||
{
|
||
"accessToken": "",
|
||
"refreshToken": "",
|
||
"actorType": "USER",
|
||
"actorId": "10001",
|
||
"user": {
|
||
"id": "10001",
|
||
"userNo": "DK88293401",
|
||
"phone": "138****8888",
|
||
"nickname": "",
|
||
"hasWechat": true
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.3 门店端(`clientApp: SHOP_H5` → `store_account`)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/shop/auth/login/sms` | Public | `{ phone, code }` → 查 `store_account` | §4.1 |
|
||
| POST | `/shop/auth/login/wechat` | Public | `{ code }` → 写辅助 openId 后仍须匹配 `store_accounts.phone` | §4.1 |
|
||
|
||
**响应 `actorType`**:`STORE`;附带 `storeId`、`storeName`。
|
||
|
||
### 2.4 合伙人端(`clientApp: PARTNER_MINI` → `partner_account`)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/partner/auth/login/sms` | Public | `{ phone, code }` → 查 `partner_account` | §5.1 |
|
||
| POST | `/partner/auth/login/wechat` | Public | 微信登录(30 天免登) | §5.1 |
|
||
|
||
**响应 `actorType`**:`PARTNER`;附带 `partnerId`、`isPrimary`、`staffRole`。
|
||
|
||
### 2.5 总部端(`clientApp: HQ_MINI` → `hq_account`)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/admin/auth/login/sms` | Public | `{ phone, code }` → 查 `hq_account` | §6 |
|
||
| POST | `/admin/auth/login/wechat` | Public | 微信登录 | §6 |
|
||
|
||
**响应 `actorType`**:`HQ`;附带 `adminRole`(`SUPER_ADMIN` / `OPS` / `FINANCE` / `CUSTOMER_SERVICE`)。
|
||
|
||
### 2.6 身份校验错误码
|
||
|
||
| code | 说明 |
|
||
|------|------|
|
||
| `PHONE_REQUIRED` | C 端微信首登未绑定手机 |
|
||
| `PHONE_ALREADY_USED` | 手机号已被同端其他账号占用 |
|
||
| `ACCOUNT_DISABLED` | B 端账号 `status=DISABLED` |
|
||
| `ACTOR_TYPE_MISMATCH` | Token `actorType` 与接口 Guard 不匹配 |
|
||
| `NOT_PRIMARY_ACCOUNT` | 非合伙人主账号调用 `PartnerPrimaryAuth` 接口 |
|
||
|
||
---
|
||
|
||
## 3. C端用户 API(UserAuth)
|
||
|
||
### 3.1 用户与城市
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/user/profile` | 个人中心信息 | §3.9 |
|
||
| PUT | `/user/profile` | 更新昵称/头像 | §3.9 |
|
||
| GET | `/user/city` | 获取选城/定位偏好 | §3.1 |
|
||
| PUT | `/user/city` | 更新选城 `{ cityCode, district }` | §3.1 |
|
||
| POST | `/user/location` | 上报定位 `{ lat, lng, city, district }` | §3.1 |
|
||
|
||
### 3.2 地址
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/user/addresses` | 地址列表 | §3.4 |
|
||
| POST | `/user/addresses` | 新增地址 | §3.4 |
|
||
| PUT | `/user/addresses/:id` | 编辑地址 | §3.4 |
|
||
| DELETE | `/user/addresses/:id` | 删除地址 | §3.4 |
|
||
| PUT | `/user/addresses/:id/default` | 设为默认 | §3.4 |
|
||
|
||
### 3.3 商品与开城(Public / 部分需登录)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| GET | `/catalog/cities/open` | Public | 已开城列表(V1 郑州) | §1.4 |
|
||
| GET | `/catalog/products` | Public | 商品列表 `?aromaType=&cityCode=` | §3.2 |
|
||
| GET | `/catalog/products/:id` | Public | 商品详情(含 benefitAmount) | §3.2 |
|
||
|
||
### 3.4 订单交易
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| POST | `/trade/orders/preview` | 下单预览:配送方式、起购、运费、权益 | §3.3 |
|
||
| POST | `/trade/orders` | 创建订单(锁单) | §3.3 |
|
||
| POST | `/trade/orders/:id/pay` | 发起微信支付,返回 prepay 参数 | §3.3.4 |
|
||
| GET | `/trade/orders` | 订单列表 `?tab=all\|pending_pay\|pending_ship\|pending_receive\|completed` | §3.5.1 |
|
||
| GET | `/trade/orders/:id` | 订单详情(进度、权益入口) | §3.5.3 |
|
||
| PUT | `/trade/orders/:id/address` | 修改收货地址(触发拦截) | §3.5.4 |
|
||
| POST | `/trade/orders/:id/cancel` | 取消待付款订单 | §3.5 |
|
||
| POST | `/trade/orders/:id/confirm-receive` | 确认收货 | §3.5.3 |
|
||
| GET | `/trade/orders/counts` | 各 Tab 数量(个人中心角标) | §3.9 |
|
||
|
||
**`POST /trade/orders/preview` 请求**
|
||
|
||
```json
|
||
{
|
||
"productId": "",
|
||
"quantity": 2,
|
||
"addressId": ""
|
||
}
|
||
```
|
||
|
||
**响应要点**:`deliveryType`, `freightAmount`, `freightPayType`, `benefitAmount`, `minQty`, `crossCityWarning`
|
||
|
||
### 3.5 好客权益
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/benefit/summary` | 权益余额汇总 | §3.8.1 |
|
||
| GET | `/benefit/coupons` | 券列表 `?status=active\|used` | §3.8.1 |
|
||
| GET | `/benefit/coupons/:id` | 券详情 | §3.8 |
|
||
| GET | `/benefit/ledgers` | 权益明细(获取+消费) | §3.8.2 |
|
||
|
||
### 3.6 核销
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| POST | `/redeem/token` | 生成核销码 `{ couponId, storeId, amount }` | §3.8.3 |
|
||
| POST | `/redeem/token/:token/refresh` | 刷新核销码(作废旧码) | §3.8.3 |
|
||
| GET | `/redeem/token/:token` | 轮询码状态(可选) | §3.8.3 |
|
||
| POST | `/redeem/rating` | 核销评价 `{ redeemRecordId, serviceScore, envScore }` | §3.8.3 |
|
||
|
||
### 3.7 门店(C端浏览)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| GET | `/stores` | Public | 门店列表(**仅 OPEN**)`?cityCode=&category=&keyword=&lat=&lng=` | §3.7 |
|
||
| GET | `/stores/:id` | Public | 门店详情 | §3.7.2 |
|
||
| GET | `/stores/categories` | Public | 分类列表 | §3.7 |
|
||
|
||
### 3.8 推广与埋点
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| POST | `/promo/touch` | UserAuth | 扫码归因 `{ promoCode }`(首次写入) | §3.10.1 |
|
||
| POST | `/log/analytics/batch` | UserAuth / Public | 批量埋点 `{ events:[] }` | §3.10.2 |
|
||
|
||
---
|
||
|
||
## 4. 门店端 API(StoreAuth)
|
||
|
||
> 登录见 §2.3。Token 中 `actorType=STORE`,`actorId` 为 `store_account.id`。
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/shop/dashboard` | 首页:今日笔数/金额、营业状态 | §4.2 |
|
||
| GET | `/shop/store` | 门店信息(只读) | §4.5 |
|
||
| PUT | `/shop/store/status` | 切换营业 `{ status: OPEN\|PAUSED }` | §4.2 |
|
||
| POST | `/shop/redeem/scan` | 扫码解析 `{ token }` → 确认页数据 | §4.3 |
|
||
| POST | `/shop/redeem/confirm` | 确认核销 `{ token }` | §4.3 |
|
||
| GET | `/shop/redeem/records` | 核销记录 `?range=today\|7d\|30d&status=` | §4.4 |
|
||
| GET | `/shop/redeem/records/summary` | 期间汇总(核销额/到账额/60%) | §4.4 |
|
||
| GET | `/shop/redeem/records/:id` | 单笔详情 | §4.4 |
|
||
|
||
**`POST /shop/redeem/scan` 响应(确认页)**
|
||
|
||
```json
|
||
{
|
||
"storeName": "",
|
||
"userPhoneMasked": "138****9021",
|
||
"amount": 100.00,
|
||
"couponNo": "DK202310248892",
|
||
"couponValidity": "永久",
|
||
"tokenExpireAt": ""
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 城市合伙人 API(PartnerAuth)
|
||
|
||
> 登录见 §2.4。Token 中 `actorType=PARTNER`,`actorId` 为 `partner_account.id`。
|
||
|
||
### 5.1 工作台
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/partner/dashboard` | 营业额、利润、门店数、今日订单 | §5.2 |
|
||
| GET | `/partner/dashboard/leaderboard` | 贡献榜 | §5.2, §5.9 |
|
||
| GET | `/partner/reports/weekly` | 经营周报 `?startDate=` | §5.8 |
|
||
|
||
### 5.2 门店管理
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/partner/stores` | 门店列表 `?status=&keyword=` | §5.3 |
|
||
| GET | `/partner/stores/:id` | 门店详情 | §5.3 |
|
||
| POST | `/partner/stores` | 录入门店(步骤1 基本信息) | §5.3.2 |
|
||
| PUT | `/partner/stores/:id/basic` | 更新基本信息 | §5.3 |
|
||
| POST | `/partner/stores/:id/media` | 上传照片/合同(步骤2) | §5.3.2 |
|
||
| PUT | `/partner/stores/:id/settlement` | 结算银行卡(步骤3) | §5.3.2 |
|
||
| POST | `/partner/stores/:id/submit-audit` | 提交审核 | §5.3.2 |
|
||
| PUT | `/partner/stores/:id/status` | 变更状态 `{ status: PAUSED\|CLOSED\|OPEN }` | §5.3 |
|
||
| GET | `/partner/store-audits` | 审核记录 | §5.3.3 |
|
||
|
||
### 5.3 订单
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/partner/orders` | 订单列表 `?range=&status=&keyword=` | §5.4 |
|
||
| GET | `/partner/orders/:id` | 订单详情(佣金、渠道) | §5.4 |
|
||
| GET | `/partner/benefit/overview` | 权益发放/待核销统计 | §5.4 |
|
||
| GET | `/partner/benefit/records` | 已核销权益明细 | §5.4 |
|
||
|
||
### 5.4 补发与拦截
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/partner/after-sales/reshipments` | 补发待处理列表 | §5.5 |
|
||
| POST | `/partner/after-sales/reshipments/:id/confirm-ship` | 开始配送 | §5.5 |
|
||
| POST | `/partner/after-sales/reshipments/:id/confirm-delivered` | 手动确认送达 | §5.5 |
|
||
| GET | `/partner/intercepts` | 拦截列表 | §5.6 |
|
||
| GET | `/partner/intercepts/:id` | 拦截详情 | §5.6 |
|
||
| POST | `/partner/intercepts/:id/start` | 发起拦截 | §5.6 |
|
||
| POST | `/partner/intercepts/:id/confirm-success` | 确认拦截成功 | §5.6 |
|
||
|
||
### 5.5 财务
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 | PRD |
|
||
|------|------|------|------|-----|
|
||
| GET | `/partner/settlement/summary` | 待结算/已结算/本月预估 | §5.7 |
|
||
| GET | `/partner/settlement/bills` | 账单列表 | §5.7 |
|
||
| GET | `/partner/settlement/bills/:id` | 账单详情(拆分佣金) | §5.7 |
|
||
| POST | `/partner/settlement/bills/:id/confirm` | 确认账单 | §5.7 |
|
||
| PartnerPrimary | | | |
|
||
| GET | `/partner/assets` | 资产明细 | §5.10 |
|
||
| POST | `/partner/withdrawals` | 申请提现 | §5.10 |
|
||
| GET | `/partner/contracts` | 合同列表 | §5.10 |
|
||
|
||
### 5.6 子账号(`partner_account` 表)
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/partner/staff` | 员工/子账号列表(`parent_account_id` 指向主账号) | §5.9 |
|
||
| POST | `/partner/staff` | 添加子账号 `{ phone, name, staffRole, code }` | §5.9 |
|
||
| PUT | `/partner/staff/:id` | 编辑/启用/禁用 | §5.9 |
|
||
| DELETE | `/partner/staff/:id` | 删除子账号 | §5.9 |
|
||
|
||
> `:id` 为 `partner_account.id`。主账号 `is_primary=1`,子账号须设 `staffRole`(`PARTNER` / `INTERNAL` / `PROMOTER`)。
|
||
|
||
---
|
||
|
||
## 6. 总部管理 API(AdminAuth)
|
||
|
||
> 登录见 §2.5。Token 中 `actorType=HQ`,`actorId` 为 `hq_account.id`。
|
||
> 门店审核、退款审核、售后工单、操作审计均关联 `hq_account.id`。
|
||
|
||
### 6.0 总部账号(`hq_account` 表,`SUPER_ADMIN` 可管)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
|------|------|------|------|
|
||
| GET | `/admin/hq-accounts` | AdminAuth | 总部账号列表 |
|
||
| POST | `/admin/hq-accounts` | SUPER_ADMIN | 创建账号 `{ phone, name, adminRole }` |
|
||
| PUT | `/admin/hq-accounts/:id` | SUPER_ADMIN | 编辑/启用/禁用 |
|
||
| GET | `/admin/hq-accounts/me` | AdminAuth | 当前总部账号信息 |
|
||
|
||
### 6.1 首页与预警
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/dashboard` | 今日概况 | §6.1 |
|
||
| GET | `/admin/alerts` | 预警列表 | §6.1, §6.10 |
|
||
| GET | `/admin/alerts/:id` | 预警详情 | §6.10 |
|
||
| PUT | `/admin/alerts/:id/resolve` | 标记已处理 | §6.10 |
|
||
|
||
### 6.2 开城
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/cities` | 开城列表 | §6.2 |
|
||
| POST | `/admin/cities` | 新增城市 | §6.2 |
|
||
| GET | `/admin/cities/:id` | 城市详情 | §6.2 |
|
||
| PUT | `/admin/cities/:id` | 编辑城市 | §6.2 |
|
||
| PUT | `/admin/cities/:id/status` | 暂停/恢复 | §6.2 |
|
||
| PUT | `/admin/cities/:id/commission` | 配置佣金比例 | §6.2 |
|
||
| POST | `/admin/partners` | 创建合伙人主体 | §6.2 |
|
||
|
||
### 6.3 商品
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/products` | 商品列表 | §6.3 |
|
||
| POST | `/admin/products` | 新增商品 | §6.3 |
|
||
| GET | `/admin/products/:id` | 商品详情 | §6.3 |
|
||
| PUT | `/admin/products/:id` | 编辑(含 benefitAmount) | §6.3 |
|
||
| PUT | `/admin/products/:id/status` | 上下架 | §6.3 |
|
||
|
||
### 6.4 订单中心
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/orders` | 订单列表/搜索 | §6.4 |
|
||
| GET | `/admin/orders/search-suggest` | 搜索建议 | §6.4 |
|
||
| GET | `/admin/orders/:id` | 订单详情 | §6.4 |
|
||
| PUT | `/admin/orders/:id/status` | 手动改状态(异常处理) | §6.4 |
|
||
| POST | `/admin/orders/:id/ship` | 跨城发货/录入运单 | §6.4 |
|
||
| GET | `/admin/orders/:id/commissions` | 佣金拆分 | §6.4 |
|
||
|
||
### 6.5 门店审核
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/store-audits` | 审核列表 `?status=` | §6.5 |
|
||
| GET | `/admin/store-audits/:id` | 审核详情 | §6.5 |
|
||
| PUT | `/admin/store-audits/:id/approve` | 通过 | §6.5 |
|
||
| PUT | `/admin/store-audits/:id/reject` | 驳回 `{ reason }` | §6.5 |
|
||
| PUT | `/admin/stores/:id` | 总部编辑门店 | §6.5 |
|
||
|
||
### 6.6 推广码
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/promo-codes` | 推广码列表 | §6.6 |
|
||
| POST | `/admin/promo-codes` | 创建(生成小程序码) | §6.6 |
|
||
| PUT | `/admin/promo-codes/:id/status` | 启用/禁用 | §6.6 |
|
||
| GET | `/admin/promo-codes/:id/stats` | 扫码/转化统计 | §6.6 |
|
||
|
||
### 6.7 结算中心
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/settlement/summary` | 待结算总额等 | §6.7 |
|
||
| GET | `/admin/settlement/partner-bills` | 合伙人待处理账单 | §6.7 |
|
||
| POST | `/admin/settlement/partner-bills` | 发起账期账单 | §6.7 |
|
||
| POST | `/admin/settlement/partner-bills/:id/send` | 发送账单通知 | §6.7 |
|
||
| POST | `/admin/settlement/partner-bills/:id/confirm-paid` | 确认打款 | §6.7 |
|
||
| GET | `/admin/settlement/store-payouts` | 门店待打款列表 | §6.7 |
|
||
| POST | `/admin/settlement/store-payouts/batch-pay` | T+1 批量打款 | §6.7 |
|
||
| GET | `/admin/settlement/withdrawals` | 提现审核列表 | §5.10 |
|
||
| PUT | `/admin/settlement/withdrawals/:id/approve` | 提现审核 | §5.10 |
|
||
|
||
### 6.8 客服 · 售后
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/after-sales` | 工单列表 `?type=refund\|reshipment&status=` | §6.8 |
|
||
| GET | `/admin/after-sales/:id` | 工单详情 | §6.8 |
|
||
| POST | `/admin/after-sales/refunds` | 创建退款 `{ orderId, amount, reason }` | §3.6.2 |
|
||
| PUT | `/admin/after-sales/refunds/:id/approve` | 审核通过并发起微信退款 | §3.6.2 |
|
||
| PUT | `/admin/after-sales/refunds/:id/reject` | 驳回 | §3.6.2 |
|
||
| POST | `/admin/after-sales/reshipments` | 创建补发 `{ orderId, reason }` | §3.6 |
|
||
| GET | `/admin/after-sales/reshipments/:id` | 补发详情/进度 | §6.8 |
|
||
|
||
### 6.9 数据报表
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| GET | `/admin/reports/overview` | 报表中心概览 | §6.9 |
|
||
| GET | `/admin/reports/gmv` | GMV 趋势 | §6.9 |
|
||
| GET | `/admin/reports/channels` | 推广渠道转化 | §3.10 |
|
||
| GET | `/admin/reports/events` | 埋点统计 | §3.10.2 |
|
||
|
||
### 6.10 通用
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| POST | `/admin/upload` | 图片/文件上传 OSS |
|
||
| GET | `/admin/operation-logs` | 操作审计(`common_event(HQ_OPERATION)`) |
|
||
|
||
---
|
||
|
||
## 7. 回调接口(验签,无 JWT)
|
||
|
||
| 方法 | 路径 | 说明 | PRD |
|
||
|------|------|------|-----|
|
||
| POST | `/callbacks/wechat/pay` | 支付结果通知 | §3.3.4 |
|
||
| POST | `/callbacks/wechat/refund` | 退款结果通知 | §3.6.2 |
|
||
| POST | `/callbacks/xfx/delivery` | 小飞侠配送状态 | §7.1 |
|
||
| POST | `/callbacks/logistics/tracking` | 跨城物流状态 | §2.3 |
|
||
|
||
---
|
||
|
||
## 8. API 统计
|
||
|
||
| 端 | 接口数(约) |
|
||
|----|-------------|
|
||
| 认证(四端分拆) | 11 |
|
||
| C端 | 28 |
|
||
| 门店 | 8 |
|
||
| 合伙人 | 32 |
|
||
| 总部 | 49 |
|
||
| 回调 | 4 |
|
||
| **合计** | **~132** |
|
||
|
||
---
|
||
|
||
## 9. 业务场景 → API 快速索引
|
||
|
||
| 场景 | 关键 API |
|
||
|------|----------|
|
||
| C端手机登录(phone 唯一) | `POST /auth/login/sms` → `user_user` |
|
||
| C端微信首登绑手机 | `POST /auth/login/wechat` → `POST /auth/wechat/bind-phone` |
|
||
| 门店 H5 登录 | `POST /shop/auth/login/sms` → `store_account` |
|
||
| 合伙人/子账号登录 | `POST /partner/auth/login/sms` → `partner_account` |
|
||
| 总部登录 | `POST /admin/auth/login/sms` → `hq_account` |
|
||
| JWT 四端隔离 | `actorType` + `actorId`,见 §1.5 |
|
||
| 同城2瓶/跨城6瓶 | `POST /trade/orders/preview` |
|
||
| 跨城到付 | preview 返回 `crossCityWarning` + create |
|
||
| 支付发券 | 回调 → 内部服务;`GET /benefit/coupons` |
|
||
| 订单5 Tab | `GET /trade/orders?tab=pending_ship` 等 |
|
||
| 改址拦截 | `PUT /trade/orders/:id/address` → `common_ticket+改址流程` |
|
||
| 核销¥500上限 | `POST /redeem/token` 校验 |
|
||
| 门店隐藏暂停 | `GET /stores` 过滤 |
|
||
| 门店T+1 | `GET /shop/redeem/records` + 总部 batch-pay |
|
||
| 合伙人T+30 | `/partner/settlement/bills/*` |
|
||
| 退款 | `/admin/after-sales/refunds/*` |
|
||
| 补发 | `/admin/after-sales/reshipments` + partner confirm |
|
||
| 推广归因 | `POST /promo/touch` + 下单写 channel |
|
||
| 埋点17事件 | `POST /analytics/events` |
|
||
|
||
---
|
||
|
||
|
||
|
||
---
|
||
|
||
# §七、开发计划与任务卡
|
||
|
||
# 杜康好客 · V1 开发计划(可执行版)
|
||
|
||
> **版本**:v2.0
|
||
> **日期**:2026-06-27
|
||
> **状态**:Agent / 人工编码事实源
|
||
> **目标上线**:郑州开城、4 SKU、四端闭环(日历 10~12 周,按团队调整)
|
||
|
||
---
|
||
|
||
## 0. 文档权威与 Agent 使用说明
|
||
|
||
### 0.1 阅读优先级(冲突时)
|
||
|
||
| 优先级 | 文档 | 用途 |
|
||
|--------|------|------|
|
||
| 1 | `本手册 §二` | **做什么**(业务规则、状态、边界) |
|
||
| 2 | `conventions.md` | **怎么协作**(模块边界、提交、契约) |
|
||
| 3 | `本手册 §四` | **怎么架构**(NestJS 模块、依赖规则) |
|
||
| 4 | `本手册 §五` | **表结构**(Prisma / SQL 事实源 v2.1) |
|
||
| 5 | `本手册 §六` | **接口契约**(v1.1,含四端 JWT) |
|
||
| 6 | `pages/{user,shop,partner,hq}/` | **UI 参照**(字段、布局、跳转) |
|
||
| 7 | `doc/原型说明.md` | 原型与 PRD 差异(如 user/9 待发货 Tab) |
|
||
|
||
### 0.2 Cursor Agent 编码流程
|
||
|
||
1. **绑定 Skill**:实现代码时启用 `.cursor/skills/dukang-coding`(或用户 @dukang-coding)
|
||
2. **领取任务**:从本文 **附录 A** 取任务卡 ID(如 `M2-FE-U-003`),一次只做一个任务卡
|
||
3. **读文档**:按任务卡上的 PRD §、API 路径、DB 表、原型路径逐项对照
|
||
4. **写代码**:遵守 `conventions.md` §2 模块边界;DTO/枚举进 `packages/shared-types`
|
||
5. **自验**:完成任务卡「验收标准」;跨模块改动同步 API 文档
|
||
6. **提交**:Conventional Commits,scope = 端或模块(`feat(trade)`)
|
||
|
||
### 0.3 技术栈(锁定)
|
||
|
||
| 层 | 选型 |
|
||
|----|------|
|
||
| 前端 | Taro 3 + React + TypeScript,Monorepo 四 App |
|
||
| 后端 | Node 20 + NestJS 10 + Prisma 5 + MySQL 8 + Redis 7 + BullMQ |
|
||
| 协作 | **方案三**:一个 `dukang-api`,模块 OWNER,禁止跨模块直写表 |
|
||
|
||
### 0.4 仓库目标结构(M0 必须落地)
|
||
|
||
```
|
||
dukang/
|
||
├── apps/
|
||
│ ├── mini-user/ # C端
|
||
│ ├── mini-partner/ # 合伙人
|
||
│ ├── mini-hq/ # 总部
|
||
│ └── h5-shop/ # 门店 H5
|
||
├── packages/
|
||
│ ├── shared-types/ # DTO、枚举、错误码、JWT Payload
|
||
│ ├── shared-utils/
|
||
│ ├── shared-ui/
|
||
│ └── domain/ # 纯函数:起购、权益额、核销上限
|
||
├── server/
|
||
│ └── dukang-api/
|
||
│ ├── prisma/schema.prisma # 已 v2.1
|
||
│ └── src/
|
||
│ ├── common/
|
||
│ ├── modules/{iam,catalog,trade,benefit,store,redeem,settlement,ops,notify,analytics}
|
||
│ ├── callbacks/
|
||
│ └── jobs/
|
||
├── pages/ # 原型图(只读参照)
|
||
├── doc/
|
||
└── conventions.md
|
||
```
|
||
|
||
---
|
||
|
||
## 1. 团队与 OWNER 分工
|
||
|
||
| OWNER | 前端 App | 后端 Module | 主责里程碑 |
|
||
|-------|----------|-------------|------------|
|
||
| A | `mini-user` | iam, trade, benefit, analytics | M1~M2, M6 |
|
||
| B | `mini-partner` | store | M1, M4 |
|
||
| C | `mini-hq` | catalog, settlement, ops | M1, M4~M6 |
|
||
| D | `h5-shop` | redeem | M3 |
|
||
| Lead | `packages/*` | callbacks, jobs, common | M0, 横切 CI |
|
||
|
||
跨模块 PR:相关双 OWNER Review(技术方案 §2.4.4 R1~R3)。
|
||
|
||
---
|
||
|
||
## 2. 里程碑总览
|
||
|
||
| 里程碑 | 周次 | 核心交付 | 出口标准 |
|
||
|--------|------|----------|----------|
|
||
| **M0** | 第 0~1 周 | Monorepo + 骨架 + 环境 | `pnpm dev` 四端可启,API `/health` 通 |
|
||
| **M1** | 第 1~2 周 | IAM 四端、开城、商品 | 总部配郑州+4 SKU;四端可登录 |
|
||
| **M2** | 第 3~4 周 | C端购酒支付履约 | 同城2瓶/跨城6瓶;支付发券;5 Tab 订单 |
|
||
| **M3** | 第 5~6 周 | 权益+核销+门店 H5 | 端到端核销;门店短信 |
|
||
| **M4** | 第 7~8 周 | 拓店审核、补发退款拦截 | 合伙人录店→总部审→C端可见 |
|
||
| **M5** | 第 9 周 | T+1 门店 / T+30 合伙人 | 结算状态正确 |
|
||
| **M6** | 第 10 周 | 推广码、埋点、报表 | 渠道可归因 |
|
||
| **上线** | 第 11~12 周 | UAT、提审、试运行 | 郑州试运行 |
|
||
|
||
```mermaid
|
||
gantt
|
||
title 杜康好客 V1(示意)
|
||
dateFormat YYYY-MM-DD
|
||
section 基础
|
||
M0 仓库骨架 :m0, 2026-07-01, 7d
|
||
M1 IAM开城商品 :m1, after m0, 10d
|
||
section 核心
|
||
M2 交易 :m2, after m1, 14d
|
||
M3 权益核销 :m3, after m2, 14d
|
||
section 运营
|
||
M4 拓店售后 :m4, after m3, 14d
|
||
M5 结算 :m5, after m4, 10d
|
||
M6 增长 :m6, after m5, 7d
|
||
section 上线
|
||
UAT上线 :launch, after m6, 14d
|
||
```
|
||
|
||
---
|
||
|
||
## 3. M0 仓库初始化(第 0~1 周)
|
||
|
||
> **阻塞一切后续任务**。任务卡见附录 A `M0-*`。
|
||
|
||
| 类别 | 交付 |
|
||
|------|------|
|
||
| 根目录 | `pnpm-workspace.yaml`、`package.json`、ESLint/Prettier、`.env.example` |
|
||
| packages | `shared-types`(ActorType、OrderStatus、错误码)、`domain`(起购/权益/核销纯函数) |
|
||
| server | NestJS 启动、`PrismaModule`、`GlobalExceptionFilter`、统一 `{code,message,data}` |
|
||
| apps | 四端 Taro 脚手架、`request.ts`(带 `X-Client-App`)、登录态存储 |
|
||
| deploy | `docker-compose.yml`(MySQL + Redis)、`prisma migrate` 或执行 `数据库设计2` §5 SQL |
|
||
| CI | lint + `prisma validate` + `domain` 单元测试 |
|
||
|
||
**M0 出口**:`GET /api/v1/health` 200;`npx prisma validate` 通过;四端空白页 + 登录页壳可编译。
|
||
|
||
---
|
||
|
||
## 4. 分里程碑交付说明
|
||
|
||
### M1 基础(IAM + 开城 + 商品)
|
||
|
||
**PRD**:§3.1 登录、§6.2 开城、§6.3 商品
|
||
**DB**:`users`、`store_accounts`、`partner_accounts`、`hq_accounts`、`cities`、`products`、`wx_app_configs`
|
||
**API**:§2 四端认证、`/catalog/*`、`/admin/cities`、`/admin/products`、`/admin/hq-accounts`
|
||
|
||
| 端 | 页面(原型) | 关键能力 |
|
||
|----|--------------|----------|
|
||
| mini-hq | hq/1~2, 6~9, 12~14 | 总部登录、开城、商品 CRUD |
|
||
| mini-user | user/1, 2 | C端登录、首页骨架 |
|
||
| mini-partner | partner/1~2 | 合伙人登录壳 |
|
||
| h5-shop | shop/1~2 | 门店登录壳 |
|
||
|
||
### M2 交易(C端主链路)
|
||
|
||
**PRD**:§3.2~§3.6
|
||
**DB**:`orders`、`order_items`、`payments`、`user_addresses`、`benefit_coupons`、`benefit_ledgers`
|
||
**API**:`/trade/orders/*`、`/user/addresses`、`callbacks/wechat/pay`
|
||
|
||
| 端 | 页面 | 关键能力 |
|
||
|----|------|----------|
|
||
| mini-user | user/3~12, **9 含待发货 Tab** | 详情、下单、支付、5 Tab 订单、改址 |
|
||
|
||
**业务验收**:同城 1 瓶拒单、2 瓶成功;跨城 5 瓶拒单、6 瓶成功;支付成功发券。
|
||
|
||
### M3 权益与核销
|
||
|
||
**PRD**:§3.7~§3.8、§4
|
||
**DB**:`redeem_tokens`、`redeem_records`、`store_ratings`、`store_payouts`(创建待打款)
|
||
**API**:`/benefit/*`、`/redeem/*`、`/stores`、`/shop/redeem/*`
|
||
|
||
| 端 | 页面 | 关键能力 |
|
||
|----|------|----------|
|
||
| mini-user | user/15~22, 17~18 | 门店列表、权益、核销码、评价 |
|
||
| h5-shop | shop/3~7 | 扫码、确认核销、记录 |
|
||
|
||
**业务验收**:核销 ¥501 拒单;码 5 分钟失效;暂停门店 C 端不可见。
|
||
|
||
### M4 运营(拓店 + 售后)
|
||
|
||
**PRD**:§5.3~§5.6、§6.5、§6.8
|
||
**DB**:`stores`、`store_media`、`store_audits`、`after_sale_tickets`、`refunds`、`delivery_intercepts`
|
||
**API**:`/partner/stores/*`、`/admin/store-audits/*`、`/admin/after-sales/*`、`/partner/intercepts/*`
|
||
|
||
### M5 结算
|
||
|
||
**PRD**:§4.4、§5.7、§6.7
|
||
**DB**:`store_payouts`、`partner_bills`、`order_commissions`、`partner_withdrawals`
|
||
**API**:`/admin/settlement/*`、`/partner/settlement/*`、`/shop/redeem/records`
|
||
|
||
### M6 增长
|
||
|
||
**PRD**:§3.10
|
||
**DB**:`promo_codes`、`user_promo_attributions`、`event_logs`
|
||
**API**:`/promo/touch`、`/analytics/events`、`/admin/promo-codes`、`/admin/reports/*`
|
||
|
||
---
|
||
|
||
## 5. 编码规范速链
|
||
|
||
- 模块禁止跨表:见 `conventions.md` §2、`技术方案` §2.5
|
||
- JWT:`actorType` + `actorId`,见 `API列表` §1.5
|
||
- C 端用户:`users.phone` 唯一必填;B 端三表分离
|
||
- 金额:`Decimal(10,2)`;权益发放 `benefitAmount ?? price`
|
||
- 核销:Redis Token 5min + `benefit_coupons.version` 乐观锁
|
||
- 订单 Tab:`all|pending_pay|pending_ship|pending_receive|completed`
|
||
|
||
---
|
||
|
||
## 6. 测试策略
|
||
|
||
| 类型 | 范围 |
|
||
|------|------|
|
||
| 单元 | `packages/domain`:起购、权益额、核销上限 ¥500 |
|
||
| 集成 | 支付回调、核销事务、退款权益 VOID |
|
||
| E2E | 购酒→发券→核销→门店 payout PENDING |
|
||
| 里程碑末 | 全量冒烟 + 附录 A 任务卡验收勾选 |
|
||
|
||
**必测 8 条**(与 v1.2 相同):起购、跨城到付、发券金额、核销上限、闭店隐藏、待发货 Tab、退款作废、T+1 状态。
|
||
|
||
---
|
||
|
||
## 7. 前置依赖
|
||
|
||
| 项 | 最迟 |
|
||
|----|------|
|
||
| 微信商户号、三小程序 AppId | M1 |
|
||
| `pages/user/9` 改稿(待发货 Tab) | M2 |
|
||
| 郑州 4 SKU 素材 | M1 |
|
||
| 小飞侠 API(可 Mock) | M2 |
|
||
| 短信模板 | M3 |
|
||
|
||
---
|
||
|
||
## 8. 人天估算(不变)
|
||
|
||
约 **176 人天**,8 人团队 **10~12 周**(见 v1.2 §4)。
|
||
|
||
---
|
||
|
||
## 附录 A · 编码任务卡
|
||
|
||
> Agent:**一次只领取一张卡**;完成后在 PR 描述写 `Closes Mx-XX-XXX`。
|
||
|
||
### M0 基础设施
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M0-INFRA-001 | Lead | pnpm workspace + 根脚本 | `/package.json`, `pnpm-workspace.yaml` | — | — | `pnpm -r list` 四 apps + server |
|
||
| M0-INFRA-002 | Lead | `packages/shared-types` 枚举与 JWT | `packages/shared-types/src/` | — | API §1.5 | 导出 ActorType、OrderStatus、ApiResponse |
|
||
| M0-INFRA-003 | Lead | `packages/domain` 纯函数 + 测试 | `packages/domain/` | PRD §2.1, §2.3 | — | 起购/权益/¥500 单测通过 |
|
||
| M0-BE-001 | Lead | NestJS 骨架 + health | `server/dukang-api/src/main.ts` | 技术方案 §2.3 | — | `GET /health` |
|
||
| M0-BE-002 | Lead | PrismaModule + migrate | `server/dukang-api/prisma/` | 数据库设计2 §5 | 全表 | `prisma validate` |
|
||
| M0-BE-003 | Lead | 统一响应/异常 Filter | `server/dukang-api/src/common/` | API §1.2 | — | `{code,message,data}` |
|
||
| M0-FE-001 | A~D | 四端 Taro init | `apps/*/` | — | — | 各端 `dev` 编译通过 |
|
||
| M0-FE-002 | A | `mini-user` request + auth 存储 | `apps/mini-user/src/services/` | API §1.1 | — | 可带 X-Client-App |
|
||
| M0-DEV-001 | Lead | docker-compose MySQL+Redis | `deploy/docker-compose.yml` | — | — | 本地 DB 可连 |
|
||
|
||
### M1 IAM + 开城 + 商品
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M1-BE-IAM-001 | A | 短信发送 | `modules/iam/` | §3.1 | `POST /auth/sms/send`, `sms_logs` | scene 分端 |
|
||
| M1-BE-IAM-002 | A | C端 sms/wechat 登录 | `modules/iam/` | §3.1, U1~U4 | `/auth/login/*`, `users` | phone 唯一 |
|
||
| M1-BE-IAM-003 | D | 门店登录 | `modules/iam/` | §4.1 | `/shop/auth/*`, `store_accounts` | actorType=STORE |
|
||
| M1-BE-IAM-004 | B | 合伙人登录 | `modules/iam/` | §5.1 | `/partner/auth/*`, `partner_accounts` | actorType=PARTNER |
|
||
| M1-BE-IAM-005 | C | 总部登录 + hq 账号 CRUD | `modules/iam/`, `modules/catalog/` | §6 | `/admin/auth/*`, `hq_accounts` | actorType=HQ |
|
||
| M1-BE-IAM-006 | A | JWT Guard 四端 | `common/guards/` | API §1.4 | — | actor 校验 |
|
||
| M1-BE-CAT-001 | C | 开城 CRUD + 佣金 | `modules/catalog/` | §6.2 | `/admin/cities/*`, `cities`, `city_commission_rules` | 郑州 ACTIVE |
|
||
| M1-BE-CAT-002 | C | 商品 CRUD | `modules/catalog/` | §6.3 | `/admin/products/*`, `products` | benefit_amount 可空 |
|
||
| M1-BE-CAT-003 | C | C端商品列表 Public | `modules/catalog/` | §3.2 | `GET /catalog/products` | 仅 ON_SALE |
|
||
| M1-FE-HQ-001 | C | 总部登录+开城+商品页 | `apps/mini-hq/` | hq/1,6~9,12,14 | §6 admin | 可配 4 SKU |
|
||
| M1-FE-U-001 | A | C端登录+首页 | `apps/mini-user/` | user/1,2 | §3.1~3.2 | 清香型 4 款 |
|
||
| M1-FE-P-001 | B | 合伙人登录壳 | `apps/mini-partner/` | partner/1~2 | §5.1 | 可登录 |
|
||
| M1-FE-S-001 | D | 门店登录壳 | `apps/h5-shop/` | shop/1~2 | §4.1 | 可登录 |
|
||
|
||
### M2 交易
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M2-BE-TRD-001 | A | 地址 CRUD | `modules/trade/` | §3.4 | `/user/addresses`, `user_addresses` | 默认地址 |
|
||
| M2-BE-TRD-002 | A | 下单 preview(起购/运费) | `modules/trade/` + `domain` | §2.3, §3.3 | `POST /trade/orders/preview` | 2/6 瓶规则 |
|
||
| M2-BE-TRD-003 | A | 创建订单 + 推广归因 | `modules/trade/` | §3.10 | `POST /trade/orders`, `orders.promo_code_id` | 带 channel_source |
|
||
| M2-BE-TRD-004 | A | 微信支付 + 回调 | `modules/trade/`, `callbacks/` | §3.3.4 | `/trade/orders/:id/pay`, `payments` | 幂等 SUCCESS |
|
||
| M2-BE-BEN-001 | A | 支付成功发券 | `modules/benefit/` | §2.1 | `benefit_coupons`, `benefit_ledgers` | GRANT 流水 |
|
||
| M2-BE-TRD-005 | A | 订单列表 5 Tab | `modules/trade/` | §3.5.1 | `GET /trade/orders?tab=` | **含 pending_ship** |
|
||
| M2-BE-TRD-006 | A | 改址 + 拦截工单 | `modules/trade/` | §3.5.4 | `delivery_intercepts` | 创建拦截 |
|
||
| M2-FE-U-002 | A | 商品详情+确认订单 | `apps/mini-user/` | user/3~5 | preview API | 跨城弹窗 |
|
||
| M2-FE-U-003 | A | 地址+支付+订单列表 | `apps/mini-user/` | user/6~12,**9** | trade API | 5 Tab |
|
||
| M2-INT-001 | A | 小飞侠 Mock/对接 | `callbacks/xfx` | §7.1 | 配送状态 | 待发货→配送中 |
|
||
|
||
### M3 权益与核销
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M3-BE-BEN-002 | A | 权益汇总/券/明细 | `modules/benefit/` | §3.8 | `/benefit/*` | 余额正确 |
|
||
| M3-BE-RDM-001 | D | 核销 Token Redis | `modules/redeem/` | §3.8.3 | `POST /redeem/token`, `redeem_tokens` | 5min/¥500 |
|
||
| M3-BE-RDM-002 | D | 门店扫码确认核销 | `modules/redeem/` | §4.3 | `/shop/redeem/*`, `redeem_records` | 事务+乐观锁 |
|
||
| M3-BE-RDM-003 | D | 核销评价 | `modules/redeem/` | §3.8.3 | `store_ratings` | 1~5 分 |
|
||
| M3-BE-STR-001 | B | C端门店列表/详情 | `modules/store/` | §3.7 | `GET /stores` | 仅 OPEN |
|
||
| M3-BE-NOT-001 | Lead | 核销短信 | `modules/notify/` | §4.3 | `sms_logs` | 门店收到短信 |
|
||
| M3-FE-U-004 | A | 权益+核销全流程 | `apps/mini-user/` | user/15~22 | benefit+redeem | 出码成功 |
|
||
| M3-FE-S-002 | D | 门店核销全流程 | `apps/h5-shop/` | shop/3~7 | shop/redeem | 扫码确认 |
|
||
|
||
### M4 运营
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M4-BE-STR-002 | B | 门店三步录入+审核 | `modules/store/` | §5.3 | `/partner/stores/*`, `store_audits` | 提交 PENDING |
|
||
| M4-BE-STR-003 | C | 总部审核门店 | `modules/store/` | §6.5 | `/admin/store-audits/*` | reviewer=hq_accounts |
|
||
| M4-BE-IAM-007 | B | 合伙人子账号 | `modules/iam/` | §5.9 | `/partner/staff`, `partner_accounts` | 主/子账号 |
|
||
| M4-BE-TRD-007 | A | 补发单 | `modules/trade/` | §3.6 | `orders` RESHIPMENT | 金额 0 |
|
||
| M4-BE-TRD-008 | A | 退款+权益 VOID | `modules/trade/` | §3.6.2 | `refunds`, `after_sale_tickets` | 微信退款 |
|
||
| M4-FE-P-002 | B | 合伙人门店+补发+拦截 | `apps/mini-partner/` | partner/4~9,12~13 | partner API | 闭环 |
|
||
| M4-FE-HQ-002 | C | 总部审核+客服 | `apps/mini-hq/` | hq/19~20,26~27 | admin after-sales | 退款可操作 |
|
||
|
||
### M5 结算
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M5-BE-STL-001 | C | 核销→store_payouts | `modules/settlement/` | §4.4 | 60%, T+1 | PENDING |
|
||
| M5-BE-STL-002 | C | T+1 打款任务 | `jobs/` | §6.7 | batch-pay | PAID |
|
||
| M5-BE-STL-003 | C | 合伙人 T+30 账单 | `modules/settlement/` | §5.7 | `partner_bills` | 确认流程 |
|
||
| M5-FE-* | B,C,D | 三端结算页 | 各 app | partner/10,22; shop/6; hq/21~23 | settlement API | 状态展示 |
|
||
|
||
### M6 增长
|
||
|
||
| ID | OWNER | 任务 | 主要路径 | PRD | API/DB | 验收 |
|
||
|----|-------|------|----------|-----|--------|------|
|
||
| M6-BE-ANA-001 | A | promo touch 归因 | `modules/analytics/` | §3.10.1 | `user_promo_attributions` | 首次触达 |
|
||
| M6-BE-ANA-002 | A | 埋点批量入库 | `modules/analytics/` | §3.10.2 | `event_logs` | 17 事件 |
|
||
| M6-BE-CAT-004 | C | 推广码+统计 | `modules/catalog/` | §6.6 | `/admin/promo-codes` | scan/order_count |
|
||
| M6-FE-HQ-003 | C | 报表+预警 | `apps/mini-hq/` | hq/3~5,15~17 | `/admin/reports` | GMV/渠道 |
|
||
|
||
---
|
||
|
||
## 附录 B · 原型 → API → 模块 速查
|
||
|
||
| 端 | 原型目录 | 主要 API 前缀 | NestJS Module |
|
||
|----|----------|---------------|---------------|
|
||
| C端 | `pages/user/` | `/auth`, `/user`, `/catalog`, `/trade`, `/benefit`, `/redeem`, `/stores`, `/promo` | iam, catalog, trade, benefit, redeem, store, analytics |
|
||
| 门店 | `pages/shop/` | `/shop/auth`, `/shop/redeem`, `/shop/store` | iam, redeem, store |
|
||
| 合伙人 | `pages/partner/` | `/partner/*` | iam, store, trade, settlement |
|
||
| 总部 | `pages/hq/` | `/admin/*` | iam, catalog, store, trade, settlement, ops, analytics |
|
||
|
||
---
|
||
|
||
## 附录 C · Skills 绑定说明
|
||
|
||
| Skill | 路径 | 何时启用 |
|
||
|-------|------|----------|
|
||
| **dukang-coding** | `.cursor/skills/dukang-coding/` | **写代码、实现任务卡、修 Bug** |
|
||
| dukang-project | `.cursor/skills/dukang-project/` | 写 PRD、评审需求、对照原型 |
|
||
|
||
在 Cursor 项目设置或对话中 @dukang-coding,并指明任务卡 ID,例如:
|
||
|
||
> 实现 M2-BE-TRD-002,按开发计划与 PRD 完成下单 preview。
|
||
|
||
---
|
||
|
||
*计划随迭代每周更新;任务卡新增请保持 ID 格式 `Mx-LAYER-NNN`。*
|
||
|
||
|
||
---
|
||
|
||
# §八、核心业务链路
|
||
|
||
### 购酒 → 发券 → 配送
|
||
|
||
```
|
||
user_user → user_order(含商品快照) → log_third_party(WECHAT_PAY)
|
||
→ user_order_delivery(1:1) → user_benefit_coupon → common_event(BENEFIT_LEDGER,GRANT)
|
||
```
|
||
|
||
### 核销 → 门店 T+1
|
||
|
||
```
|
||
Redis redeem:token(5min) → user_redeem_record → common_event(BENEFIT_LEDGER,REDEEM)
|
||
→ store_payout(T+1) → user_store_rating → log_third_party(SMS)
|
||
```
|
||
|
||
### 门店入驻
|
||
|
||
```
|
||
partner_partner → store_store + common_resource → common_event(STORE_AUDIT)
|
||
→ hq_account 审核 → store_account
|
||
```
|
||
|
||
### 退款
|
||
|
||
```
|
||
common_ticket(REFUND) → log_third_party(WECHAT_REFUND) → user_benefit_coupon VOID
|
||
→ common_event(BENEFIT_LEDGER,VOID) → common_event(ORDER_STATUS,REFUNDED)
|
||
```
|
||
|
||
### 改址拦截
|
||
|
||
用户改址 API 更新 user_order 收货字段 → common_event(ORDER_STATUS) + 可选 common_ticket(ALERT) → 合伙人 `pages/partner/4-拦截配送.png` 处理 → user_order_delivery 与第三方回调同步状态。
|
||
|
||
---
|
||
|
||
# §九、第三方集成与非功能
|
||
|
||
| 系统 | 用途 | 落库 |
|
||
|------|------|------|
|
||
| 微信支付/退款 | 下单、退款 | log_third_party + user_order.pay_* |
|
||
| 小飞侠 | 同城配送 | log_third_party(XFX) + user_order_delivery |
|
||
| 物流 | 跨城 | user_order_delivery + 总部发货 |
|
||
| 短信 | 验证码、核销通知 | log_third_party(SMS) |
|
||
| OSS | 图片/合同 | common_resource |
|
||
|
||
**非功能**:JWT 四端隔离;支付/核销幂等;列表 P95 < 500ms;核销 Redis 5min + 券 version 乐观锁;手机号脱敏。
|
||
|
||
---
|
||
|
||
*编码配合根目录 agent.md、skills.md、conventions.md。*
|