feat(work-order): 发布并核销支持抖音券(按来源分流,抖音走 DYC 券核销)
This commit is contained in:
+71
-6
@@ -1,7 +1,7 @@
|
||||
# 抖音码速达 · 总览(进度 / 代码 / 配置 / 上线)
|
||||
|
||||
> 更新:2026-10-09 **状态:最小接入已实现完毕,且已在真实平台跑通**(真实网关签名验证 / 真实推送订阅 / 真实 orderDetail 建单 / 真实 coupons.syncV2 同步成功),两端自检全绿
|
||||
> 本文是这套内容的**入口**,具体细节在 04~11。
|
||||
> 更新:2026-10-15 **状态:最小接入已跑通,且按 SKU 的三层分流已上线**(真实网关签名验证 / 真实推送订阅 / 真实 orderDetail 建单 / 真实 coupons.syncV2 同步成功 / 工单发布顺带核销抖音券),两端自检全绿
|
||||
> 本文是这套内容的**入口**,具体细节在 04~11,最新增量见 [§九点六](#九点六2026-10-14--10-15-增量)。
|
||||
|
||||
---
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
按 [05-最小接入方案分析.md](05-最小接入方案分析.md) 落地的**最小闭环六步全部完成**,后端 636 测试 / 前端 115 测试全绿,迁移 `094` 已在本地临时库实测通过(建表 + 幂等 + 唯一约束行为均验证)。
|
||||
|
||||
**没做的**:**按 SKU 的三层分类**(抖音目前只有「皮肤自动发货」+「人工」两条路,缺 91/快手 的中间层 → 总设计见 [12-按SKU分类改造总设计.md](12-按SKU分类改造总设计.md),分层设计与生产实测见 [10-三层分流设计.md](10-三层分流设计.md),运营动作见 [11-接单模板待补清单.md](11-接单模板待补清单.md))、兑换后的实际交付物(卡密/充值)、`order.searchList` 对账。
|
||||
**没做的**:兑换后的实际交付物(卡密/充值)、`order.searchList` 对账、兑换页二次校验(手机后 4 位)。
|
||||
|
||||
> ✅ **原「按 SKU 的三层分类」已上线**(2026-10-14):抖音与 91/快手 同构(命中映射 → `affiliate_dash` 自动发货;未命中 → 接单平台建工单;都不中 → 无载体=待人工),载体唯一有硬守卫。总设计 [12-按SKU分类改造总设计.md](12-按SKU分类改造总设计.md)、分层实测 [10-三层分流设计.md](10-三层分流设计.md)、运营动作 [11-接单模板待补清单.md](11-接单模板待补清单.md)。
|
||||
|
||||
**只走真实公网联调**(离线模拟已按要求删除):
|
||||
|
||||
@@ -205,15 +207,17 @@ git add apps/backend/src/app.ts \
|
||||
| # | 缺口 | 影响 | 备注 |
|
||||
| --- | --- | --- | --- |
|
||||
| ~~1~~ | ~~后台前端配置面板~~ | **已完成**:`/admin/platform-shops?tab=douyinMashida` | — |
|
||||
| 2 | 履约任务分支 | **已完成**:抖音已接入 `affiliate_dash`(皮肤/道具自动发货)+ `manual_dispatch`(人工兜底) | `product-resolution-service.ts:255-317`;但**写死了 preferred,履约路由规则对抖音无效** |
|
||||
| 2b | **接单平台发单层(层②)** | 抖音单不进打手池:生产实测 11 笔全 `unmatched`、工单 0 个 | 设计 [10-三层分流设计.md](10-三层分流设计.md) / 运营 [11-接单模板待补清单.md](11-接单模板待补清单.md) |
|
||||
| ~~2~~ | ~~履约任务分支~~ | **已完成且已修正**:命中映射 → `affiliate_dash` 自动发货;未命中**不再写死** preferred、**不再兜底 `manual_dispatch`**(否则会出现「人工任务 + 工单」双载体) | `product-resolution-service.ts:286-350`(commit `4b081d88`) |
|
||||
| ~~2b~~ | ~~**接单平台发单层(层②)**~~ | **已完成**:抖音按内部 SKU 三层分类(`snapshot.classification`),发单层有「载体唯一」硬守卫(命中 `affiliate_dash` 即跳过建工单);生产库接单模板 `platform` 已全部清空(354 条),抖音单从此可命中模板 | [10-三层分流设计.md](10-三层分流设计.md) / [11-接单模板待补清单.md](11-接单模板待补清单.md) |
|
||||
| ~~2c~~ | ~~工单「发布并核销」只核销快手电子凭证~~ | **已完成**(2026-10-15):按来源分流,抖音工单核销 DYC 券(`redeem_certificates`),见 [§九点六](#九点六2026-10-14--10-15-增量) | `worker-platform/publish-douyin-voucher-service.ts` |
|
||||
| 3 | 兑换后的实际交付物 | 当前只「上报核销 + 展示掩码券码 + 发链接」 | 等业务定(B2) |
|
||||
| 4 | `order.searchList` 对账任务 | 消息丢了就漏单 | 二期 |
|
||||
| 5 | `cancelVerify` 后台按钮 | 误核销只能手工 | 出网方法已就绪 |
|
||||
| ~~5~~ | ~~`cancelVerify` 后台按钮~~ | **已完成**:后台「抖音券核销」含核销/冲正/重新同步/对账/重发/作废(每个写操作带审计) | `routes/admin/douyin-mashida.ts`(commit `5a73fb74`) |
|
||||
| 6 | 兑换页二次校验(手机后 4 位) | 知道订单号即可兑换 | 看业务是否接受(B1) |
|
||||
| 7 | `message.config` 自动订阅 | 需平台侧手配 | 可选做「一键订阅」 |
|
||||
| 8 | 隧道域名变化需手工同步平台侧 | `set-public-url` 会打印待配项;ngrok 免费版建议保留静态域名 | 固定域名后基本不是问题 |
|
||||
| 9 | ngrok 免费版对浏览器插警示页 | 买家点 `cert_link` 会先过一页英文提示 | 正式环境用正式域名;联调期间点一下即可 |
|
||||
| — | 工单里的抖音券前端不渲染 | **有意为之**(2026-10-15 用户口径):打手/客服**不需要看到券码**,快照只落 `material_json` 供追溯 | `material_json.douyinMashidaVoucher` |
|
||||
|
||||
### 联调要实测的点
|
||||
|
||||
@@ -260,6 +264,67 @@ git add apps/backend/src/app.ts \
|
||||
| `order.message` 发消息 | ✅ 兑换成功后已调用,无错误日志(成功日志默认被 integration 阈值 warn 挡住) |
|
||||
| `messagetest` 自测入口 | ⚠️ 始终 `20006 data参数内容解析异常`,未探明其 data 要求;不影响真实链路 |
|
||||
|
||||
## 九点六、2026-10-14 / 10-15 增量
|
||||
|
||||
### 1)按 SKU 三层分流上线(`4b081d88`)
|
||||
|
||||
抖音与 91/快手 同构,**只动抖音,91 不变**:
|
||||
|
||||
| 层 | 判据 | 载体 |
|
||||
| --- | --- | --- |
|
||||
| ① 自动发货 | 内部 SKU 命中 `AFFILIATE_DASH_SKU_MAPPING`(常量表 + 后台 `skuMapping` 增量) | `affiliate_dash` 履约任务(买家输 UID → 扫码绑定 → 自动核销) |
|
||||
| ② 接单平台 | 命中接单模板(`work_product_rules`,按**内部 SKU**) | `work_orders` 工单 |
|
||||
| ③ 人工 | 两者都不中 | **无载体**(无任务无工单)=待人工 |
|
||||
|
||||
- `sku_code` 恒为**内部 SKU**(不再被英文 sku 覆写);引流长标题只进 `snapshot.productTitle`,**永不参与匹配**。
|
||||
- 未命中映射时**不设 preferred、强制覆盖 `unmatchedExecutorKey:''`**——否则会出现「人工任务 + 工单」双载体。
|
||||
- 载体唯一守卫:`sync-worker-orders-service.ts:65` 命中 `classification.channel==='affiliate_dash'` 的订单项**不建工单**(reason `affiliate_dash_carrier_taken`)。
|
||||
- 券 → 工单快照:`material_json.douyinMashidaVoucher`(对齐快手 `kuaishouIndustryVoucher`)。**前端有意不渲染**(打手/客服不需要看到券码)。
|
||||
|
||||
### 2)接单模板匹配引擎重构(`10464fea`,P0+P1)
|
||||
|
||||
按 [接单模板匹配引擎重构设计.md](../接单模板匹配引擎重构设计.md) 抽出 `services/product-match/`(适配器按**来源**划分:`kuaishou-91` / `pdd` / `douyin-mashida`)。生产回放 6000 条订单项:91/PDD 决策 **0 差异**,抖音 5 条全为修正。旧 `work-product-match-mappers.ts` 变为门面,签名不变。
|
||||
|
||||
### 3)工单「发布并核销」支持抖音券(本次)
|
||||
|
||||
**问题**:抖音单走到接单平台后有工单,但「发布并核销」只查 `kuaishou_industry_vouchers`(抖音订单在那张表里永远是空的)→ **抖音券从未被核销**。三个入口(发布 / 指派 / 寄售履约)共用同一个函数,全部受影响。
|
||||
|
||||
**改法**:在唯一入口按**来源**分流,核销本身**不重复实现**。
|
||||
|
||||
```text
|
||||
publishAdminWorkOrder / assignAdminWorkOrder / 寄售履约
|
||||
└─ consumeIndustryVouchersBeforeWorkOrderPublish (publish-voucher-service.ts)
|
||||
├─ 抖音(orders.provider === 'douyin_mashida')
|
||||
│ └─ verifyDouyinMashidaCertificateForWorkOrderPublish (publish-douyin-voucher-service.ts)
|
||||
│ ├─ 按 platform_order_id(= redeem_certificates.order_id,子单优先/父单兜底)查券
|
||||
│ ├─ 委托 verifyCertificate(redeem/certificate-service.ts)→ coupons.verifyV3
|
||||
│ │ (幂等 / invalid 拒核 / 未同步拒核 / 平台券码优先 / 失败对账自愈)
|
||||
│ └─ 券快照 merge 进工单 material_json.douyinMashidaVoucher + 事件 publish_voucher_consumed
|
||||
└─ 其它来源(91/快手)
|
||||
└─ 原快手电子凭证路径(listKuaishouIndustryVouchersByOid + consumeKuaishouIndustryVoucher)
|
||||
```
|
||||
|
||||
| 文件 | 作用 |
|
||||
| --- | --- |
|
||||
| `worker-platform/publish-douyin-voucher-service.ts` | 抖音券核销分支(新增) |
|
||||
| `worker-platform/publish-voucher-service.ts` | 顶部按来源分流(`isDouyinMashidaWorkOrder`,查 `orders.provider`) |
|
||||
| `utils/voucher-consume.ts` | 前端失败提示改为「请到「抖音券核销」或快手电子凭证后台人工核销后再发货」 |
|
||||
|
||||
口径要点:
|
||||
|
||||
1. **查不到券 → 抛 409**(`work_order_publish_douyin_certificate_missing`)而不是静默成功——抖音口径是「任何订单都发券」,查不到说明发券环节没走完,需要运营去「抖音券核销」重发。
|
||||
2. **券状态落库由 `verifyCertificate` 负责**,因此后台「抖音券核销」界面的状态、重复发布的幂等行为与买家兑换页完全一致(不会有「本地说没核销」的分叉)。
|
||||
3. **回填工单是 best-effort**:失败只留 warn,不影响发布结果。
|
||||
4. 单测用 `setOrderProviderResolverForTest` / `setDouyinVoucherDepsForTest` 注入(生产恒为 undefined,直连真实仓储与网关)。
|
||||
|
||||
**验证**(2026-10-15):后端 `npm run check` ✅ 740 例 0 失败(本次新增 13 例:核销成功回填/保留 material 其它字段/无券报错/真源报错转失败结果且不回填/已核销幂等/指派路径/无平台单号跳过 + 来源分流回归 3 例);前端 `npm run check` ✅ 143 例 0 失败。
|
||||
|
||||
### 4)其它
|
||||
|
||||
- `584b6f52`:问题单处置存在活跃拼单份额时,禁止取消 / 退回大厅 / 重开。
|
||||
|
||||
---
|
||||
|
||||
## 十、自检结果(本次)
|
||||
|
||||
| 项 | 结果 |
|
||||
|
||||
Reference in New Issue
Block a user