feat(mp-agency): GET /mp/agency/{id} + 全部 mp 公司接口补返 agencyId

- 新增 GET /mp/agency/{id} 按公司 ID 查公开详情(含资质)
- /mp/agency/primary、/mp/common/merchant-qualifications 响应补 agencyId
- 通知 mmg 前端可由 /mp/product/{id}.agencyId 闭环拉公司详情

PR #1761 + #1763
Issue #1759 + #1762
这个提交包含在:
API Changelog Bot 2026-05-06 21:25:52 +08:00
父节点 54a6c45135
当前提交 7e4b6365f1

查看文件

@ -0,0 +1,175 @@
# mp-agency: 新增 GET /mp/agency/{id} + 全部 mp 公司接口补返 agencyId
> **服务**: hl-order-service-v2 (端口 8084) + hl-mp-service (端口 8085)
> **PR**: #1761(GET /mp/agency/{id}) + #1763(VO/DTO 补 agencyId)
> **Issue**: #1759 + #1762
> **日期**: 2026-05-06
> **影响范围**: C 端公司公开信息所有接口(/mp/agency/primary、/mp/agency/{id}、/mp/common/merchant-qualifications)
> **@mmg**
---
## 一、背景
PR #1748(2026-05-06)让 `/mp/product/{id}` 详情接口返出团旅行社公司 ID(`agencyId`/`agencyName`)。前端拿到 agencyId 后需查公司详细信息(营业执照号/统一社会信用代码/客服电话/地址/资质附件)用于产品详情页/合同页/客服联系页展示。
之前只有 `/mp/agency/primary` 一个接口,只能查主体公司,无法支持"按非主体公司 ID 查"。本次新增 `/mp/agency/{id}` 闭环。
同时发现 `/mp/common/merchant-qualifications` 列表只返 code 不返 agencyId,前端拿到列表后无法用 `/mp/agency/{id}` 闭环查详情;`/mp/agency/primary``/mp/agency/{id}` 自己也不返 agencyId 无法做 cache key。**根因**:`MpAgencyRespVO` 评审 PR #1732 时为不暴露主键剔除了 agencyId,但 PR #1748 已让 `/mp/product/{id}` 暴露 agencyId,这条防线已失效。统一让所有 mp 公司接口都带 agencyId。
---
## 二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|------|------|------|----------|------|
| 1 | 按公司ID查公开详情 | GET | `/mp/agency/{id}` | **新增** | 免登录,字段结构 = /primary |
| 2 | 主体公司公开详情 | GET | `/mp/agency/primary` | 响应字段新增 | + `agencyId` |
| 3 | 合作公司公开列表 | GET | `/mp/common/merchant-qualifications` | 响应字段新增 | 每家公司元素 + `agencyId` |
---
## 三、接口详情
### 1. 按公司ID查公开详情 `GET /mp/agency/{id}`(新增)
**VO**: `MpAgencyRespVO`(等同 `/primary`)
#### 入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|------|------|------|------|------|------|
| id | Path | Long | ✅ | - | 公司ID(来自 `/mp/product/{id}` 返的 `agencyId``/mp/common/merchant-qualifications` 列表元素 `agencyId`) |
#### 出参 `Result<MpAgencyRespVO>`
| 字段 | 类型 | 说明 |
|------|------|------|
| agencyId | Long(JSON 序列化为 String 防 JS 精度丢失) | 公司ID |
| code | String | 公司编码 |
| agencyName | String | 公司名称 |
| licenseNumber | String | 旅行社业务经营许可证号 |
| businessLicenseNumber | String | 统一社会信用代码 |
| complaintPhone | String | 客服电话 |
| agencyAddress | String | 公司地址 |
| visible | Integer | 是否在小程序展示(1=展示/0=隐藏) |
| qualifications | List<MpAgencyQualificationVO> | 公开资质列表 |
#### 鉴权
- **免登录**(网关 `/mp/agency/**` 已配 JwtAuthFilter 白名单)
#### 请求示例
```
GET /mp/agency/2051985889785012226
```
#### 响应示例
```json
{
"code": 200,
"message": "成功",
"data": {
"agencyId": "2051985889785012226",
"code": "kj",
"agencyName": "内蒙古呼伦文化科技有限公司",
"licenseNumber": "",
"businessLicenseNumber": "91150702MAK1T8Q0XG",
"complaintPhone": "",
"agencyAddress": "",
"visible": 1,
"qualifications": [
{
"name": "公司科技营业执照",
"qualificationType": "BUSINESS_LICENSE",
"qualificationTypeLabel": "营业执照",
"fileUrl": "https://hlgl-test.oss-cn-beijing.aliyuncs.com/...",
"fileType": "IMAGE",
"fileTypeLabel": "图片",
"issueDate": null,
"expireDate": null
}
]
},
"success": true
}
```
#### 错误响应
```json
{ "code": 594001, "message": "旅行社公司不存在(id=999999999999999999)", "success": false, "data": null }
```
```json
{ "code": 400, "message": "参数类型错误: id='abc'(需要 Long 类型)", "success": false, "data": null }
```
---
### 2. 主体公司公开详情 `GET /mp/agency/primary`(已存在,新增 agencyId 字段)
响应结构完全等同新接口 `/mp/agency/{id}`,字段集相同;`agencyId` 为新增字段。
---
### 3. 合作公司公开列表 `GET /mp/common/merchant-qualifications`(已存在,新增 agencyId 字段)
每个数组元素新增 `agencyId` + `visible` 字段(对齐 RespVO 字段集)。
```json
{
"code": 200,
"data": [
{
"agencyId": "2051985000000000001",
"code": "hulai",
"agencyName": "...",
"qualifications": [...]
}
]
}
```
---
## 四、不影响范围
- **仅影响**: 上述 3 个 mp 公司接口(`/mp/agency/primary``/mp/agency/{id}``/mp/common/merchant-qualifications`)的响应结构(向前兼容: 只新增字段,不删不改)
- **零影响**:
- admin 端 agency 接口(`/admin/agency/**`)结构不变
- 12301 凭据(appId/signKey)、支付配置(mchId/apiV3Key)依然不暴露给前端
- 其他 mp 接口结构不变
---
## 五、测试环境已验证
```
GET /mp/agency/primary → 200 + data.agencyId 非空 ✓
GET /mp/agency/2051985889785012226 → 200 + data.agencyId == path id ✓
GET /mp/agency/999999999999999999 → 200 + code:594001 AGENCY_NOT_FOUND ✓
GET /mp/agency/abc → 200 + code:400 参数类型错 ✓
```
`/mp/common/merchant-qualifications` 因 mp-service 端 `@MpCache` 30 min Redis 缓存,部署完成后**新结构(带 agencyId)在缓存自然过期后(< 30 min)自动生效**,无需重启;前端可在 30 min 后接入或直接以 `/mp/agency/primary` + `/mp/agency/{id}` 闭环
---
## 六、前端建议接入方式
1. 产品详情页:`/mp/product/{id}` 拿到 `agencyId``/mp/agency/{id}` 拉公司详情(显示出团旅行社营业执照、资质附件等)
2. 合同页/协议页落款:沿用 `/mp/agency/primary`(主体公司)
3. 关于我们/合作公司列表:`/mp/common/merchant-qualifications` 列表 → 点击进详情 `/mp/agency/{agencyId}`
---
## 七、相关文档
- Issue #1759: https://git.1814.love:8443/wx/HL/issues/1759
- Issue #1762: https://git.1814.love:8443/wx/HL/issues/1762
- PR #1761: https://git.1814.love:8443/wx/HL/pulls/1761
- PR #1763: https://git.1814.love:8443/wx/HL/pulls/1763
- 上游 PR #1748: `/mp/product/{id}` 补返 agencyId