Files
order_site/docs/khhao来源接入设计.md
T
2026-05-02 16:20:08 +08:00

10 KiB
Raw Blame History

khhao 新数据来源接入设计

1. 背景

当前系统的订单来源只有 agiso,核心模式是:

  • 上游通过 webhook 推送订单事件;
  • 后端按 provider + platform + shopId + platformOrderId 幂等落库;
  • 命中履约绑定后生成任务、领取链接、自动发货等后续流程。

现在需要新增一个来源:admin.khhao.com 这一套已开发好的平台后台。

agiso 的差异是:

  • 不是 webhook 推送,而是账号密码登录 + 验证码识别 + Cookie 会话查询
  • 订单数据来自平台接口查询;
  • 初期目标是先完成登录能力订单查询能力,再决定是否做定时拉取/增量同步。

2. 已确认事实(来自 2026-05-02 的 HAR

HAR 文件:/Users/yml/Desktop/抓包/登陆.har

已确认接口链路:

  1. 打开登录页
    GET https://admin.khhao.com/c/login/index.php

  2. 获取验证码图片
    GET https://admin.khhao.com/verify_img.php

  3. 提交登录表单
    POST https://admin.khhao.com/c/login/index.php
    表单字段:

    • username
    • password
    • img_code
  4. 登录成功响应

    {"errcode":0,"msg":"登陆成功","url":"/c/payOrder/index.php"}
    
  5. 查询订单列表
    GET https://admin.khhao.com/c/payOrder/get.php?page=1&limit=50

  6. 当前 HAR 中,登录依赖 PHPSESSID Cookie 维持会话。

订单列表响应里已看到这些关键字段:

  • ordersn:外部订单号
  • pingtai / pingtaiName:平台标识/平台名
  • shopid / shopName:店铺
  • goodid / goodName:商品
  • skuSKU
  • fee:成交金额
  • chengben / lirun:成本/利润
  • num:数量
  • status / statusName:订单状态
  • addtime:下单/录入时间

3. 设计目标

3.1 MVP 目标

先做最小可用能力:

  1. 后端可通过账号密码自动登录 khhao;
  2. 自动拉取验证码图片,并用现有 ddddocr 识别;
  3. 登录成功后带 Cookie 调用订单查询接口;
  4. 能按统一结构把 khhao 订单转换为内部订单模型;
  5. 提供一个手动查询 / 手动同步入口,先不直接接入自动履约主流程。

3.2 第二阶段目标

  1. 支持按时间窗口或页码批量拉取订单;
  2. 增加定时轮询同步;
  3. 将 khhao 订单正式纳入现有订单履约流程;
  4. 视需要增加远端订单详情接口接入。

4. 关键设计决策

4.1 新来源标识

建议:

  • provider = 'khhao'
  • platform = 由返回字段映射

原因:

  • 现有系统已经以 provider/platform 作为来源分层;
  • khhao 本身更像“聚合后台/运营后台”,其下可能有多个平台;
  • 后续如果 pingtai=3 代表快手、还有其它平台,也可以继续扩展。

建议先做一个映射表,例如:

  • 3 -> kuaishou
  • 未识别值 -> unknown

同时把原始 pingtaipingtaiName 放进 raw_payload_json 保留证据。

4.2 接入模式

agisopushkhhao 应设计成 pull

因此不要强行塞进 webhook-service,而是单独建立:

  • 登录会话服务
  • 验证码识别服务
  • 订单查询服务
  • 订单转换/同步服务

4.3 会话管理

建议优先采用 纯 HTTP + Cookie Jar,不引入浏览器自动化。

原因:

  • HAR 显示登录流程很简单,没有前端加密、签名或复杂跳转;
  • 验证码是普通图片;
  • 登录后查询接口是标准 XHR
  • 用 HTTP 实现更稳定,也更适合服务端定时任务。

只有在后续发现以下情况时,再退回浏览器方案:

  • 服务端校验动态前端字段;
  • 有 JS 生成签名;
  • Cookie/会话依赖浏览器行为;
  • 验证码识别成功但仍反复登录失败。

4.4 OCR 复用

现有 OCR 子服务已经使用:

  • apps/backend/subservices/ocr-worker
  • ddddocr>=1.6.1

因此不需要新增 OCR 技术栈,只需要把 khhao 验证码图片作为图片字节传给现有 OCR 能力即可。

建议新增一个更通用的方法,而不是继续绑定在 “Tencent” 语义上:

  • 现状:recognizeTencentCaptcha
  • 建议新增:recognizeImageCaptcha

然后:

  • 腾讯验证码继续走原接口或复用通用接口;
  • khhao 登录验证码直接走通用接口。

5. 推荐模块拆分

建议新增目录:

apps/backend/src/services/platforms/khhao/

建议模块:

5.1 captcha-service.js

职责:

  • 请求 /verify_img.php
  • 读取图片字节
  • 调 OCR
  • 返回识别结果与调试信息

建议返回:

  • captchaText
  • imageBase64(仅调试阶段可选)
  • cookieHeaders

5.2 session-service.js

职责:

  • 初始化 Cookie 容器;
  • 访问登录页,拿到初始 PHPSESSID
  • 获取验证码并识别;
  • 提交登录表单;
  • 校验登录响应;
  • 返回已登录会话对象。

建议会话对象:

  • baseUrl
  • cookieHeader
  • cookieMap
  • loggedInAt

5.3 order-query-service.js

职责:

  • 调用 /c/payOrder/get.php
  • 支持分页参数:pagelimit
  • 后续支持筛选参数(如果继续抓到更多接口)
  • 返回原始平台订单列表

5.4 order-mapper-service.js

职责:

  • 将 khhao 原始订单映射成内部统一订单结构;
  • 归一化金额、数量、状态、平台、店铺、SKU;
  • 产出可供 order-service 或新同步服务消费的对象。

建议映射:

  • platformOrderId <- ordersn
  • shopId <- shopid
  • shopName <- shopName
  • totalAmount <- fee(转分)
  • items[0].skuCode <- sku
  • items[0].skuName <- goodName
  • items[0].quantity <- num
  • rawPayload <- 原始整条记录

注意:

  • 当前列表接口一条记录看起来像“一单一商品”,但不能假设永远如此;
  • 第一版可以先按单商品映射;
  • 如果后续发现有多商品订单,再调整内部映射。

5.5 order-sync-service.js

职责:

  • 批量查询 khhao 订单;
  • order-mapper-service 转换;
  • 调内部订单 upsert
  • 记录同步结果、失败原因、游标信息。

这里建议不要直接复用 upsertOrderFromWebhook(event),因为它的命名和语义绑定 webhook。

更合理的演进方向:

  • 抽一个来源无关的方法,例如 upsertOrderFromSource(event)
  • webhook-service 继续只负责 webhook 解析;
  • khhao 同步服务直接调用来源无关的 upsert。

6. 配置设计

6.1 运行时配置

建议在:

  • apps/backend/config/default.cjs
  • apps/backend/src/types/runtime-config.js
  • apps/backend/src/config/runtime.js

增加:

platforms: {
  khhao: {
    baseUrl: 'https://admin.khhao.com',
    timeoutMs: 5000,
    loginPath: '/c/login/index.php',
    captchaPath: '/verify_img.php',
    orderListPath: '/c/payOrder/get.php',
  },
}

6.2 凭据配置

不建议把账号密码直接写进仓库文档或默认配置。

建议通过以下方式之一管理:

  1. 环境变量;
  2. apps/backend/data/khhao-sources.json
  3. 后台平台配置页维护。

建议结构:

{
  "sources": [
    {
      "sourceKey": "khhao-main",
      "enabled": true,
      "baseUrl": "https://admin.khhao.com",
      "username": "******",
      "password": "******",
      "defaultPlatform": "kuaishou"
    }
  ]
}

第一阶段最省成本的方案:本地文件 + 环境变量覆盖

7. 与现有系统的衔接方式

7.1 第一阶段:只做手动查询/同步

建议新增后台接口,例如:

  • POST /api/v1/admin/platform-config/khhao/test-login
  • POST /api/v1/admin/platform-config/khhao/query-orders
  • POST /api/v1/admin/platform-config/khhao/sync-orders

这样好处是:

  • 不会影响现有 agiso 主链路;
  • 可以先验证 OCR、登录、Cookie、字段映射;
  • 便于比对真实订单数据。

7.2 第二阶段:纳入统一订单流程

当字段映射稳定后,再把 khhao 同步数据接到统一订单主链路:

  • 来源查询 -> 订单映射 -> 通用 upsert -> 履约绑定 -> 任务生成

这一步需要补充:

  • khhao 订单状态到内部 orderStatus/payStatus 的映射;
  • 去重与增量同步策略;
  • 同一来源重复登录的频率控制;
  • 同步审计日志。

8. 状态映射建议

当前 HAR 仅看到:

  • status = 2 => 已发货
  • status = 0 => 未打款

第一阶段不要写死太多业务含义,建议:

内部订单状态

  • status=0 -> created
  • status=2 -> delivered
  • 未知值 -> unknown

内部支付状态

  • status=0 -> unpaid
  • status=2 -> paid
  • 未知值 -> unknown

但这只是 初版推断,最终要以更多样本验证。

9. 风险点

  1. 验证码识别率

    • ddddocr 大概率可用,但识别失败需要自动重试;
    • 建议单次登录允许 2~3 次验证码重试。
  2. 登录态过期

    • 需要判断何时复用 Cookie,何时重新登录;
    • 第一阶段可以每次查询都重新登录,先求稳定。
  3. 订单列表不是详情接口

    • 当前拿到的是列表接口,不排除存在订单详情页/详情接口;
    • 第一版先以列表字段落库;
    • 如果后续履约需要更多字段,再补抓详情接口。
  4. 平台字段含义未完全确认

    • pingtai=3 目前只从样本推断是快手;
    • 需要再抓几个平台样本确认映射表。
  5. 同步边界

    • khhao 是拉取式来源,必须明确增量条件;
    • 第一版建议按 page/limit 手动同步,先不做自动游标。

10. 推荐实施顺序

阶段 A:打通基础能力

  1. 增加 khhao 配置结构;
  2. 增加通用图片 OCR 能力;
  3. 实现登录 + Cookie 会话;
  4. 实现订单列表查询;
  5. 增加后台“测试登录 / 查询订单”接口。

阶段 B:打通内部模型

  1. 实现 khhao -> 内部订单映射;
  2. 提炼 webhook 无关的通用 order upsert
  3. 增加手动同步接口;
  4. 在后台展示同步结果。

阶段 C:进入自动履约

  1. 增量同步;
  2. 定时任务;
  3. 状态回补;
  4. 接入履约绑定、任务生成、消息通知。

11. 本次设计结论

结论很明确:

  • khhao 不应该按 agiso webhook 思路接;
  • 应该作为一个新的 pull 型来源 单独建接入层;
  • OCR 直接复用现有 ddddocr 子服务;
  • 第一阶段先做手动查询/同步最稳;
  • 等字段、状态、平台映射稳定后,再接入统一履约主流程。