Files
junhong_cmp_fiber/docs/7月迭代/七月迭代联调交付说明.md
break cb26217205 让七月迭代具备可直接部署的配置基线
补齐三套环境配置、测试环境部署门禁与 system_config 初始化,并按当前无企微应用的约束将企微凭据改为明文存储。

Constraint: 当前测试环境尚无企微应用及历史企微密文数据

Rejected: 使用启动环境变量加密企微凭据 | 用户明确要求直接明文保存并移除加密密钥

Confidence: high

Scope-risk: moderate

Directive: 企微真实闭环完成前保持两个旧审批入口开关为 true

Tested: gofmt;git diff --check;bash -n;docker compose config;Gitea workflow YAML 解析;OpenAPI 重新生成

Not-tested: go test;常规 go build;LSP;实际数据库迁移;真实测试环境部署;企微真实联调
2026-07-25 18:18:45 +08:00

9.8 KiB
Raw Blame History

七月迭代联调交付说明

交付状态

本说明覆盖 deliver-july-iteration-confirmed-scope 的企业微信、Gateway、Redis/Asynq、对象存储和前端联调输入。生产代码、增量迁移和 OpenAPI 已生成至可联调状态;仓库迁移已新增至 000196,测试环境下次部署时由 API 启动脚本自动执行尚未执行自动化测试、完整构建、LSP 或真实外部环境闭环。

接口统一使用 {code,msg,data,timestamp} 响应。完整请求和响应结构以 docs/admin-openapi.yaml 为准。

企业微信联调

环境和管理配置

配置 来源 说明
JUNHONG_WECOM_BASE_URL 环境变量 默认 https://qyapi.weixin.qq.com
JUNHONG_WECOM_TIMEOUT 环境变量 默认 10s
corp_idagent_id、Secret POST /api/admin/wecom/applications 管理端按明文提交并保存;超级管理员读取时返回明文,业务日志不记录
回调 Token、EncodingAESKey 同上 Token 按明文提交EncodingAESKey 固定 43 位
默认发起人 PUT /api/admin/wecom/applications/:id/default-creator 必须先同步可见成员,再从当前可见成员中选择
template_id 和控件映射 PUT /api/admin/wecom/scenes/:business_type 模板必须先在企微后台创建,本系统只校验和绑定

部署侧还必须在企微管理后台配置:自建应用审批权限、应用可见通讯录范围、调用接口的可信 IP以及公开可访问的回调地址

GET/POST {API_PUBLIC_BASE_URL}/api/callback/wecom/approval/{application_id}

配置和联调顺序

  1. 部署 API 和 Worker并确认数据库迁移已执行至最新版本。
  2. 创建应用配置并调用 POST /api/admin/wecom/applications/:id/test 验证取 token。
  3. 调用 POST /api/admin/wecom/applications/:id/members/sync,再分页查询成员。
  4. 为内部系统账号调用 PUT /api/admin/accounts/:id/wecom-binding 绑定 (corp_id,userid)
  5. 选择一个当前可见成员作为默认发起人。代理退款、代理相关业务以及未绑定内部员工均使用该成员发起,但本地业务单仍保存真实提交人。
  6. 分别配置 refund_approvaloffline_recharge_approvaltemplate_id 和控件映射。选择控件必须填写企微模板真实 option key。
  7. 在企微后台配置回调 URL、Token、EncodingAESKey完成 GET 校验。
  8. 分别提交一笔退款和员工线下代充值,验证 applyeventsp_no、回调、详情同步、标准终态和业务终态。

Integration Log 不记录 Secret、access_token、media_id、附件正文或完整企微响应普通业务字段和业务快照按明文保存便于业务处理。

结果未知和旧入口

  • applyevent 超时或断连后标记为结果未知不自动创建第二张审批单Worker 通过时间窗单号和详情查询恢复。
  • wecom:approval:recovery 每 2 分钟触发,详情同步使用 wecom:approval:sync
  • 在真实退款和线下代充值闭环、存量 provider 清单均验证前,保持 JUNHONG_APPROVAL_LEGACY_REFUND_MANUAL_ENABLED=trueJUNHONG_APPROVAL_LEGACY_OFFLINE_RECHARGE_PAY_ENABLED=true
  • 切换后前端只读展示 approval_providerapproval_statusapproval_status_name,不得再提供企微记录的本地人工通过、驳回或线下确认按钮。

Gateway 卡限速联调

环境变量 说明
JUNHONG_GATEWAY_BASE_URL Gateway API 基础地址
JUNHONG_GATEWAY_APP_ID Gateway 应用 ID
JUNHONG_GATEWAY_APP_SECRET Gateway 应用密钥
JUNHONG_GATEWAY_TIMEOUT 超时秒数,允许 5300默认配置为 60

接口固定为:

PUT /api/admin/iot-cards/:iccid/speed-tier

请求只允许 code=-1..8Gateway 业务参数只有卡 ICCID 对应的 cardNo 和档位 code。设备没有限速接口,也不得通过设备绑定关系间接限速。

联调需覆盖全部档位、越权卡、明确失败和超时。超时返回结果未知时,按 Integration Log 中的 ICCID 到 Gateway 运维侧核对当前档位,再决定是否人工重试;系统不会盲目自动重发。

Redis、Asynq 和 Worker

API 与 Worker 必须连接同一 Redis/Asynq。新增或复用的任务如下

任务类型 队列 用途
wecom:approval:sync wecom:approval 拉取企微详情并同步标准决策
wecom:approval:recovery wecom:approval 结果未知恢复和未终态轮询
asset:package:batch_order 同名独立队列 单列 CSV 批量订购
device:import 同名独立队列 原设备导入和设备 CSV 批量分配共用任务外壳,通过 operation_type 分支
package:expiry:reminder data:cleanup 每日 15/7/3 天套餐临期提醒
export:dispatch/shard/finalize 各自既有队列 六类新增 datasource 继续复用导出流水线

联调时确认 Worker 启动日志已注册上述 HandlerJUNHONG_WORKER_ROLE 的部署拓扑为单实例 all,或严格一个 leader 加多个 consumer

System Config 初始化

迁移 000195_seed_july_system_config 初始化以下 6 个代码已注册配置;使用 ON CONFLICT DO NOTHING,不会覆盖环境管理员已经保存的值:

  • carrier_callback.ctcc_realname.enabled=false
  • carrier_callback.cmcc_realname.enabled=false
  • carrier_callback.cucc_realname.enabled=false
  • carrier_callback.cucc_realname_removal.enabled=false
  • c2b.payment.card_allowed_methods=["wallet","wechat","alipay"]
  • c2b.payment.device_allowed_methods=["wallet","wechat","alipay"]

部署后通过 GET /api/admin/system-configs 核对 6 项均为 registered=true。运营商回调默认关闭,完成对应运营商联调后再逐项开启;支付方式默认全选,可由超级管理员按卡和设备分别调整。

对象存储和 CSV

先调用 POST /api/admin/storage/upload-url 获取预签名地址,再把文件直传对象存储,业务接口只接收返回的 file_key

purpose 业务 文件要求
batch_purchase 资产套餐批量订购 UTF-8 单列 CSV最多 1000 行、10MB
device_batch_allocation 设备分配代理或设置套餐系列 UTF-8 单列 CSV支持 VirtualNo、IMEI、SN最多 1000 行、10MB

对象存储需配置 JUNHONG_STORAGE_PROVIDER、S3 endpoint/region/bucket/access key/secret key、SSL/path style 和预签名有效期。Worker 必须具备下载相同私有对象的权限。

前端接口和字段

场景 前端接入要点
店铺登录限制 PUT /api/admin/shops/:idclient_login_disabled;列表和详情同字段回显,只阻止新登录,不踢出已有 Token
实名策略 卡、设备分别调用 POST /api/admin/iot-cards/batch-update-realname-policyPOST /api/admin/devices/batch-update-realname-policy;最多 500 条、全成全败
C 端资产初始化 使用 effective_realname_policyrealname_requiredrealname_statusallowed_payment_methods,不要在前端重新推断策略
支付方式配置 GET/PUT /api/admin/system-configs 管理 c2b.payment.card_allowed_methodsc2b.payment.device_allowed_methods;至少保留一种
临期资产 GET /api/admin/expiring-assets,使用数量、高亮和优先标识
企微配置 使用应用、成员同步/选择、默认发起人、账号绑定和场景接口;模板节点和审批人规则仍在企微后台维护
退款/充值/换货 展示 submitter_id/submitter_name;退款和充值只读展示企微审批渠道及状态
订单/退款资产 卡展示 ICCID设备优先 VirtualNo、缺失时展示 IMEI订单同时展示 purchase_role
批量订购 上传 purpose=batch_purchase,再调用 POST /api/admin/asset-package-batch-orders;任务列表和详情使用统一状态名称
设备批量分配 上传 purpose=device_batch_allocation,再调用 POST /api/admin/devices/import/allocations;任务查询复用设备导入任务接口并展示 operation_type/operation_name/target_id/status_name
业务导出 POST /api/admin/export-tasks;新增场景为 iot_cardpackageagent_wallet_transactionagent_rechargerefundexchange
卡固定限速 只在卡页面展示固定档位选择;设备页面不得出现限速入口

已知限制

  • 本系统不创建企微模板、不配置审批节点或审批人规则,也不提供扫码绑定。
  • 企微应用只能看到其可见范围内的成员;可见范围或可信 IP 错误会导致连接、绑定或提交失败。
  • 卡限速不保存本地当前档位,结果未知必须人工向 Gateway 核对。
  • CSV 任务逐行部分成功,不保证整批业务原子性;任务详情是失败和跳过原因的权威展示。
  • 店铺登录限制不主动吊销既有 C 端 Token。
  • 测试库此前已完成 000182000194 结构落库和注释核对;000195000196 将在下一次测试环境部署时执行,外部系统闭环和前端浏览器验收尚未完成。

发布和回滚

  1. 发布目标数据库必须执行至 000196,并核对 tb_system_config 已出现 6 个七月迭代默认配置、tb_wecom_application 已使用明文凭据字段;测试环境由 API 容器启动脚本自动迁移。
  2. 先部署数据库兼容代码、API 和 Worker保持旧审批入口开启再配置企微应用、模板、回调和默认发起人。
  3. 真实审批闭环通过后,先隐藏前端旧按钮,再关闭旧入口配置并重启 API。
  4. 回滚时先停止新批量任务和新审批提交,等待已领取任务结束,再回退应用版本。新增表和列暂不删除。
  5. 已产生的审批、退款、钱包流水、订单、通知、Outbox、Integration Log、设备分配和限速审计均为业务事实不得清表回滚使用前向修复。