diff --git a/changelogs/2026-05/13_improve_contract_supp_clause_size_2000_to_5000.md b/changelogs/2026-05/13_improve_contract_supp_clause_size_2000_to_5000.md new file mode 100644 index 0000000..e9c47be --- /dev/null +++ b/changelogs/2026-05/13_improve_contract_supp_clause_size_2000_to_5000.md @@ -0,0 +1,94 @@ +--- +date: 2026-05-13 +type: backend-improvement +service: hl-order-service-v2 +priority: medium +notify: ["@mmg"] +status: verified +--- + +# 12301 合同补充约定字数上限 2000 → 5000 (已测试服验证) + +> **PR**: [#2187](https://git.1814.love:8443/wx/HL/pulls/2187) — 已合并 dev + 部署测试服 +> **Issue**: [#2186](https://git.1814.love:8443/wx/HL/issues/2186) +> **状态**: ✅ **测试服已验证** (api.test.1814.love:9443) — 3/3 case 端到端通过 + +--- + +## 一、背景 + +`hl-ui` 管理端「编辑补充约定模板」弹窗目前 `maxlength=2000`,实际旅行社业务里 12301 旅游合同补充约定动辄超过 2000 字符,卡用户。 + +调研结论: +- **12301 国家旅游局 API 公开/内部文档均未约束 supplementaryClause 字段长度**(项目内 `35_合同对接12301国家旅游局API需求规格.md` 通篇没列字段长度;搜索 tourage.cn / 12301 字段长度均无公开资料) +- 数据库 `contract.supplementary_clause` / `contract_scheme.supplementary_clause` 是 `TEXT`(~21000 中文字符),底层不卡 +- 历史 12301 错误码 `errcode=301025` 是换行符问题(已 `replace("\n", " ")` 净化),没遇到过长度被拒 +- **2000 是当初开发期保守值**,本次放宽到 5000,留安全垫给 12301 未知上限 + +--- + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 创建合同方案 | POST | `/admin/contract/scheme` | 校验放宽 | `supplementaryClause` 字数上限 2000 → 5000 | +| 2 | 更新合同方案 | PUT | `/admin/contract/scheme/{schemeId}` | 校验放宽 | 同上 | +| 3 | 创建合同 | POST | `/admin/contract/create`(及其同族) | 校验放宽 | `supplementaryClause` 字数上限 2000 → 5000 | +| 4 | 报备合同(SYNC) | POST | `/admin/contract/report`(及其同族) | 校验放宽 | `supplementaryClause` 字数上限 2000 → 5000 | + +**未变接口**(已有行为不变): +- `POST/PUT /admin/contract/clause-template`(补充约定模板 CRUD):后端 `ClauseTemplateRequest.content` 本来就没 `@Size` 限制,DB TEXT 兜底。前端弹窗当前 2000 字限制是**前端自己加的**,需前端同步改。 + +--- + +## 三、字段约束变化 + +| DTO 字段 | 原约束 | 新约束 | +|---|---|---| +| `ContractSchemeRequest.supplementaryClause` | `@Size(max=2000)` | `@Size(max=5000)` | +| `CreateContractRequest.supplementaryClause` | `@Size(max=2000)` | `@Size(max=5000)` | +| `ReportContractRequest.supplementaryClause` | `@Size(max=2000)` | `@Size(max=5000)` | + +错误 message 同步从「补充约定/条款不能超过2000个字符」改为「...不能超过5000个字符」。 + +--- + +## 四、前端待办(@mmg) + +请 hl-ui 同步把以下输入框 `maxlength=2000` → `maxlength=5000`: + +1. **「编辑补充约定模板」弹窗**(模板内容输入框)— 截图见 Issue #2186 +2. **合同方案管理页**——「补充条款」输入框(POST/PUT `/admin/contract/scheme` 调用方) +3. **创建合同 / 报备合同表单**——「补充约定内容」输入框 + +字数计数器 `2000/2000` 显示也要同步改 `5000/5000`。 + +> 不改前端的话:用户能勾选 ≤2000 字符的旧模板,但不能写超过 2000 字符的内容(前端仍卡);后端能接 5000,前端是瓶颈。 + +--- + +## 五、测试服已验证 (硬性凭证) + +`POST /admin/contract/scheme`,Bearer admin token: + +``` +A. supplementaryClause = "夏" × 4500 字符 + → HTTP 200 code=200 success schemeId=2054442503913779201 ✓ (原 max=2000 会拦) + +B. supplementaryClause = "x" × 5001 字符 + → HTTP 200 code=400 message="补充条款不能超过5000个字符" ✓ (@Size(max=5000) 生效) + +C. supplementaryClause = "中" × 2001 字符 + → HTTP 200 code=200 success schemeId=2054442506648465410 ✓ (原 max=2000 会拦) + +[CLEANUP] DELETE /admin/contract/scheme/2054442503913779201 → HTTP 200 +[CLEANUP] DELETE /admin/contract/scheme/2054442506648465410 → HTTP 200 +``` + +--- + +## 六、风险与回滚 + +- **风险**:12301 远端实际可能有 supplementaryClause 上限(未知),5000 字以内若被 12301 拒绝,会在 12301 调用时报 4xx/errcode 错误(不会损坏本地数据,仅合同上报失败)。 +- **回滚**:3 处 `@Size(max=5000)` 改回 `2000` 即可,无 schema 变更、无数据兼容性问题。 +- 若线上出现 12301 实际拒绝长 supplementaryClause 的 errcode,据实再调小。