收口 v3 合同通知文档自检
这个提交包含在:
父节点
01b39a30df
当前提交
1465075091
@ -43,24 +43,28 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
## 3. 通用协议
|
||||
|
||||
- 认证:所有端点都需要管理后台 JWT;旅行社敏感写操作按接口标注需 ADMIN 或 SUPER_ADMIN。
|
||||
- 成功包装:`{"code":200,"data":...,"message":"操作成功","success":true}`,字段名是 `message`,不是 `msg`。
|
||||
- 成功包装:`{
|
||||
"code":200,"data":...,"message":"操作成功","success":true
|
||||
}`,字段名是 `message`,不是 `msg`。
|
||||
- 分页包装:`data.records` / `data.total` / `data.page` / `data.pageSize`。
|
||||
- 失败包装:`{"code":业务错误码,"data":null,"message":"可读提示","success":false}`。
|
||||
- 失败包装:`{
|
||||
"code":业务错误码,"data":null,"message":"可读提示","success":false
|
||||
}`。
|
||||
- 幂等:GET 幂等;PUT 为目标状态更新时可重试;POST 创建/上传不得盲目重试;DELETE 不保证重复调用仍成功。
|
||||
- 金额按 JSON string 消费;雪花 ID 按 string 消费,不得转 JavaScript `Number`。
|
||||
|
||||
## 4. 完整接口清单(56)
|
||||
## 变更接口(完整接口清单,56)
|
||||
|
||||
| Controller | 数量 | 路径域 |
|
||||
|---|---:|---|
|
||||
| AdminContractController | 15 | `/v3/admin/contract` |
|
||||
| AdminContractSchemeController | 7 | `/v3/admin/contract/scheme` |
|
||||
| AdminContractSchemeAttachmentController | 4 | `/v3/admin/contract/scheme/{schemeId}/attachments` |
|
||||
| AdminContractSchemeTourGuideController | 4 | `/v3/admin/contract/scheme/{schemeId}/tour-guides` |
|
||||
| AdminContractSchemeAttachmentController | 4 | `/v3/admin/contract/scheme/<schemeId>/attachments` |
|
||||
| AdminContractSchemeTourGuideController | 4 | `/v3/admin/contract/scheme/<schemeId>/tour-guides` |
|
||||
| AdminClauseTemplateController | 6 | `/v3/admin/contract/clause-template` |
|
||||
| AdminTravelAgencyController | 11 | `/v3/admin/travel-agency` |
|
||||
| AdminTravelAgencyQualificationController | 4 | `/v3/admin/travel-agency/{agencyId}/qualification` |
|
||||
| AdminTravelAgencyPaymentController | 5 | `/v3/admin/travel-agency/{agencyId}/payment` |
|
||||
| AdminTravelAgencyQualificationController | 4 | `/v3/admin/travel-agency/<agencyId>/qualification` |
|
||||
| AdminTravelAgencyPaymentController | 5 | `/v3/admin/travel-agency/<agencyId>/payment` |
|
||||
|
||||
## 5. 接口详情
|
||||
|
||||
@ -70,9 +74,21 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
|
||||
- **场景/协议**:手工填写全量签约数据;`POST /v3/admin/contract/create`;管理员 JWT;非幂等。
|
||||
- **请求体(全部字段)**:`orderId:long?`、`contractType:string?(TOUR/INSURANCE)`、`platform:string?(12301/LOCAL/TENCENT_ESIGN)`、`vendorCode:string?`、`templateCode:string!`、`agencyCode:string?`、`mchId:string?`、`transactorName:string?`、`transactorPhone:string?`、`destination:string!`、`routeName:string!`、`days:int?`、`nights:int?`、`departureDate:date!`、`returnDate:date!`、`departureCity:string?`、`groupId:string?`、`signatoryMode:int?(1..3)`、`signatoryName:string!`、`signatoryPhone:string!`、`signatoryIdType:int?`、`signatoryIdNumber:string!`、`signingPlace:string?`、`adultCost:decimal!`、`childCost:decimal?`、`totalAmount:decimal!`、`paymentMethod:int?(1..3)`、`disputeResolution:int?(1..2)`、`tribunalName:string?`、`litigationCourt:string?`、`contactName:string!`、`contactPhone:string!`、`supplementaryClause:string?`、`travelers:array!`、`accordingContract:boolean?`、`accordingContractPhase:object?`、`contractNum:string?`、`holdNum:string?`、`paymentDescription:string?`、`paymentOther:string?`、`agreeToBuyInsurance:boolean?`、`insuranceCompany:string?`、`insuranceCoverage:string?`、`insurancePremium:string?`、`insuranceProductName:string?`、`insurancePurchaseMethod:int?(1..3)`、`guideServiceCost:decimal?`、`paymentTime:string?`、`startHour:int?(0..23)`、`endHour:int?(0..23)`、`touristCondition:string?`、`schemeId:string?`。`travelers[]`:`name:string!`、`gender:string?(0/1/2)`、`age:int?`、`idCardType:int?(1/2)`、`idCardNo:string!`、`phone:string?`、`isSigner:boolean?`、`isChild:boolean?`、`nationality:string?`、`race:string?`、`roomGroupNo:int?`。
|
||||
- **响应(完整)**:`ContractDetailVO`:`contractId:string, orderId:string, schemeId:string|null, orderNo:string|null, teamNo:string|null, templateCode, templateName, contractNumber, platform, contractType, contractTypeLabel, mode, modeLabel, status, statusLabel, signUrl, qrCodeUrl, fileUrl, agencyCode, travelAgencyName, destination, departureDate, returnDate, totalAmount:string, touristCount:int, contactName, contactPhone, createTime, supplementaryClause, travelers[], statusLogs[]`;`travelers[]={travelerId:string,name,idCardType,idCardTypeLabel,idCardNo,phone,isSigner}`;`statusLogs[]={logId:string,contractId:string,oldStatus,oldStatusLabel,newStatus,newStatusLabel,source,sourceLabel,rawPayload,createTime}`。
|
||||
- **响应(完整)**:`ContractDetailVO`:`contractId:string, orderId:string, schemeId:string|null, orderNo:string|null, teamNo:string|null, templateCode, templateName, contractNumber, platform, contractType, contractTypeLabel, mode, modeLabel, status, statusLabel, signUrl, qrCodeUrl, fileUrl, agencyCode, travelAgencyName, destination, departureDate, returnDate, totalAmount:string, touristCount:int, contactName, contactPhone, createTime, supplementaryClause, travelers[], statusLogs[]`;`travelers[]={
|
||||
travelerId:string,name,idCardType,idCardTypeLabel,idCardNo,phone,isSigner
|
||||
}`;`statusLogs[]={
|
||||
logId:string,contractId:string,oldStatus,oldStatusLabel,newStatus,newStatusLabel,source,sourceLabel,rawPayload,createTime
|
||||
}`。
|
||||
- **边界/错误**:行程未确认 `510220`;已有有效合同 `510214`;模板不存在 `510215`;签署人手机缺失 `510213`;必填/长度/手机格式错误返回参数校验失败。
|
||||
- **典型示例**:请求 `{"orderId":"2079000000000000001","templateCode":"TOURAGE_STANDARD","destination":"呼伦贝尔","routeName":"草原5日","departureDate":"2026-08-10","returnDate":"2026-08-14","signatoryName":"张某","signatoryPhone":"138****8000","signatoryIdNumber":"110101********1234","adultCost":"3000.00","totalAmount":"6000.00","contactName":"张某","contactPhone":"138****8000","travelers":[{"name":"张某","idCardNo":"110101********1234","isSigner":true}]}`;响应 `{"code":200,"data":{"contractId":"2080000000000000001","orderId":"2079000000000000001","status":"GENERATED","totalAmount":"6000.00","travelers":[],"statusLogs":[]},"message":"操作成功","success":true}`。
|
||||
- **典型示例**:请求 `{
|
||||
"orderId":"2079000000000000001","templateCode":"TOURAGE_STANDARD","destination":"呼伦贝尔","routeName":"草原5日","departureDate":"2026-08-10","returnDate":"2026-08-14","signatoryName":"张某","signatoryPhone":"138****8000","signatoryIdNumber":"110101********1234","adultCost":"3000.00","totalAmount":"6000.00","contactName":"张某","contactPhone":"138****8000","travelers":[{
|
||||
"name":"张某","idCardNo":"110101********1234","isSigner":true
|
||||
}]
|
||||
}`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","orderId":"2079000000000000001","status":"GENERATED","totalAmount":"6000.00","travelers":[],"statusLogs":[]
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.2 按方案创建合同
|
||||
|
||||
@ -80,82 +96,140 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
- **入参**:请求体 `orderId:string!`、`schemeId:string!`。
|
||||
- **响应(完整)**:与 5.1.1 的 `ContractDetailVO` 字段完全一致:`contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount,touristCount,contactName,contactPhone,createTime,supplementaryClause,travelers[],statusLogs[]`。
|
||||
- **边界/错误**:方案不存在/已停用 `510205`;方案未配模板 `510206`;订单信息失败 `510207`;行程未确认 `510220`;已有合同 `510214`。
|
||||
- **示例**:请求 `{"orderId":"2079000000000000001","schemeId":"2020001"}`;响应 `{"code":200,"data":{"contractId":"2080000000000000001","orderId":"2079000000000000001","schemeId":"2020001","status":"GENERATED","travelers":[],"statusLogs":[]},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `{
|
||||
"orderId":"2079000000000000001","schemeId":"2020001"
|
||||
}`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","orderId":"2079000000000000001","schemeId":"2020001","status":"GENERATED","travelers":[],"statusLogs":[]
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.3 作废合同
|
||||
|
||||
- **场景/协议**:不可恢复地作废有效合同;`POST /v3/admin/contract/{id}/invalidate`; JWT;重复调用不保证成功。
|
||||
- **场景/协议**:不可恢复地作废有效合同;`POST /v3/admin/contract/<id>/invalidate`; JWT;重复调用不保证成功。
|
||||
- **入参**:路径 `id:string!` 合同 ID;无请求体。
|
||||
- **响应(完整)**:`ContractVO={contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount:string,touristCount,contactName,contactPhone,createTime}`。
|
||||
- **响应(完整)**:`ContractVO={
|
||||
contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount:string,touristCount,contactName,contactPhone,createTime
|
||||
}`。
|
||||
- **边界/错误**:合同不存在 `510001`;缺合同编号 `510003`;上游作废失败 `510104`。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000001/invalidate` 无 body;响应 `{"code":200,"data":{"contractId":"2080000000000000001","status":"VOIDED","statusLabel":"已作废"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000001/invalidate` 无 body;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","status":"VOIDED","statusLabel":"已作废"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.4 合同列表(本 PR 修改)
|
||||
|
||||
- **场景/协议**:合同管理分页列表;`GET /v3/admin/contract/list`; JWT;幂等。
|
||||
- **Query(全部)**:`page:int?=1`、`pageSize:int?=10`、`orderId:string?`、`status:string?`、`platform:string?`、`orderNo:string?`、`teamNo:string?`、`contactName:string?`。三个文本条件都 trim;全空白忽略;`%` / `_` / `\` 字面匹配;条件间 AND。
|
||||
- **响应(完整)**:`PageResult.records[]` 每项为 `ContractVO={contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount:string,touristCount,contactName,contactPhone,createTime}`;顶层 `total:long,page:int,pageSize:int`。
|
||||
- **响应(完整)**:`PageResult.records[]` 每项为 `ContractVO={
|
||||
contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount:string,touristCount,contactName,contactPhone,createTime
|
||||
}`;顶层 `total:long,page:int,pageSize:int`。
|
||||
- **边界**:`orderNo=%` 只匹配订单号中真实的 `%`,不会全表命中;`orderNo= ` 等价于未传;无结果返回空 `records`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/list?page=1&pageSize=10&orderNo=HL2026&teamNo=26-08`;响应 `{"code":200,"data":{"records":[{"contractId":"2080000000000000001","orderId":"2079000000000000001","orderNo":"HL202608040001","teamNo":"26-0804","status":"SIGNED","totalAmount":"6000.00"}],"total":1,"page":1,"pageSize":10},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/list?page=1&pageSize=10&orderNo=HL2026&teamNo=26-08`;响应 `{
|
||||
"code":200,"data":{
|
||||
"records":[{
|
||||
"contractId":"2080000000000000001","orderId":"2079000000000000001","orderNo":"HL202608040001","teamNo":"26-0804","status":"SIGNED","totalAmount":"6000.00"
|
||||
}],"total":1,"page":1,"pageSize":10
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.5 合同详情
|
||||
|
||||
- **场景/协议**:查看合同、出行人和状态日志;`GET /v3/admin/contract/{id}`; JWT;幂等。
|
||||
- **场景/协议**:查看合同、出行人和状态日志;`GET /v3/admin/contract/<id>`; JWT;幂等。
|
||||
- **入参**:路径 `id:string!`。
|
||||
- **响应(完整)**:`ContractDetailVO`全字段:`contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount,touristCount,contactName,contactPhone,createTime,supplementaryClause,travelers[{travelerId,name,idCardType,idCardTypeLabel,idCardNo,phone,isSigner}],statusLogs[{logId,contractId,oldStatus,oldStatusLabel,newStatus,newStatusLabel,source,sourceLabel,rawPayload,createTime}]`。
|
||||
- **错误/示例**:不存在 `510001`。请求 `GET /v3/admin/contract/2080000000000000001`;响应 `{"code":200,"data":{"contractId":"2080000000000000001","orderId":"2079000000000000001","teamNo":"26-0804","totalAmount":"6000.00","travelers":[{"travelerId":"2081000000000000001","name":"张某"}],"statusLogs":[]},"message":"操作成功","success":true}`。
|
||||
- **响应(完整)**:`ContractDetailVO`全字段:`contractId,orderId,schemeId,orderNo,teamNo,templateCode,templateName,contractNumber,platform,contractType,contractTypeLabel,mode,modeLabel,status,statusLabel,signUrl,qrCodeUrl,fileUrl,agencyCode,travelAgencyName,destination,departureDate,returnDate,totalAmount,touristCount,contactName,contactPhone,createTime,supplementaryClause,travelers[{
|
||||
travelerId,name,idCardType,idCardTypeLabel,idCardNo,phone,isSigner
|
||||
}],statusLogs[{
|
||||
logId,contractId,oldStatus,oldStatusLabel,newStatus,newStatusLabel,source,sourceLabel,rawPayload,createTime
|
||||
}]`。
|
||||
- **错误/示例**:不存在 `510001`。请求 `GET /v3/admin/contract/2080000000000000001`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","orderId":"2079000000000000001","teamNo":"26-0804","totalAmount":"6000.00","travelers":[{
|
||||
"travelerId":"2081000000000000001","name":"张某"
|
||||
}],"statusLogs":[]
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.6 下载合同文件
|
||||
|
||||
- **场景/协议**:取得已签署/已上报合同下载 URL;`GET /v3/admin/contract/{id}/download`; JWT;幂等。
|
||||
- **场景/协议**:取得已签署/已上报合同下载 URL;`GET /v3/admin/contract/<id>/download`; JWT;幂等。
|
||||
- **入参/响应**:路径 `id:string!`;`data:string` 为下载 URL,无其他 data 字段。
|
||||
- **错误/边界**:`510001` 不存在;`510101` 未签署完成;`510102` 文件 URL 缺失。
|
||||
- **示例**:请求 `GET /v3/admin/contract/2080000000000000001/download`;响应 `{"code":200,"data":"https://example.invalid/signed/contract.pdf?token=masked","message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/2080000000000000001/download`;响应 `{
|
||||
"code":200,"data":"https://example.invalid/signed/contract.pdf?token=masked","message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.7 重发签署短信
|
||||
|
||||
- **场景/协议**:为未完成签署的合同重发短信;`POST /v3/admin/contract/{id}/resend-sms`; JWT;有 1 分钟频控,不可并发重试。
|
||||
- **场景/协议**:为未完成签署的合同重发短信;`POST /v3/admin/contract/<id>/resend-sms`; JWT;有 1 分钟频控,不可并发重试。
|
||||
- **入参/响应**:路径 `id:string!`;`data:boolean`。
|
||||
- **错误/边界**:`510001`、`510005` 已签署、`510006` 过于频繁、`510007` 合同编号缺失、`510008` 联系人手机缺失。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000001/resend-sms` 无 body;响应 `{"code":200,"data":true,"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000001/resend-sms` 无 body;响应 `{
|
||||
"code":200,"data":true,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.8 合同模板列表
|
||||
|
||||
- **场景/协议**:创建合同时选择平台模板;`GET /v3/admin/contract/templates`; JWT;幂等。
|
||||
- **Query**:`platform:string?` (`12301` 等)。
|
||||
- **响应(完整)**:`data[]` 每项 `templateId:string,templateCode:string,templateName:string,platform:string,mode:string,status:string,description:string|null,createTime:datetime`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/templates?platform=12301`;响应 `{"code":200,"data":[{"templateId":"101","templateCode":"TOURAGE_STANDARD","templateName":"标准旅游合同","platform":"12301","mode":"STANDARD","status":"ACTIVE","description":null,"createTime":"2026-08-01T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/templates?platform=12301`;响应 `{
|
||||
"code":200,"data":[{
|
||||
"templateId":"101","templateCode":"TOURAGE_STANDARD","templateName":"标准旅游合同","platform":"12301","mode":"STANDARD","status":"ACTIVE","description":null,"createTime":"2026-08-01T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.9 刷新合同状态
|
||||
|
||||
- **场景/协议**:主动从合同平台同步最新状态;`GET /v3/admin/contract/{id}/status`; JWT;查询可重试,但可产生状态更新。
|
||||
- **场景/协议**:主动从合同平台同步最新状态;`GET /v3/admin/contract/<id>/status`; JWT;查询可重试,但可产生状态更新。
|
||||
- **入参/响应**:路径 `id:string!`;`ContractVO`完整字段同 5.1.3。
|
||||
- **错误/示例**:`510001`;`510103` 缺合同编号。请求 `GET /v3/admin/contract/2080000000000000001/status`;响应 `{"code":200,"data":{"contractId":"2080000000000000001","status":"SIGNED","statusLabel":"已签署"},"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:`510001`;`510103` 缺合同编号。请求 `GET /v3/admin/contract/2080000000000000001/status`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","status":"SIGNED","statusLabel":"已签署"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.10 按订单查询全部合同
|
||||
|
||||
- **场景/协议**:查询订单下包含已作废数据的全部合同;`GET /v3/admin/contract/by-order/{orderId}`; JWT;幂等。
|
||||
- **场景/协议**:查询订单下包含已作废数据的全部合同;`GET /v3/admin/contract/by-order/<orderId>`; JWT;幂等。
|
||||
- **入参/响应**:`orderId:string!`;`data[]` 每项为 5.1.3 的完整 `ContractVO`。无记录返回 `[]`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/by-order/2079000000000000001`;响应 `{"code":200,"data":[{"contractId":"2080000000000000001","orderId":"2079000000000000001","status":"SIGNED","totalAmount":"6000.00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/by-order/2079000000000000001`;响应 `{
|
||||
"code":200,"data":[{
|
||||
"contractId":"2080000000000000001","orderId":"2079000000000000001","status":"SIGNED","totalAmount":"6000.00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.11 获取订单有效合同
|
||||
|
||||
- **场景/协议**:取指定订单最新非作废合同;`GET /v3/admin/contract/active-by-order/{orderId}`; JWT;幂等。
|
||||
- **场景/协议**:取指定订单最新非作废合同;`GET /v3/admin/contract/active-by-order/<orderId>`; JWT;幂等。
|
||||
- **入参/响应**:`orderId:string!`;`data` 为 5.1.3 的完整 `ContractVO`,没有有效合同时可为 `null`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/active-by-order/2079000000000000001`;响应 `{"code":200,"data":{"contractId":"2080000000000000001","status":"SIGNED","totalAmount":"6000.00"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/active-by-order/2079000000000000001`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000001","status":"SIGNED","totalAmount":"6000.00"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.12 可用合同平台列表
|
||||
|
||||
- **场景/协议**:展示已注册平台及可用性;`GET /v3/admin/contract/platforms`; JWT;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项 `platformName:string,displayName:string,available:boolean`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/platforms`;响应 `{"code":200,"data":[{"platformName":"12301","displayName":"12301团队报送","available":true}],"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/platforms`;响应 `{
|
||||
"code":200,"data":[{
|
||||
"platformName":"12301","displayName":"12301团队报送","available":true
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.13 已配置旅行社列表
|
||||
|
||||
- **场景/协议**:按平台筛选可用旅行社;`GET /v3/admin/contract/agencies`; JWT;幂等。
|
||||
- **Query**:`platform:string?`。
|
||||
- **响应(完整)**:`data[]` 每项 `code,agencyName,licenseNumber,businessLicenseNumber,agencyAddress,agencyCountry,agencyState,agencyCity,agencyDistrict,transactorName,transactorPhone,regionId,businessScope,zjParentId,appId,signKey,teamReportAppId,teamReportSignKey,mchId,complaintPhone,email,supportedPlatforms[],bankCard,complaintProvince,complaintCity,complaintAreaCode,complaintAddress,tribunalName,litigationCourt`。注意其中存在高敏配置,仅在授权后台使用,不得写日志/埋点。
|
||||
- **示例**:请求 `GET /v3/admin/contract/agencies?platform=12301`;响应 `{"code":200,"data":[{"code":"hulai","agencyName":"呼籁旅行社","licenseNumber":"L-XX-100001","supportedPlatforms":["12301"],"appId":"***","signKey":"***"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `GET /v3/admin/contract/agencies?platform=12301`;响应 `{
|
||||
"code":200,"data":[{
|
||||
"code":"hulai","agencyName":"呼籁旅行社","licenseNumber":"L-XX-100001","supportedPlatforms":["12301"],"appId":"***","signKey":"***"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.14 报备合同(线下签约)
|
||||
|
||||
@ -163,15 +237,23 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
- **请求体**:字段、必填性与校验完全同 5.1.1 `CreateContractRequest`。
|
||||
- **响应(完整)**:与 5.1.1 `ContractDetailVO` 完全一致。
|
||||
- **错误/边界**:参数校验;未知旅行社 `510201`;上报失败 `510203`;腾讯电子签不支持 SYNC `510403`。
|
||||
- **示例**:请求同 5.1.1,`platform=12301`;响应 `{"code":200,"data":{"contractId":"2080000000000000002","mode":"SYNC","status":"REPORTED","travelers":[],"statusLogs":[]},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求同 5.1.1,`platform=12301`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000002","mode":"SYNC","status":"REPORTED","travelers":[],"statusLogs":[]
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.1.15 上传已签署合同 PDF
|
||||
|
||||
- **场景/协议**:仅 SYNC 合同上传签署后 PDF;`POST /v3/admin/contract/{id}/upload-pdf`; JWT;非幂等。
|
||||
- **场景/协议**:仅 SYNC 合同上传签署后 PDF;`POST /v3/admin/contract/<id>/upload-pdf`; JWT;非幂等。
|
||||
- **入参**:路径 `id:string!`;`multipart/form-data` 中 `file:file!`。
|
||||
- **响应(完整)**:5.1.3 的完整 `ContractVO`。
|
||||
- **错误/边界**:`510001`、`510105` 缺合同编号、`510106` 当前状态不允许、`510107` 上传失败;ONLINE/STANDARD 合同不适用。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000002/upload-pdf` + `file=@signed-contract.pdf`;响应 `{"code":200,"data":{"contractId":"2080000000000000002","mode":"SYNC","status":"UPLOADED","fileUrl":"https://example.invalid/signed.pdf"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `POST /v3/admin/contract/2080000000000000002/upload-pdf` + `file=@signed-contract.pdf`;响应 `{
|
||||
"code":200,"data":{
|
||||
"contractId":"2080000000000000002","mode":"SYNC","status":"UPLOADED","fileUrl":"https://example.invalid/signed.pdf"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.2 AdminContractSchemeController(7)
|
||||
|
||||
@ -181,46 +263,78 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
|
||||
- `GET /v3/admin/contract/scheme/list`;产品/合同方案下拉;JWT;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项包含上述 `ContractSchemeVO` 全部 19 字段,仅返回 `status=ACTIVE`。
|
||||
- **示例**:`GET .../list` → `{"code":200,"data":[{"schemeId":"2020001","name":"标准方案","contractPlatform":"12301","contractMode":"STANDARD","status":"ACTIVE"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../list` → `{
|
||||
"code":200,"data":[{
|
||||
"schemeId":"2020001","name":"标准方案","contractPlatform":"12301","contractMode":"STANDARD","status":"ACTIVE"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.2 全部方案列表
|
||||
|
||||
- `GET /v3/admin/contract/scheme/list-all`;方案管理页;JWT;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项包含 `ContractSchemeVO` 全部 19 字段,包含 ACTIVE/INACTIVE。
|
||||
- **示例**:`GET .../list-all` → `{"code":200,"data":[{"schemeId":"2020001","name":"标准方案","status":"ACTIVE"},{"schemeId":"2020002","name":"旧方案","status":"INACTIVE"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../list-all` → `{
|
||||
"code":200,"data":[{
|
||||
"schemeId":"2020001","name":"标准方案","status":"ACTIVE"
|
||||
},{
|
||||
"schemeId":"2020002","name":"旧方案","status":"INACTIVE"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.3 方案详情
|
||||
|
||||
- `GET /v3/admin/contract/scheme/{schemeId}`;编辑回显;JWT;幂等;路径 `schemeId:string!`。
|
||||
- `GET /v3/admin/contract/scheme/<schemeId>`;编辑回显;JWT;幂等;路径 `schemeId:string!`。
|
||||
- **响应(完整)**:`ContractSchemeVO` 全部 19 字段。不存在返回 `510209`。
|
||||
- **示例**:`GET .../2020001` → `{"code":200,"data":{"schemeId":"2020001","name":"标准方案","contractPlatform":"12301","contractTemplateCode":"A00001","templateCode":"A00001","status":"ACTIVE"},"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../2020001` → `{
|
||||
"code":200,"data":{
|
||||
"schemeId":"2020001","name":"标准方案","contractPlatform":"12301","contractTemplateCode":"A00001","templateCode":"A00001","status":"ACTIVE"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.4 创建方案
|
||||
|
||||
- `POST /v3/admin/contract/scheme`;新增平台/模板/签约模式配置;JWT;非幂等。
|
||||
- **请求体**:上述 `ContractSchemeRequest` 全部 13 字段。**响应**:上述 `ContractSchemeVO` 全部 19 字段。
|
||||
- **边界/错误**:`name` 必填;手机/长度/签署模式校验;未知旅行社 `510201`。
|
||||
- **示例**:请求 `{"name":"标准方案","contractPlatform":"12301","contractTemplateCode":"A00001","contractMode":"STANDARD","signatoryMode":1,"agencyCode":"hulai","sortOrder":10}`;响应 `{"code":200,"data":{"schemeId":"2020001","name":"标准方案","status":"ACTIVE"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `{
|
||||
"name":"标准方案","contractPlatform":"12301","contractTemplateCode":"A00001","contractMode":"STANDARD","signatoryMode":1,"agencyCode":"hulai","sortOrder":10
|
||||
}`;响应 `{
|
||||
"code":200,"data":{
|
||||
"schemeId":"2020001","name":"标准方案","status":"ACTIVE"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.5 更新方案
|
||||
|
||||
- `PUT /v3/admin/contract/scheme/{schemeId}`;编辑方案;JWT;目标更新可重试。
|
||||
- `PUT /v3/admin/contract/scheme/<schemeId>`;编辑方案;JWT;目标更新可重试。
|
||||
- **入参**:路径 `schemeId:string!` + `ContractSchemeRequest` 全部字段。**响应**:`ContractSchemeVO` 全部字段。
|
||||
- **边界/错误**:已用方案创建的合同不受后续修改影响;不存在 `510209`。
|
||||
- **示例**:请求 `PUT .../2020001` + `{"name":"标准方案V2","contractPlatform":"12301","contractMode":"STANDARD"}`;响应 `{"code":200,"data":{"schemeId":"2020001","name":"标准方案V2","status":"ACTIVE"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `PUT .../2020001` + `{
|
||||
"name":"标准方案V2","contractPlatform":"12301","contractMode":"STANDARD"
|
||||
}`;响应 `{
|
||||
"code":200,"data":{
|
||||
"schemeId":"2020001","name":"标准方案V2","status":"ACTIVE"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.6 切换启停状态
|
||||
|
||||
- `PUT /v3/admin/contract/scheme/{schemeId}/toggle-status`;启用/停用方案;JWT;每次翻转,非幂等。
|
||||
- `PUT /v3/admin/contract/scheme/<schemeId>/toggle-status`;启用/停用方案;JWT;每次翻转,非幂等。
|
||||
- **入参**:`schemeId:string!`;无 body。**响应**:`ContractSchemeVO` 全部字段。不存在 `510209`。
|
||||
- **示例**:`PUT .../2020001/toggle-status` → `{"code":200,"data":{"schemeId":"2020001","status":"INACTIVE"},"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../2020001/toggle-status` → `{
|
||||
"code":200,"data":{
|
||||
"schemeId":"2020001","status":"INACTIVE"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.2.7 删除方案
|
||||
|
||||
- `DELETE /v3/admin/contract/scheme/{schemeId}`;软删除;JWT;不保证重复调用成功。
|
||||
- `DELETE /v3/admin/contract/scheme/<schemeId>`;软删除;JWT;不保证重复调用成功。
|
||||
- **入参/响应**:`schemeId:string!`;成功 `data:null`,无其他响应字段。
|
||||
- **错误/边界**:不存在 `510209`;被产品引用 `510218`;引用校验不可用 `510219`。
|
||||
- **示例**:`DELETE .../2020001` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../2020001` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.3 AdminContractSchemeAttachmentController(4)
|
||||
|
||||
@ -228,100 +342,168 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
|
||||
#### 5.3.1 附件列表
|
||||
|
||||
- `GET /v3/admin/contract/scheme/{schemeId}/attachments`;按 `sortOrder` 升序回显;JWT;幂等;`schemeId:string!`。
|
||||
- `GET /v3/admin/contract/scheme/<schemeId>/attachments`;按 `sortOrder` 升序回显;JWT;幂等;`schemeId:string!`。
|
||||
- **响应(完整)**:`data[]` 每项含 `AttachmentResp` 全部 9 字段;无配置返回 `[]`。
|
||||
- **示例**:`GET .../2020001/attachments` → `{"code":200,"data":[{"attachmentId":"1010001","schemeId":"2020001","fileName":"service.pdf","ossUrl":"https://example.invalid/a.pdf","ossKey":"contract/a.pdf","fileSize":1024,"fileType":"PDF","sortOrder":10,"createTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../2020001/attachments` → `{
|
||||
"code":200,"data":[{
|
||||
"attachmentId":"1010001","schemeId":"2020001","fileName":"service.pdf","ossUrl":"https://example.invalid/a.pdf","ossKey":"contract/a.pdf","fileSize":1024,"fileType":"PDF","sortOrder":10,"createTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.3.2 上传附件
|
||||
|
||||
- `POST /v3/admin/contract/scheme/{schemeId}/attachments`;上传合同方案附件;JWT;非幂等。
|
||||
- `POST /v3/admin/contract/scheme/<schemeId>/attachments`;上传合同方案附件;JWT;非幂等。
|
||||
- **入参**:`schemeId:string!`;multipart `file:file!`、`fileType:string?(PDF/IMAGE/OTHER)`、`sortOrder:int?`。**响应**:`AttachmentResp` 全部 9 字段。
|
||||
- **错误/边界**:空文件、超限、OSS 不可用或上传失败都返回 `510508`。
|
||||
- **示例**:`POST .../2020001/attachments` + `file=@service.pdf&fileType=PDF&sortOrder=10` → `{"code":200,"data":{"attachmentId":"1010001","schemeId":"2020001","fileType":"PDF","sortOrder":10},"message":"操作成功","success":true}`。
|
||||
- **示例**:`POST .../2020001/attachments` + `file=@service.pdf&fileType=PDF&sortOrder=10` → `{
|
||||
"code":200,"data":{
|
||||
"attachmentId":"1010001","schemeId":"2020001","fileType":"PDF","sortOrder":10
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.3.3 删除附件
|
||||
|
||||
- `DELETE /v3/admin/contract/scheme/{schemeId}/attachments/{attachmentId}`;软删;JWT;路径 `schemeId:string!`,`attachmentId:string!`;无 body。
|
||||
- `DELETE /v3/admin/contract/scheme/<schemeId>/attachments/<attachmentId>`;软删;JWT;路径 `schemeId:string!`,`attachmentId:string!`;无 body。
|
||||
- **响应/错误**:成功 `data:null`;附件不存在或不属于该方案 `510506`。已生成合同的旧 URL 不受影响。
|
||||
- **示例**:`DELETE .../2020001/attachments/1010001` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../2020001/attachments/1010001` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.3.4 更新附件排序
|
||||
|
||||
- `PUT /v3/admin/contract/scheme/{schemeId}/attachments/{attachmentId}/sort`;JWT;目标更新可重试。
|
||||
- `PUT /v3/admin/contract/scheme/<schemeId>/attachments/<attachmentId>/sort`;JWT;目标更新可重试。
|
||||
- **入参**:路径 `schemeId:string!`,`attachmentId:string!`;body `sortOrder:int!(>=0)`。**响应**:`data:null`。
|
||||
- **错误/示例**:不存在 `510506`;负数为参数校验失败。请求 `{"sortOrder":20}` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在 `510506`;负数为参数校验失败。请求 `{
|
||||
"sortOrder":20
|
||||
}` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.4 AdminContractSchemeTourGuideController(4)
|
||||
|
||||
`GuideResp={guideId:string,schemeId:string,name:string,phone:string|null,licenseNumber:string|null,sortOrder:int,createTime:datetime}`;`GuideSave={name:string!(max50),phone:string?(11位手机,max20),licenseNumber:string?(max64),sortOrder:int?(>=0)}`。
|
||||
`GuideResp={
|
||||
guideId:string,schemeId:string,name:string,phone:string|null,licenseNumber:string|null,sortOrder:int,createTime:datetime
|
||||
}`;`GuideSave={
|
||||
name:string!(max50),phone:string?(11位手机,max20),licenseNumber:string?(max64),sortOrder:int?(>=0)
|
||||
}`。
|
||||
|
||||
#### 5.4.1 导游列表
|
||||
|
||||
- `GET /v3/admin/contract/scheme/{schemeId}/tour-guides`;JWT;幂等;`schemeId:string!`;未配导游返回 `[]`,不兜底。
|
||||
- `GET /v3/admin/contract/scheme/<schemeId>/tour-guides`;JWT;幂等;`schemeId:string!`;未配导游返回 `[]`,不兜底。
|
||||
- **响应(完整)**:`data[]` 每项含 `GuideResp` 全部 7 字段。
|
||||
- **示例**:`GET .../2020001/tour-guides` → `{"code":200,"data":[{"guideId":"3030001","schemeId":"2020001","name":"张某","phone":"138****8000","licenseNumber":"L-XX-100001","sortOrder":0,"createTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../2020001/tour-guides` → `{
|
||||
"code":200,"data":[{
|
||||
"guideId":"3030001","schemeId":"2020001","name":"张某","phone":"138****8000","licenseNumber":"L-XX-100001","sortOrder":0,"createTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.4.2 新增导游
|
||||
|
||||
- `POST /v3/admin/contract/scheme/{schemeId}/tour-guides`;JWT;创建加锁,非幂等。
|
||||
- `POST /v3/admin/contract/scheme/<schemeId>/tour-guides`;JWT;创建加锁,非幂等。
|
||||
- **入参**:`schemeId:string!` + `GuideSave` 全部 4 字段。**响应**:`GuideResp` 全部 7 字段。
|
||||
- **边界/示例**:姓名必填;手机格式错误拒绝。请求 `{"name":"张某","phone":"13800138000","licenseNumber":"L-XX-100001","sortOrder":0}` → `{"code":200,"data":{"guideId":"3030001","schemeId":"2020001","name":"张某","phone":"13800138000","licenseNumber":"L-XX-100001","sortOrder":0,"createTime":"2026-08-04T10:00:00"},"message":"操作成功","success":true}`。
|
||||
- **边界/示例**:姓名必填;手机格式错误拒绝。请求 `{
|
||||
"name":"张某","phone":"13800138000","licenseNumber":"L-XX-100001","sortOrder":0
|
||||
}` → `{
|
||||
"code":200,"data":{
|
||||
"guideId":"3030001","schemeId":"2020001","name":"张某","phone":"13800138000","licenseNumber":"L-XX-100001","sortOrder":0,"createTime":"2026-08-04T10:00:00"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.4.3 修改导游
|
||||
|
||||
- `PUT /v3/admin/contract/scheme/{schemeId}/tour-guides/{guideId}`;JWT;目标更新可重试。
|
||||
- `PUT /v3/admin/contract/scheme/<schemeId>/tour-guides/<guideId>`;JWT;目标更新可重试。
|
||||
- **入参**:`schemeId:string!`,`guideId:string!` + `GuideSave` 全部字段。**响应**:`GuideResp` 全部字段。
|
||||
- **错误/示例**:不存在/归属不符 `510507`。请求 `{"name":"李某","sortOrder":1}` → `{"code":200,"data":{"guideId":"3030001","schemeId":"2020001","name":"李某","sortOrder":1},"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在/归属不符 `510507`。请求 `{
|
||||
"name":"李某","sortOrder":1
|
||||
}` → `{
|
||||
"code":200,"data":{
|
||||
"guideId":"3030001","schemeId":"2020001","name":"李某","sortOrder":1
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.4.4 删除导游
|
||||
|
||||
- `DELETE /v3/admin/contract/scheme/{schemeId}/tour-guides/{guideId}`;JWT;不保证重复调用成功。
|
||||
- `DELETE /v3/admin/contract/scheme/<schemeId>/tour-guides/<guideId>`;JWT;不保证重复调用成功。
|
||||
- **入参/响应**:`schemeId:string!`,`guideId:string!`;成功 `data:null`。不存在/归属不符 `510507`。
|
||||
- **示例**:`DELETE .../2020001/tour-guides/3030001` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../2020001/tour-guides/3030001` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.5 AdminClauseTemplateController(6)
|
||||
|
||||
`ClauseTemplateVO={templateId:string,name:string,content:string,sortOrder:int,status:string,createTime:datetime}`;`ClauseTemplateRequest={name:string!,content:string!,sortOrder:int?}`。
|
||||
`ClauseTemplateVO={
|
||||
templateId:string,name:string,content:string,sortOrder:int,status:string,createTime:datetime
|
||||
}`;`ClauseTemplateRequest={
|
||||
name:string!,content:string!,sortOrder:int?
|
||||
}`。
|
||||
|
||||
#### 5.5.1 启用模板列表
|
||||
|
||||
- `GET /v3/admin/contract/clause-template/list`;创建合同时选择;JWT;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项含 `ClauseTemplateVO` 全部 6 字段,仅 ACTIVE。
|
||||
- **示例**:`GET .../list` → `{"code":200,"data":[{"templateId":"401","name":"夏季小团","content":"脱敏示例条款","sortOrder":1,"status":"ACTIVE","createTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../list` → `{
|
||||
"code":200,"data":[{
|
||||
"templateId":"401","name":"夏季小团","content":"脱敏示例条款","sortOrder":1,"status":"ACTIVE","createTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.5.2 全部模板列表
|
||||
|
||||
- `GET /v3/admin/contract/clause-template/list-all`;模板管理页;JWT;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项含 `ClauseTemplateVO` 全部 6 字段,包含 ACTIVE/INACTIVE。
|
||||
- **示例**:`GET .../list-all` → `{"code":200,"data":[{"templateId":"401","name":"夏季小团","content":"条款","sortOrder":1,"status":"INACTIVE","createTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../list-all` → `{
|
||||
"code":200,"data":[{
|
||||
"templateId":"401","name":"夏季小团","content":"条款","sortOrder":1,"status":"INACTIVE","createTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.5.3 创建补充约定模板
|
||||
|
||||
- `POST /v3/admin/contract/clause-template`;JWT;非幂等。
|
||||
- **请求/响应**:body `ClauseTemplateRequest` 全部 3 字段;返回 `ClauseTemplateVO` 全部 6 字段。名称和内容必填。
|
||||
- **示例**:请求 `{"name":"夏季小团","content":"脱敏示例条款","sortOrder":1}` → `{"code":200,"data":{"templateId":"401","name":"夏季小团","content":"脱敏示例条款","sortOrder":1,"status":"ACTIVE","createTime":"2026-08-04T10:00:00"},"message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `{
|
||||
"name":"夏季小团","content":"脱敏示例条款","sortOrder":1
|
||||
}` → `{
|
||||
"code":200,"data":{
|
||||
"templateId":"401","name":"夏季小团","content":"脱敏示例条款","sortOrder":1,"status":"ACTIVE","createTime":"2026-08-04T10:00:00"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.5.4 更新补充约定模板
|
||||
|
||||
- `PUT /v3/admin/contract/clause-template/{id}`;JWT;可重试。
|
||||
- `PUT /v3/admin/contract/clause-template/<id>`;JWT;可重试。
|
||||
- **入参/响应**:`id:string!` + `ClauseTemplateRequest` 全部字段;返回 `ClauseTemplateVO` 全部字段。旧合同快照不受影响。
|
||||
- **错误/示例**:不存在 `510211`。请求 `{"name":"夏季小团V2","content":"新条款","sortOrder":2}` → `{"code":200,"data":{"templateId":"401","name":"夏季小团V2","content":"新条款","sortOrder":2,"status":"ACTIVE"},"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在 `510211`。请求 `{
|
||||
"name":"夏季小团V2","content":"新条款","sortOrder":2
|
||||
}` → `{
|
||||
"code":200,"data":{
|
||||
"templateId":"401","name":"夏季小团V2","content":"新条款","sortOrder":2,"status":"ACTIVE"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.5.5 切换模板启停
|
||||
|
||||
- `PUT /v3/admin/contract/clause-template/{id}/toggle-status`;JWT;每次翻转,非幂等。
|
||||
- `PUT /v3/admin/contract/clause-template/<id>/toggle-status`;JWT;每次翻转,非幂等。
|
||||
- **入参/响应**:`id:string!`;无 body;返回 `ClauseTemplateVO` 全部 6 字段。不存在 `510211`。
|
||||
- **示例**:`PUT .../401/toggle-status` → `{"code":200,"data":{"templateId":"401","name":"夏季小团","content":"条款","sortOrder":1,"status":"INACTIVE","createTime":"2026-08-04T10:00:00"},"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../401/toggle-status` → `{
|
||||
"code":200,"data":{
|
||||
"templateId":"401","name":"夏季小团","content":"条款","sortOrder":1,"status":"INACTIVE","createTime":"2026-08-04T10:00:00"
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.5.6 删除补充约定模板
|
||||
|
||||
- `DELETE /v3/admin/contract/clause-template/{id}`;JWT;软删;重复调用不保证成功。
|
||||
- `DELETE /v3/admin/contract/clause-template/<id>`;JWT;软删;重复调用不保证成功。
|
||||
- **入参/响应**:`id:string!`;成功 `data:null`。已创建合同保留快照。不存在 `510211`。
|
||||
- **示例**:`DELETE .../401` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../401` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.6 AdminTravelAgencyController(11)
|
||||
|
||||
`AgencySimpleResp={agencyId:string,code,agencyName,isPrimary:int,sortOrder:int,createTime,updateTime}`。
|
||||
`AgencySimpleResp={
|
||||
agencyId:string,code,agencyName,isPrimary:int,sortOrder:int,createTime,updateTime
|
||||
}`。
|
||||
|
||||
`AgencyResp` 完整字段:`agencyId:string,code,agencyName,licenseNumber,businessLicenseNumber,agencyCountry,agencyState,agencyCity,agencyDistrict,agencyAddress,transactorName,transactorPhone,email,bankCard,complaintPhone,complaintProvince,complaintCity,complaintAreaCode,complaintAddress,tribunalName,litigationCourt,regionId,businessScope,zjParentId,appId,signKey,teamReportAppId,teamReportSignKey,supportedPlatforms,supportedPlatformsList[],supportedPlatformsLabels[],isPrimary,status,statusLabel,sortOrder,visible,remark,qualifications[],payments[],createTime,updateTime`。
|
||||
`AgencySave` 完整字段:`code:string!(2..32,小写字母/数字/-),agencyName:string!(max128),licenseNumber:string?(max64),businessLicenseNumber:string!,agencyCountry,agencyState,agencyCity,agencyDistrict,agencyAddress,transactorName,transactorPhone,email,bankCard,complaintPhone,complaintProvince,complaintCity,complaintAreaCode,complaintAddress,tribunalName,litigationCourt,regionId,businessScope,zjParentId:int?,appId,signKey,teamReportAppId,teamReportSignKey,supportedPlatforms:string(JSON array),isPrimary:int?(0/1),status:string?,sortOrder:int?,visible:int?(0/1),remark`。
|
||||
@ -331,137 +513,213 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
- `GET /v3/admin/travel-agency/page`;管理列表;ADMIN+;幂等。
|
||||
- **Query(全部)**:`page:int?`,`pageSize:int?`,`status:string?(ENABLED/DISABLED)`,`isPrimary:int?(0/1)`,`agencyName:string?`。
|
||||
- **响应(完整)**:`records[]` 每项含上述 `AgencyResp` 全部字段;顶层 `total,page,pageSize`。
|
||||
- **示例**:`GET .../page?page=1&pageSize=10&status=ENABLED` → `{"code":200,"data":{"records":[{"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","status":"ENABLED","statusLabel":"启用","qualifications":[],"payments":[]}],"total":1,"page":1,"pageSize":10},"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../page?page=1&pageSize=10&status=ENABLED` → `{
|
||||
"code":200,"data":{
|
||||
"records":[{
|
||||
"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","status":"ENABLED","statusLabel":"启用","qualifications":[],"payments":[]
|
||||
}],"total":1,"page":1,"pageSize":10
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.2 启用旅行社下拉
|
||||
|
||||
- `GET /v3/admin/travel-agency/enabled`;ADMIN+;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项含 `AgencySimpleResp` 全部 7 字段。
|
||||
- **示例**:`GET .../enabled` → `{"code":200,"data":[{"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../enabled` → `{
|
||||
"code":200,"data":[{
|
||||
"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.3 产品页可用旅行社
|
||||
|
||||
- `GET /v3/admin/travel-agency/enabled-for-product`;过滤经营许可证号为空的公司;ADMIN+;幂等;无入参。
|
||||
- **响应(完整)**:`data[]` 每项含 `AgencySimpleResp` 全部 7 字段。
|
||||
- **示例**:`GET .../enabled-for-product` → `{"code":200,"data":[{"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../enabled-for-product` → `{
|
||||
"code":200,"data":[{
|
||||
"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.4 按合同平台筛选旅行社
|
||||
|
||||
- `GET /v3/admin/travel-agency/enabled-by-platform`;合同方案下拉;ADMIN+;幂等。
|
||||
- **Query**:`contractPlatform:string!` (`12301`/`TENCENT_ESIGN`)。**响应**:`AgencySimpleResp` 全部 7 字段;主体公司优先、ID 升序。
|
||||
- **边界/示例**:空值返回“合同平台不能为空”。`GET .../enabled-by-platform?contractPlatform=12301` → `{"code":200,"data":[{"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **边界/示例**:空值返回“合同平台不能为空”。`GET .../enabled-by-platform?contractPlatform=12301` → `{
|
||||
"code":200,"data":[{
|
||||
"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","isPrimary":1,"sortOrder":1,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-04T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.5 旅行社详情
|
||||
|
||||
- `GET /v3/admin/travel-agency/{id}`;含资质和支付子表;ADMIN+;幂等;`id:string!`。
|
||||
- `GET /v3/admin/travel-agency/<id>`;含资质和支付子表;ADMIN+;幂等;`id:string!`。
|
||||
- **响应(完整)**:上述 `AgencyResp` 全部字段;`qualifications[]` 字段见 5.7;`payments[]` 字段见 5.8。不存在 `594001`。
|
||||
- **示例**:`GET .../7001` → `{"code":200,"data":{"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","status":"ENABLED","qualifications":[],"payments":[]},"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../7001` → `{
|
||||
"code":200,"data":{
|
||||
"agencyId":"7001","code":"hulai","agencyName":"呼籁旅行社","status":"ENABLED","qualifications":[],"payments":[]
|
||||
},"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.6 新建旅行社
|
||||
|
||||
- `POST /v3/admin/travel-agency`;SUPER_ADMIN;非幂等。
|
||||
- **请求体**:上述 `AgencySave` 全部 33 字段。**响应**:`data:string` 新 agencyId,无其他 data 字段。
|
||||
- **边界/错误**:编码重复 `594010`;非 SUPER_ADMIN `594009`;编码格式/必填/长度校验。高敏 key 不得打印。
|
||||
- **示例**:请求 `{"code":"demo-agency","agencyName":"示例旅行社","businessLicenseNumber":"9115********0001","supportedPlatforms":"[\"12301\"]","status":"ENABLED","isPrimary":0,"visible":1}` → `{"code":200,"data":"7002","message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `{
|
||||
"code":"demo-agency","agencyName":"示例旅行社","businessLicenseNumber":"9115********0001","supportedPlatforms":"[\"12301\"]","status":"ENABLED","isPrimary":0,"visible":1
|
||||
}` → `{
|
||||
"code":200,"data":"7002","message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.7 编辑旅行社
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{id}`;ADMIN+;目标更新可重试。
|
||||
- `PUT /v3/admin/travel-agency/<id>`;ADMIN+;目标更新可重试。
|
||||
- **入参/响应**:`id:string!` + `AgencySave` 全部字段;成功 `data:null`。`code` 编辑时不可改。
|
||||
- **错误/示例**:不存在 `594001`。请求 `{"code":"hulai","agencyName":"呼籁旅行社","businessLicenseNumber":"9115********0001","status":"ENABLED"}` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在 `594001`。请求 `{
|
||||
"code":"hulai","agencyName":"呼籁旅行社","businessLicenseNumber":"9115********0001","status":"ENABLED"
|
||||
}` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.8 停用旅行社
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{id}/disable`;ADMIN+;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- `PUT /v3/admin/travel-agency/<id>/disable`;ADMIN+;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- **响应/错误**:成功 `data:null`;不存在 `594001`;主体公司不可停用 `594005`。
|
||||
- **示例**:`PUT .../7002/disable` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../7002/disable` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.9 启用旅行社
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{id}/enable`;ADMIN+;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- `PUT /v3/admin/travel-agency/<id>/enable`;ADMIN+;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- **响应/错误**:成功 `data:null`;不存在 `594001`。
|
||||
- **示例**:`PUT .../7002/enable` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../7002/enable` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.10 删除旅行社
|
||||
|
||||
- `DELETE /v3/admin/travel-agency/{id}`;ADMIN+;强保留语义(状态置 DISABLED);不保证重复调用成功。
|
||||
- `DELETE /v3/admin/travel-agency/<id>`;ADMIN+;强保留语义(状态置 DISABLED);不保证重复调用成功。
|
||||
- **入参/响应**:`id:string!`;成功 `data:null`。
|
||||
- **错误/边界**:`594001`;主体公司 `594005`;本接口不做物理删除。
|
||||
- **示例**:`DELETE .../7002` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../7002` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.6.11 设为主体公司
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{id}/set-primary`;SUPER_ADMIN;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- `PUT /v3/admin/travel-agency/<id>/set-primary`;SUPER_ADMIN;路径 `id:string!`;无 body;目标状态幂等。
|
||||
- **响应/错误**:成功 `data:null`;`594001`;目标停用或主体约束失败 `594005/594006`;非 SUPER_ADMIN `594009`。
|
||||
- **示例**:`PUT .../7001/set-primary` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../7001/set-primary` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.7 AdminTravelAgencyQualificationController(4)
|
||||
|
||||
`QualificationResp={qualificationId:string,agencyId:string,name,qualificationType,qualificationTypeLabel,fileUrl,fileType,fileTypeLabel,issueDate,expireDate,sortOrder,remark,createTime,updateTime}`。
|
||||
`QualificationSave={name:string!(max64),qualificationType:string!(max32),fileUrl:string!,fileType:string?(PDF/IMAGE/OTHER),issueDate:date?,expireDate:date|null,sortOrder:int?,remark:string?}`。
|
||||
`QualificationResp={
|
||||
qualificationId:string,agencyId:string,name,qualificationType,qualificationTypeLabel,fileUrl,fileType,fileTypeLabel,issueDate,expireDate,sortOrder,remark,createTime,updateTime
|
||||
}`。
|
||||
`QualificationSave={
|
||||
name:string!(max64),qualificationType:string!(max32),fileUrl:string!,fileType:string?(PDF/IMAGE/OTHER),issueDate:date?,expireDate:date|null,sortOrder:int?,remark:string?
|
||||
}`。
|
||||
|
||||
#### 5.7.1 资质列表
|
||||
|
||||
- `GET /v3/admin/travel-agency/{agencyId}/qualification`;ADMIN+;幂等;`agencyId:string!`。
|
||||
- `GET /v3/admin/travel-agency/<agencyId>/qualification`;ADMIN+;幂等;`agencyId:string!`。
|
||||
- **响应(完整)**:`data[]` 每项含 `QualificationResp` 全部 14 字段;`fileUrl` 为有效期 30 分钟的临时 URL。
|
||||
- **示例**:`GET .../7001/qualification` → `{"code":200,"data":[{"qualificationId":"8001","agencyId":"7001","name":"旅行社业务经营许可证","qualificationType":"TRAVEL_AGENCY_LICENSE","qualificationTypeLabel":"旅行社业务经营许可证","fileUrl":"https://example.invalid/temp?token=masked","fileType":"PDF","fileTypeLabel":"PDF","issueDate":"2024-01-01","expireDate":null,"sortOrder":1,"remark":null,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-01T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例**:`GET .../7001/qualification` → `{
|
||||
"code":200,"data":[{
|
||||
"qualificationId":"8001","agencyId":"7001","name":"旅行社业务经营许可证","qualificationType":"TRAVEL_AGENCY_LICENSE","qualificationTypeLabel":"旅行社业务经营许可证","fileUrl":"https://example.invalid/temp?token=masked","fileType":"PDF","fileTypeLabel":"PDF","issueDate":"2024-01-01","expireDate":null,"sortOrder":1,"remark":null,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-01T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.7.2 新增资质
|
||||
|
||||
- `POST /v3/admin/travel-agency/{agencyId}/qualification`;ADMIN+;非幂等。
|
||||
- `POST /v3/admin/travel-agency/<agencyId>/qualification`;ADMIN+;非幂等。
|
||||
- **入参/响应**:`agencyId:string!` + `QualificationSave` 全部 8 字段;成功 `data:string` 新 qualificationId。
|
||||
- **错误/边界**:文件无效(>10MB、非 PDF/JPG/PNG、上传失败)`594008`;长期有效传 `expireDate:null`。
|
||||
- **示例**:请求 `{"name":"旅行社业务经营许可证","qualificationType":"TRAVEL_AGENCY_LICENSE","fileUrl":"oss://private/masked.pdf","fileType":"PDF","issueDate":"2024-01-01","expireDate":null,"sortOrder":1}` → `{"code":200,"data":"8001","message":"操作成功","success":true}`。
|
||||
- **示例**:请求 `{
|
||||
"name":"旅行社业务经营许可证","qualificationType":"TRAVEL_AGENCY_LICENSE","fileUrl":"oss://private/masked.pdf","fileType":"PDF","issueDate":"2024-01-01","expireDate":null,"sortOrder":1
|
||||
}` → `{
|
||||
"code":200,"data":"8001","message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.7.3 编辑资质
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{agencyId}/qualification/{qualificationId}`;ADMIN+;目标更新可重试。
|
||||
- `PUT /v3/admin/travel-agency/<agencyId>/qualification/<qualificationId>`;ADMIN+;目标更新可重试。
|
||||
- **入参/响应**:路径中 `agencyId` 用于 URL 归类,后端操作键为 `qualificationId:string!`;body `QualificationSave` 全部字段;成功 `data:null`。
|
||||
- **错误/示例**:不存在 `594001`;文件无效 `594008`。请求 `{"name":"经营许可证(新)","qualificationType":"TRAVEL_AGENCY_LICENSE","fileUrl":"oss://private/masked.pdf","fileType":"PDF"}` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在 `594001`;文件无效 `594008`。请求 `{
|
||||
"name":"经营许可证(新)","qualificationType":"TRAVEL_AGENCY_LICENSE","fileUrl":"oss://private/masked.pdf","fileType":"PDF"
|
||||
}` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.7.4 删除资质
|
||||
|
||||
- `DELETE /v3/admin/travel-agency/{agencyId}/qualification/{qualificationId}`;ADMIN+;软删;不保证重复调用成功。
|
||||
- `DELETE /v3/admin/travel-agency/<agencyId>/qualification/<qualificationId>`;ADMIN+;软删;不保证重复调用成功。
|
||||
- **入参/响应**:`qualificationId:string!`;成功 `data:null`;不存在 `594001`。
|
||||
- **示例**:`DELETE .../7001/qualification/8001` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../7001/qualification/8001` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
### 5.8 AdminTravelAgencyPaymentController(5)
|
||||
|
||||
`PaymentResp={paymentId:string,agencyId:string,name,mchId,appId,apiV3Key,mchSerialNo,publicKeyId,privateKeyPath,publicKeyPath,isDefault:int,status,statusLabel,remark,createTime,updateTime}`。
|
||||
`PaymentSave={name:string!(max64),mchId:string!(max32),appId:string!(max64),apiV3Key:string!,mchSerialNo:string?,publicKeyId:string?,isDefault:int?(0/1),status:string?(ENABLED/DISABLED),remark:string?}`。这些接口包含高敏密钥/证书信息,仅 SUPER_ADMIN 使用,响应不得写入日志、埋点或客户端持久存储。
|
||||
`PaymentResp={
|
||||
paymentId:string,agencyId:string,name,mchId,appId,apiV3Key,mchSerialNo,publicKeyId,privateKeyPath,publicKeyPath,isDefault:int,status,statusLabel,remark,createTime,updateTime
|
||||
}`。
|
||||
`PaymentSave={
|
||||
name:string!(max64),mchId:string!(max32),appId:string!(max64),apiV3Key:string!,mchSerialNo:string?,publicKeyId:string?,isDefault:int?(0/1),status:string?(ENABLED/DISABLED),remark:string?
|
||||
}`。这些接口包含高敏密钥/证书信息,仅 SUPER_ADMIN 使用,响应不得写入日志、埋点或客户端持久存储。
|
||||
|
||||
#### 5.8.1 支付配置列表
|
||||
|
||||
- `GET /v3/admin/travel-agency/{agencyId}/payment`;SUPER_ADMIN;幂等;`agencyId:string!`。
|
||||
- `GET /v3/admin/travel-agency/<agencyId>/payment`;SUPER_ADMIN;幂等;`agencyId:string!`。
|
||||
- **响应(完整)**:`data[]` 每项含 `PaymentResp` 全部 16 字段。
|
||||
- **示例(脱敏)**:`GET .../7001/payment` → `{"code":200,"data":[{"paymentId":"9001","agencyId":"7001","name":"微信支付-主商户","mchId":"1106******39","appId":"wx************ff36","apiV3Key":"***","mchSerialNo":"***","publicKeyId":"PUB_***","privateKeyPath":"cert/***/apiclient_key.pem","publicKeyPath":"cert/***/public_key.pem","isDefault":1,"status":"ENABLED","statusLabel":"启用","remark":null,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-01T10:00:00"}],"message":"操作成功","success":true}`。
|
||||
- **示例(脱敏)**:`GET .../7001/payment` → `{
|
||||
"code":200,"data":[{
|
||||
"paymentId":"9001","agencyId":"7001","name":"微信支付-主商户","mchId":"1106******39","appId":"wx************ff36","apiV3Key":"***","mchSerialNo":"***","publicKeyId":"PUB_***","privateKeyPath":"cert/***/apiclient_key.pem","publicKeyPath":"cert/***/public_key.pem","isDefault":1,"status":"ENABLED","statusLabel":"启用","remark":null,"createTime":"2026-08-01T10:00:00","updateTime":"2026-08-01T10:00:00"
|
||||
}],"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.8.2 新增支付配置
|
||||
|
||||
- `POST /v3/admin/travel-agency/{agencyId}/payment`;SUPER_ADMIN;非幂等。
|
||||
- `POST /v3/admin/travel-agency/<agencyId>/payment`;SUPER_ADMIN;非幂等。
|
||||
- **入参/响应**:`agencyId:string!` + `PaymentSave` 全部 9 字段;成功 `data:string` 新 paymentId。`privateKeyPath/publicKeyPath` 不接受前端传入。
|
||||
- **错误/边界**:商户号重复 `594011`;非 SUPER_ADMIN `594009`;必填/长度校验。
|
||||
- **示例(虚构)**:请求 `{"name":"微信支付-主商户","mchId":"1900000001","appId":"wxdemo000000000001","apiV3Key":"***REDACTED***","mchSerialNo":"***REDACTED***","publicKeyId":"PUB_DEMO","isDefault":1,"status":"ENABLED"}` → `{"code":200,"data":"9001","message":"操作成功","success":true}`。
|
||||
- **示例(虚构)**:请求 `{
|
||||
"name":"微信支付-主商户","mchId":"1900000001","appId":"wxdemo000000000001","apiV3Key":"***REDACTED***","mchSerialNo":"***REDACTED***","publicKeyId":"PUB_DEMO","isDefault":1,"status":"ENABLED"
|
||||
}` → `{
|
||||
"code":200,"data":"9001","message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.8.3 编辑支付配置
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{agencyId}/payment/{paymentId}`;SUPER_ADMIN;目标更新可重试。
|
||||
- `PUT /v3/admin/travel-agency/<agencyId>/payment/<paymentId>`;SUPER_ADMIN;目标更新可重试。
|
||||
- **入参/响应**:URL 含 `agencyId`,操作键为 `paymentId:string!`;body `PaymentSave` 全部字段;成功 `data:null`。
|
||||
- **错误/示例**:不存在 `594001`;商户号冲突 `594011`。请求 `{"name":"微信支付-主商户","mchId":"1900000001","appId":"wxdemo000000000001","apiV3Key":"***REDACTED***","status":"ENABLED"}` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **错误/示例**:不存在 `594001`;商户号冲突 `594011`。请求 `{
|
||||
"name":"微信支付-主商户","mchId":"1900000001","appId":"wxdemo000000000001","apiV3Key":"***REDACTED***","status":"ENABLED"
|
||||
}` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.8.4 删除支付配置
|
||||
|
||||
- `DELETE /v3/admin/travel-agency/{agencyId}/payment/{paymentId}`;SUPER_ADMIN;不保证重复调用成功。
|
||||
- `DELETE /v3/admin/travel-agency/<agencyId>/payment/<paymentId>`;SUPER_ADMIN;不保证重复调用成功。
|
||||
- **入参/响应**:`paymentId:string!`;成功 `data:null`。
|
||||
- **错误/边界**:不存在 `594001`;默认商户不可删 `594007`,须先将另一条设为默认。
|
||||
- **示例**:`DELETE .../7001/payment/9002` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`DELETE .../7001/payment/9002` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
#### 5.8.5 设为默认支付商户
|
||||
|
||||
- `PUT /v3/admin/travel-agency/{agencyId}/payment/{paymentId}/set-default`;SUPER_ADMIN;目标状态幂等。
|
||||
- `PUT /v3/admin/travel-agency/<agencyId>/payment/<paymentId>/set-default`;SUPER_ADMIN;目标状态幂等。
|
||||
- **入参/响应**:`agencyId:string!`,`paymentId:string!`;无 body;成功 `data:null`。
|
||||
- **错误/边界**:支付配置不存在/归属不符 `594001`;同一公司最多一条 `isDefault=1`。
|
||||
- **示例**:`PUT .../7001/payment/9001/set-default` → `{"code":200,"data":null,"message":"操作成功","success":true}`。
|
||||
- **示例**:`PUT .../7001/payment/9001/set-default` → `{
|
||||
"code":200,"data":null,"message":"操作成功","success":true
|
||||
}`。
|
||||
|
||||
## 6. 枚举/数据字典(按类型分表)
|
||||
|
||||
@ -569,6 +827,13 @@ N+1 消除是内部性能修复,不属于前端契约变更。
|
||||
| 594010 | 旅行社编码重复 | 新建旅行社 |
|
||||
| 594011 | 微信支付商户号冲突 | 新增/编辑支付配置 |
|
||||
|
||||
## 验证证据
|
||||
|
||||
- PR #5501 已合并:merge commit `45117d3d5896515909e303dcbfa9d3616f881803`,head `f66d236f2aea2d0a63db8cb58d59f2ae74e2b6fb`。
|
||||
- 基于合并代码静态核对 8 个 admin Controller,端点计数 `15+7+4+4+6+11+4+5=56`。
|
||||
- 文档本地自检:56 个接口小节、只有目标文件进入 commit、`git diff --check` 通过。
|
||||
- 本 PR 的测试服部署和网关 HTTP 行为验证状态以文档 frontmatter 为准,不用本地静态核对冒充。
|
||||
|
||||
## 8. 业务边界与 v1/v3 数据隔离
|
||||
|
||||
- 根据 Issue #5368 在 2026-08-04 的决策,管理后台合同整页的列表、详情、创建、作废、刷新、下载、短信和上传统一调用 `/v3/admin/*`。
|
||||
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户