# feat(agency): 旅行社公司管理新模块 + 产品绑定公司 (定稿) **日期**: 2026-05-06 **通知对象**: @mmg (前端) **关联 PR**: wx/HL #1710 (主) + #1711 (runtime hotfix) + #1712 (gateway 白名单 hotfix) + #1715 (admin path 纠回设计冻结的 travel-agency) **关联工单**: wx/HL #1707 closed **测试服已部署 + round-trip 验证通过**: 2026-05-06 15:13 (旧 path /admin/agency)、2026-05-06 15:39 (新 path /admin/travel-agency, PR #1715 部署完成) --- ## 一、部署状态 (测试服 https://api.test.1814.love:9443) | 接口 | round-trip 验证 | |---|---| | GET /admin/travel-agency/page | ✅ 200 / 3 家明文 | | GET /admin/travel-agency/{id} | ✅ 200 / 完整公司信息 | | GET /admin/travel-agency/enabled | ✅ 200 / 下拉选项 | | GET /admin/travel-agency/{id}/qualification | ✅ 200 / 资质列表 | | GET /admin/travel-agency/{id}/payment | ✅ 200 / 支付配置列表 | | GET /mp/agency/primary | ✅ 200 / 主体公司公开信息(无需登录) | --- ## 二、后端接口 (网关 admin/travel-agency) > ⚠️ **2026-05-06 15:35 更正 (PR #1715)**: 前一版本 changelog 误将 path 标为 `/admin/agency` (副本 A 实施漂移设计文档)。现已纠回设计冻结的 `/admin/travel-agency`,代码 + 网关路由 + 本文档全部对齐。**前端请用 `/admin/travel-agency` 调用**。 ### 1. 主体 CRUD (admin) | Method | Path | 说明 | |--------|------|------| | GET | `/admin/travel-agency/page?pageNum=&pageSize=&code=&agencyName=&status=` | 公司列表(分页) | | GET | `/admin/travel-agency/{id}` | 详情 | | GET | `/admin/travel-agency/enabled` | 启用列表(下拉用, `List<{id,code,agencyName}>`) | | POST | `/admin/travel-agency` | 新建 (SUPER_ADMIN) | | PUT | `/admin/travel-agency/{id}` | 编辑 | | POST | `/admin/travel-agency/{id}/disable` | 停用 (主体不可停, 引用产品也不可) | | POST | `/admin/travel-agency/{id}/set-primary` | 设为主体 (全局唯一 STORED 生成列+UNIQUE 兜底) | | DELETE | `/admin/travel-agency/{id}` | 软删 (SUPER_ADMIN, 主体/有引用拒绝) | ### 2. 资质子表 (admin/agency/{agencyId}/qualification) | Method | Path | 说明 | |--------|------|------| | GET | `/admin/travel-agency/{agencyId}/qualification` | 列表 | | POST | `/admin/travel-agency/{agencyId}/qualification` (multipart) | 上传 (name + file + sortOrder + remark + 可选 issueDate/expireDate) | | PUT | `/admin/travel-agency/{agencyId}/qualification/{id}` | 编辑 | | DELETE | `/admin/travel-agency/{agencyId}/qualification/{id}` | 删除 | - 文件类型白名单: PDF / JPG / PNG / JPEG (后续可加字典 `qualification_file_type`) ### 3. 支付子表 (admin/agency/{agencyId}/payment) | Method | Path | 说明 | |--------|------|------| | GET | `/admin/travel-agency/{agencyId}/payment` | 列表 | | POST | `/admin/travel-agency/{agencyId}/payment` | 新增 (mchId + apiV3Key + mchSerialNo + publicKeyId + isDefault) | | PUT | `/admin/travel-agency/{agencyId}/payment/{paymentId}` | 编辑 (加密字段密文返回, 编辑用 placeholder) | | DELETE | `/admin/travel-agency/{agencyId}/payment/{paymentId}` | 删除 | | POST | `/admin/travel-agency/{agencyId}/payment/{paymentId}/set-default` | 设为默认 mchId | ### 4. mp 端 (无需登录) | Method | Path | 说明 | |--------|------|------| | GET | `/mp/agency/primary` | 主体公司公开信息 (name + 许可证 + 客服电话 + 地址) | --- ## 三、关键业务规则 1. **产品绑定公司 = 绑定商户号** — 用户原话 (2026-05-06): "下单只能是这个商户号了"。创建产品必填 `agencyId`, 下单 `mchId` 永远走 `agency.default.payment.mchId`, `productMchId` 不再被读取。 2. **历史产品默认填主体公司 hulai** — V20260506_001 + V20260506_006 全行回填 (含软删 12371 条)。 3. **主体公司全局唯一** — STORED 生成列 `primary_lock` + UNIQUE 兜底。 4. **加密字段 (apiV3Key/mchSerialNo)** — admin 后台需手动补录, `AgencyDataInitializer` 启动只 UPSERT 主表 + 默认 mchId/cert 路径。 --- ## 四、产品端字段 (前端必改) - `ProductSaveReqVO` 必须传 `agencyId: Long` - `ProductDetailVO` / Resp 增加 `agencyId / mchId` 字段 - 产品编辑页"所属公司"下拉调 `/admin/travel-agency/enabled` - V20260507_001 部署后 `product.agency_id NOT NULL`, 漏传校验失败 --- ## 五、订单端字段 - `OrderInfo` 加 `agencyId Long` (V20260506_006 ALTER) - 订单列表/详情 `mchName` 拼接走 `TravelAgencyService.getById`, 不再读 `OrderHelperService.MCH_NAMES` 静态映射 --- ## 六、UI 建议 (前端自由发挥) **admin 后台**: 顶级菜单 "系统管理 > 旅行社公司管理" - 左列表 + 右编辑面板, Tab 分 基础信息 / 资质附件 / 支付配置 三段 - 主体公司用徽章高亮 (返字段 `isPrimary=1`) - `status=DISABLED` 全局灰显 --- ## 七、curl 验证示例 ```bash # admin 拿 token TOK=$(curl -sk -X POST "https://api.test.1814.love:9443/admin/auth/login" \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"Admin@123456"}' \ | python -c "import json,sys; print(json.load(sys.stdin)['data']['token'])") # 公司列表 curl -sk "https://api.test.1814.love:9443/admin/travel-agency/page?pageNum=1&pageSize=10" \ -H "Authorization: Bearer $TOK" # 主体公司公开信息 (mp 端用, 不需 token) curl -sk "https://api.test.1814.love:9443/mp/agency/primary" ``` --- ## 八、关联文档 - PR #1710 / #1711 / #1712 全 merge dev - 工单 wx/HL #1707 closed (有 closing comment + status/已完成 label) --- cc @mmg