From 4e52f2697257ab49ba8f7c2995d04efafafbf70d Mon Sep 17 00:00:00 2001 From: lc Date: Sun, 6 Sep 2026 10:02:59 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=BE=9B=E5=BA=94=E5=95=86?= =?UTF-8?q?=E8=B4=A6=E6=88=B7=E4=B8=8E=E5=90=88=E5=90=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...应商合同修改与删除接口-修改接口-管理后台.md | 300 ++++++++++++++++++ ...•†账户修改入口与删除限制-修改接口-管理后台.md | 234 ++++++++++++++ 2 files changed, 534 insertions(+) create mode 100644 changelogs-v2/2026-09/06_6842_供应商合同修改与删除接口-修改接口-管理后台.md create mode 100644 changelogs-v2/2026-09/06_7087_供应商账户修改入口与删除限制-修改接口-管理后台.md diff --git a/changelogs-v2/2026-09/06_6842_供应商合同修改与删除接口-修改接口-管理后台.md b/changelogs-v2/2026-09/06_6842_供应商合同修改与删除接口-修改接口-管理后台.md new file mode 100644 index 00000000..1f86f6dd --- /dev/null +++ b/changelogs-v2/2026-09/06_6842_供应商合同修改与删除接口-修改接口-管理后台.md @@ -0,0 +1,300 @@ +--- +schema: "hl-changelog/v2" +ticket: "6842" +title: "供应商合同修改与删除接口" +consumer: "admin" +author: "lc(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "汇总现有合同修改、删除契约;前端按完整替换、必填原因及可选合同版本接入。既有 TEST 业务实测及本次只读复核范围见正文。" +updated_at: "2026-09-06" +base: "dev-v3" +--- + +# 供应商合同:修改与删除接口 + +> **影响范围**:管理后台供应商合同编辑、删除。当前状态:后端已部署;前端待核对接入。 + +更新为整份替换,15 个业务字段均可空;修改、删除都必须提交 `changeReason`。`expectedUpdateTime` 可省略,传入时必须使用合同自身版本。 + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|---|---|---|---|---| +| 1 | 修改供应商合同 | PUT | `/admin/supplier/items/{supplierId}/contracts/{contractId}/update` | 现有契约说明 | 完整替换一份合同 | +| 2 | 删除供应商合同 | DELETE | `/admin/supplier/items/{supplierId}/contracts/{contractId}/del` | 现有契约说明 | 携带 JSON 原因软删除一份合同 | + +## 三、接口详情 + +### 1. 修改供应商合同 `PUT /admin/supplier/items/{supplierId}/contracts/{contractId}/update` + +**VO**: `SupplierContractUpdateReqVO / SupplierContractRespVO` + +#### 使用场景 + +编辑供应商下已登记的单份合同。提交应保留的全部业务字段;未提交字段按空值覆盖。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 所属供应商 | +| `contractId` | Path | String | 是 | 正整数 ID | 目标合同 | +| `changeReason` | Body | String | 是 | 去空白后非空,最长 500 字符 | 本次修改原因 | +| `expectedUpdateTime` | Body | String/null | 否 | `yyyy-MM-dd HH:mm:ss` | 合同 `updateTime`,传入即校验 | +| `contractName` | Body | String/null | 否 | 最长 500 字符 | 合同名称 | +| `contractNo` | Body | String/null | 否 | 最长 100 字符 | 合同编号 | +| `contractType` | Body | String/null | 否 | `FRAME` / `SINGLE_TRIP` / `PURCHASE` | 合同类型 | +| `signDate` | Body | String/null | 否 | `yyyy-MM-dd` | 签署日期 | +| `startDate` | Body | String/null | 否 | `yyyy-MM-dd` | 有效期开始 | +| `endDate` | Body | String/null | 否 | 两端有值时不得早于 `startDate` | 有效期结束 | +| `businessLine` | Body | String/null | 否 | 最长 100 字符 | 业务线自由文本 | +| `relatedMainContract` | Body | String/null | 否 | 最长 100 字符 | 关联主合同引用 | +| `autoRenew` | Body | Boolean/null | 否 | `true` / `false` / `null` | 自动续约 / 不续约 / 未登记 | +| `amount` | Body | String/null | 否 | 非负,最多 10 位整数、2 位小数 | 金额,如 `"1200.50"` | +| `pricingMode` | Body | String/null | 否 | 最长 100 字符 | 计价方式 | +| `settleCycle` | Body | String/null | 否 | 最长 32 字符 | 结算周期自由文本 | +| `status` | Body | String/null | 否 | `DRAFT` / `ACTIVE` / `SIGNED` / `EXPIRED` | 合同状态 | +| `scanFileUrl` | Body | String/null | 否 | 最长 1000 字符 | 一个合同附件的永久地址 | +| `remark` | Body | String/null | 否 | 最长 500 字符 | 合同备注 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `code` / `message` / `success` | Integer / String / Boolean | 成功为 `200`、`成功`、`true` | +| `data.contractId` | String | 合同 ID | +| `data.contractName` | String/null | 合同名称 | +| `data.contractNo` | String/null | 合同编号 | +| `data.contractType` | String/null | 合同类型 | +| `data.signDate` | String/null | 签署日期 | +| `data.startDate` / `data.endDate` | String/null | 有效期,`yyyy-MM-dd` | +| `data.businessLine` | String/null | 业务线 | +| `data.relatedMainContract` | String/null | 关联主合同 | +| `data.autoRenew` | Boolean/null | 自动续约标记,`false` 与 `null` 含义不同 | +| `data.amount` | String/null | 金额;无金额为 `null` | +| `data.pricingMode` | String/null | 计价方式 | +| `data.settleCycle` | String/null | 结算周期 | +| `data.status` | String/null | 合同状态;历史读取可能出现 `TERMINATED` | +| `data.scanFileUrl` | String/null | 合同附件地址 | +| `data.remark` | String/null | 合同备注 | +| `data.updateTime` | String | 合同新版本,`yyyy-MM-dd HH:mm:ss` | + +#### 请求示例 + +以下 ID、附件地址和时间均为示例值。 + +```http +PUT /admin/supplier/items/2095000000000000001/contracts/2095000000000000010/update +Authorization: Bearer <当前有效凭证> +Content-Type: application/json + +{ + "changeReason": "调整合同有效期", + "expectedUpdateTime": "2026-09-06 10:00:00", + "contractName": "年度服务合同", + "contractNo": "HT-2026-001", + "contractType": "FRAME", + "signDate": "2026-09-01", + "startDate": "2026-09-01", + "endDate": "2027-09-30", + "businessLine": "旅行服务", + "relatedMainContract": null, + "autoRenew": false, + "amount": "1200.50", + "pricingMode": "按团结算", + "settleCycle": "月结", + "status": "SIGNED", + "scanFileUrl": "https://files.example.com/contracts/demo.pdf", + "remark": null +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "contractId": "2095000000000000010", + "contractName": "年度服务合同", + "contractNo": "HT-2026-001", + "contractType": "FRAME", + "signDate": "2026-09-01", + "startDate": "2026-09-01", + "endDate": "2027-09-30", + "businessLine": "旅行服务", + "relatedMainContract": null, + "autoRenew": false, + "amount": "1200.50", + "pricingMode": "按团结算", + "settleCycle": "月结", + "status": "SIGNED", + "scanFileUrl": "https://files.example.com/contracts/demo.pdf", + "remark": null, + "updateTime": "2026-09-06 10:00:01" + } +} +``` + +#### 空数据 / 降级响应 + +可空业务字段省略或传 `null` 均清空;可选文本空白也规范化为空。只传 `changeReason` 会尝试清空全部业务字段,不表示仅改原因。成功返回合同对象,无变化时返回业务错误。 + +#### 错误响应 + +合同版本过期: + +```json +{"code":395014,"message":"数据已被他人修改,请刷新后重试","success":false,"data":null} +``` + +`400`:缺少原因或格式错误;`395002`:无写权限;`395051`:合同不存在、已删除或归属不符;`395054`:日期倒置;`395057`:无实际变化;`395031`:供应商已归档;`395005`:主体企微审批未结束或状态不允许。 + +#### 业务边界 + +- 要求 `FINANCE` 或 `SUPER_ADMIN` 且具有 `supplier:update`;`ADMIN` 被拒绝。 +- 合同必须属于路径供应商,供应商不能已归档,主体企微审批必须已结束。 +- 完整替换包含页面隐藏字段;需保留的字段应原样提交。版本取合同自身,不使用供应商主体版本。 + +### 2. 删除供应商合同 `DELETE /admin/supplier/items/{supplierId}/contracts/{contractId}/del` + +**VO**: `SupplierContractDeleteReqVO / Result` + +#### 使用场景 + +删除一份已登记合同。DELETE 请求须携带 JSON 请求体。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 所属供应商 | +| `contractId` | Path | String | 是 | 正整数 ID | 目标合同 | +| `changeReason` | Body | String | 是 | 去空白后非空,最长 500 字符 | 本次删除原因 | +| `expectedUpdateTime` | Body | String/null | 否 | `yyyy-MM-dd HH:mm:ss` | 合同当前版本,提供时必须匹配 | + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `code` | Integer | 成功为 `200` | +| `message` | String | 成功为 `成功` | +| `success` | Boolean | 成功为 `true` | +| `data` | null | 无合同对象 | + +#### 请求示例 + +```http +DELETE /admin/supplier/items/2095000000000000001/contracts/2095000000000000010/del +Authorization: Bearer <当前有效凭证> +Content-Type: application/json + +{ + "changeReason": "合同重复登记", + "expectedUpdateTime": "2026-09-06 10:00:01" +} +``` + +#### 响应示例 + +```json +{"code":200,"message":"成功","success":true,"data":null} +``` + +#### 空数据 / 降级响应 + +成功的 `data: null` 为正常结果,删除后从详情合同列表中移除该项。 + +#### 错误响应 + +缺少删除原因: + +```json +{"code":400,"message":"变更原因不能为空","success":false,"data":null} +``` + +`395002`:无写权限;`395051`:合同不存在、已删除或归属不符;`395014`:版本过期;`395031`:供应商已归档;`395005`:主体企微审批未结束或状态不允许。 + +#### 业务边界 + +- 要求 `FINANCE` 或 `SUPER_ADMIN` 且具有 `supplier:update`;供应商已归档或主体企微审批未结束时拒绝。 +- 删除为软删除,不删除供应商或账户;没有合同恢复接口。 +- 前端请求库需将原因放进 DELETE 的 JSON body;不能只拼 Query 参数或只传 ID。 + +## 四、契约约束与正确调用方式 + +从 `GET /admin/supplier/items/{supplierId}/basic-info/view` 的 `data.contracts[]` 读取合同、`contractId` 和 `updateTime`。修改时提交应保留的全部字段;修改成功用新版本继续操作,删除成功刷新列表。版本冲突重新读取后再编辑。日期按 GMT+8 日历日期传 `yyyy-MM-dd`。 + +## 五、数据库行为 + +更新只替换目标合同并刷新合同版本;删除后有效详情不再返回该合同,历史记录保留。供应商主体版本不因合同写入改变。参数、权限、归属或版本校验失败时不产生合同变更。 + +## 六、边界行为 + +未登录或登录失效按认证失败处理;供应商不存在返回 `395001`。业务错误可能随 HTTP 200 返回,应检查 `code` 和 `success`。金额 `1200.5` 与 `1200.50` 视为相同值,仅改变金额格式不会构成实际变更。 + +## 六.5、枚举 / 数据字典 + +### `contractType` + +| 值 | 中文 | 说明 | +|---|---|---| +| `FRAME` | 框架合同 | 可写 | +| `SINGLE_TRIP` | 单团单合同 | 可写 | +| `PURCHASE` | 采购合同 | 可写 | +| `null` | 未登记 | 可写 | + +### `status` + +| 值 | 中文 | 说明 | +|---|---|---| +| `DRAFT` | 草稿 | 可写 | +| `ACTIVE` | 生效中 | 可写 | +| `SIGNED` | 已签约 | 可写 | +| `EXPIRED` | 已过期 | 可写 | +| `TERMINATED` | 已终止 | 仅历史回显,不可提交 | +| `null` | 未登记 | 可写 | + +## 六.6、修改前后对比 + +本次为既有契约汇总,后端无新增变更。 + +| 字段 / 行为 | 早期 #6544 说明 | 当前契约 | +|---|---|---| +| 合同业务字段 | 部分必填 | 全部可空;含业务线、关联主合同、自动续约 | +| `expectedUpdateTime` | 必填 | 可选,提供时校验合同版本 | +| `status` | 未列出 `SIGNED` | 支持已签约 `SIGNED` | +| 修改 / 删除 | 独立接口 | 路径保持不变;原因仍必填 | + +## 六.7、影响评估 + +本次没有新增兼容性变化,无需与后端同步上线。前端接入现有修改、删除按钮时使用上述请求体,避免只传变化字段导致清空、丢弃 DELETE body 或误用主体版本。 + +## 七、不影响范围 + +本次仅说明合同维护入口;供应商主体保存和账户维护继续使用各自接口。 + +## 八、测试环境已验证 + +- 既有业务实测:#6654 已覆盖合同补全、清空、删除、缺原因及版本失败零写入;#6842 已覆盖扩展字段保存回读、`SIGNED`、`null`、`false` 和日期错误零写入。 +- 本次于 2026-09-06 通过 TEST Gateway 只读核对 Resource Swagger:合同 PUT、DELETE 路径存在,更新的 15 个业务字段、可选版本与必填原因均已发布;同步核对最新 `dev-v3`。此次未重复执行共享环境业务写操作。 + +## 十、相关文档 + +- [合同修改、删除实测 #6654](https://git.1814.love:8443/wx/HL/issues/6654#issuecomment-43820) +- [补充字段与实测 #6842](https://git.1814.love:8443/wx/HL/issues/6842#issuecomment-44703) + +## 关联 / 联系人 + +- **Issue**: [#6842](https://git.1814.love:8443/wx/HL/issues/6842) +- **PR**: [#6858](https://git.1814.love:8443/wx/HL/pulls/6858)、[#6665](https://git.1814.love:8443/wx/HL/pulls/6665) +- **后端负责人**: @lc diff --git a/changelogs-v2/2026-09/06_7087_供应商账户修改入口与删除限制-修改接口-管理后台.md b/changelogs-v2/2026-09/06_7087_供应商账户修改入口与删除限制-修改接口-管理后台.md new file mode 100644 index 00000000..32cbdcd3 --- /dev/null +++ b/changelogs-v2/2026-09/06_7087_供应商账户修改入口与删除限制-修改接口-管理后台.md @@ -0,0 +1,234 @@ +--- +schema: "hl-changelog/v2" +ticket: "7087" +title: "供应商账户修改入口与删除限制" +consumer: "admin" +author: "lc(GIT)" +change_type: "修改接口" +backend_status: "deployed" +gateway_status: "verified" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "现有接口说明与历史口径纠正;前端按草稿账户修改入口接入,取消空数组删除账户。既有 TEST 业务实测及本次只读复核范围见正文。" +updated_at: "2026-09-06" +base: "dev-v3" +--- + +# 供应商账户:修改入口与删除限制 + +> **影响范围**:管理后台供应商账户编辑、删除操作。当前状态:后端已部署;前端待核对接入。 + +## ⚠️ 关键变化 + +草稿初始账户通过供应商更新接口修改,必须保留一项账户。**旧 #6669 文档的 `initialAccounts: []` 删除方式已被 #7087 收紧,当前返回 `400 / 账户不能为空`。** 草稿的 `changeReason` 现可省略。 + +| 操作 | 当前支持情况 | +|---|---| +| 修改草稿初始账户 | 支持,使用下文接口,供应商及其已有账户必须均为 `DRAFT` | +| 修改已提交或已生效账户资料 | 未提供独立接口;不能通过供应商更新绕过状态限制 | +| 单独删除账户 | 未提供接口;不能提交空数组清空最后一项账户 | +| 设置默认账户 | 已有 `PUT /admin/supplier/bank-accounts/{accountId}/default/update`,仅改变默认标记 | + +## 二、变更接口清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|---|---|---|---|---| +| 1 | 修改草稿初始账户 | PUT | `/admin/supplier/items/{supplierId}/update` | 现有契约说明 | 通过 `initialAccounts` 完整替换唯一草稿账户;禁止空数组删除 | + +## 三、接口详情 + +### 1. 修改草稿初始账户 `PUT /admin/supplier/items/{supplierId}/update` + +**VO**: `SupplierUpdateReqVO / SupplierBankAccountReqVO / SupplierWriteRespVO` + +#### 使用场景 + +在资料完整的草稿供应商下修改初始账户。本节列出账户编辑所需载荷;其余主体资料省略时保留现值。保存后主体必填资料、供应商类型、联系人、账户仍须完整。 + +#### 入参 + +| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | +|---|---|---|---|---|---| +| `supplierId` | Path | String | 是 | 正整数 ID | 供应商 ID | +| `expectedUpdateTime` | Body | String | 是 | `yyyy-MM-dd HH:mm:ss` | 供应商主体版本,不能使用账户版本 | +| `initialAccounts` | Body | Array | 本场景是 | 恰好 1 项 | 省略或 `null` 保留现值;`[]` 拒绝 | +| `initialAccounts[].accountType` | Body | String | 是 | `CORPORATE` / `PERSONAL` | 对公 / 对私 | +| `initialAccounts[].bankName` | Body | String | 是 | 非空,最长 500 字符 | 开户银行 | +| `initialAccounts[].accountNo` | Body | String | 是 | 去空白和连字符后 8~32 位数字 | 收款账号 | +| `initialAccounts[].bankBranch` | Body | String/null | 否 | 最长 500 字符 | 开户支行,可清空 | +| `initialAccounts[].proofFileUrls` | Body | Array/null | 否 | 最多 20 个不重复的公网 HTTPS 地址,每项最长 1000 字符;不带查询参数或片段 | 证明附件,省略或 `[]` 清空 | +| `initialAccounts[].settleMode` | Body | String/null | 否 | `PREPAY` / `MONTHLY` / `SINGLE` | 结算方式 | +| `initialAccounts[].accountPeriod` | Body | String/null | 条件必填 | 最长 50 字符;仅 `MONTHLY` 必填,其他方式须为空 | 月结账期 | +| `initialAccounts[].invoiceType` | Body | String/null | 否 | `SPECIAL` / `NORMAL` / `NONE` | 发票类型 | +| `initialAccounts[].taxRate` | Body | String/null | 条件必填 | 0%~100%,最多两位小数 | 可开票时必填;`NONE` 或未选发票类型时须为空 | +| `changeReason` | Body | String | 否 | 最长 500 字符 | 此处为 `DRAFT`,允许省略 | + +不提交 `accountId`、`accountName` 或账户状态;户名由供应商全称确定。 + +#### 出参 + +| 字段 | 类型 | 说明 | +|---|---|---| +| `code` / `message` / `success` | Integer / String / Boolean | 业务结果;成功为 `200`、`成功`、`true` | +| `data.supplierId` / `data.supplierNo` | String | 供应商 ID / 编号 | +| `data.status` / `data.statusName` | String | 本场景为 `DRAFT` / `草稿` | +| `data.onboardingStage` | String | 本场景为 `PROFILE_DRAFT` | +| `data.initialAccounts` | Array | 保存后的初始账户摘要 | +| `data.initialAccounts[].accountId` | String | 当前账户 ID,替换账号后应重新读取 | +| `data.initialAccounts[].accountNo` | String | 完整账号 | +| `data.initialAccounts[].accountNoMask` | String | 废弃兼容字段,实际同样为完整账号;使用 `accountNo` | +| `data.initialAccounts[].status` | String | 本场景为 `DRAFT` | +| `data.approval` | null | 草稿直接保存,不发起审批 | +| `data.updateTime` | String | 保存后的供应商版本,供下次编辑使用 | + +#### 请求示例 + +以下 ID、账号和时间均为示例值。 + +```http +PUT /admin/supplier/items/2095000000000000001/update +Authorization: Bearer <当前有效凭证> +Content-Type: application/json + +{ + "expectedUpdateTime": "2026-09-06 10:00:00", + "initialAccounts": [{ + "accountType": "CORPORATE", + "bankName": "示例银行", + "accountNo": "6222000012345678", + "bankBranch": "示例支行", + "proofFileUrls": [], + "settleMode": "MONTHLY", + "accountPeriod": "月结30天", + "invoiceType": "SPECIAL", + "taxRate": "6%" + }] +} +``` + +#### 响应示例 + +```json +{ + "code": 200, + "message": "成功", + "success": true, + "data": { + "supplierId": "2095000000000000001", + "supplierNo": "SUP2095000000000000001", + "status": "DRAFT", + "statusName": "草稿", + "onboardingStage": "PROFILE_DRAFT", + "initialAccounts": [{ + "accountId": "2095000000000000002", + "accountNo": "6222000012345678", + "accountNoMask": "6222000012345678", + "status": "DRAFT" + }], + "approval": null, + "updateTime": "2026-09-06 10:00:01" + } +} +``` + +#### 空数据 / 降级响应 + +成功响应包含账户摘要。编辑表单完整回显使用 `GET /admin/supplier/items/{supplierId}/account-info/list` 的 `data.bankAccounts`,主体版本取该响应的 `data.updateTime`。摘要不包含银行、附件和结算字段,不能直接作为下次完整账户载荷。 + +#### 错误响应 + +提交 `initialAccounts: []`: + +```json +{"code":400,"message":"账户不能为空","success":false,"data":null} +``` + +其他常见业务码:`395002` 无写权限;`395005` 非草稿或主体企微审批未结束;`395009` 已有账户不是草稿;`395014` 主体版本过期;`395027` 账号已占用;`400` 缺版本、字段或结算组合不合法。完全未改变数据也返回 `400 / 未检测到实际变化`。 + +#### 业务边界 + +- 要求 `FINANCE` 或 `SUPER_ADMIN` 且具有 `supplier:update`;`ADMIN` 被拒绝。 +- 仅可维护草稿初始账户;已提交、已生效、已驳回账户没有资料修改或删除入口。 +- 一项账户是完整快照:未提交的可选字段会被清空,需保留的字段必须一并带回。 +- 相同账号保留账户 ID;换成新账号会替换旧草稿账户,成功后刷新列表和版本。 + +## 四、契约约束与正确调用方式 + +1. 按供应商读取账户列表和主体版本,草稿页面提交一项完整账户。 +2. 从月结切换为其他结算方式时同步清空 `accountPeriod`;选不开票时同步清空 `taxRate`。 +3. 保存成功刷新账户;版本冲突先重新读取。前端移除空数组删除逻辑,不生成不存在的账户删除路径。 + +## 五、数据库行为 + +修改成功保留一项草稿账户并刷新供应商版本;更换账号时旧草稿账户不再出现在有效列表。校验失败不改变账户;空数组请求不会删除数据。 + +## 六、边界行为 + +未登录或登录失效按认证失败处理;必须检查响应体 `code`、`success`,不能仅凭 HTTP 200 判断保存成功。既有主体资料不完整时,账户编辑同样会被必填校验拒绝。 + +## 六.5、枚举 / 数据字典 + +### `accountType` + +| 值 | 中文 | 说明 | +|---|---|---| +| `CORPORATE` | 对公 | 必填账户类型之一 | +| `PERSONAL` | 对私 | 必填账户类型之一 | + +### `settleMode` + +| 值 | 中文 | 说明 | +|---|---|---| +| `PREPAY` | 预付 | 账期须为空 | +| `MONTHLY` | 月结 | 必填账期 | +| `SINGLE` | 单次结算 | 账期须为空 | +| `null` | 未登记 | 账期须为空 | + +### `invoiceType` + +| 值 | 中文 | 说明 | +|---|---|---| +| `SPECIAL` | 专票 | 必填税率 | +| `NORMAL` | 普票 | 必填税率 | +| `NONE` | 不开票 | 税率须为空 | +| `null` | 未登记 | 税率须为空 | + +## 六.6、修改前后对比 + +本次补充文档,后端无新增变更。 + +| 字段 / 行为 | 旧 #6669 说明 | 当前契约 | +|---|---|---| +| `initialAccounts: []` | 可清空账户 | #7087 起拒绝,必须保留账户 | +| 草稿 `changeReason` | 必填 | #6684 起可省略 | +| `expectedUpdateTime` | 必填 | 仍必填,使用供应商主体版本 | +| 独立账户修改 / 删除 | 无独立接口 | 仍无独立接口;草稿修改走主体更新 | + +## 六.7、影响评估 + +- 本次没有新增兼容性变化;前端须遵守已部署的账户非空约束。 +- 无需与后端同步上线;清理旧的 `[]` 删除调用,按上述状态控制编辑入口。 + +## 七、不影响范围 + +本次说明覆盖草稿初始账户维护;新增账户审批、默认账户切换和合同契约保持现状。 + +## 八、测试环境已验证 + +- 既有业务实测:#6654 最终证据记录草稿账户修改、可选字段清空与版本失败零写入;#7087 记录显式空账户被拒绝、至少一项账户保存成功。旧证据中的整项清空已被 #7087 覆盖。 +- 本次于 2026-09-06 通过 TEST Gateway 只读核对 Resource Swagger:主体更新路径及账户请求/摘要字段存在,未发布独立账户修改、删除路径;同时核对最新 `dev-v3` 源码。此次未重复执行共享环境业务写操作。 + +## 十、相关文档 + +- [账户修改既有实测 #6654](https://git.1814.love:8443/wx/HL/issues/6654#issuecomment-43820) +- [账户非空约束与实测 #7087](https://git.1814.love:8443/wx/HL/issues/7087#issuecomment-46744) +- [草稿免填变更原因 #6684](https://git.1814.love:8443/wx/HL/issues/6684) + +## 关联 / 联系人 + +- **Issue**: [#7087](https://git.1814.love:8443/wx/HL/issues/7087) +- **PR**: [#7093](https://git.1814.love:8443/wx/HL/pulls/7093) +- **后端负责人**: @lc