frontend_status verified,frontend_ref f5414b12,target_release v2.1。
15 KiB
schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
| schema | ticket | title | consumer | author | change_type | backend_status | gateway_status | frontend_status | frontend_owner | frontend_ref | target_release | verified_at | status_note | updated_at | base |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hl-changelog/v2 | 6842 | 供应商补充合同字段与附件 | admin | lc(GIT) | 修改接口 | deployed | verified | verified | hl-admin | f5414b12 | v2.1 | 2026-09-01 | PR #6858 已合并 dev-v3,hl-resource-service 已部署提交 5546d7907c6eda9b372b4639094f84e568de6496。TEST Gateway 已验证完整字段与全空业务字段合同的新增、更新、详情回读,以及单个 PDF 上传、预览、下载和清理。前端 hl-admin v2.1 提交 f5414b12 已交付:ContractEditModal 增 businessLine/relatedMainContract/autoRenew(三态,false 不按空过滤)+SIGNED 选项,scanFileUrl 改 FileUpload 文件中心单附件(upload/token→confirm 写 ossUrl),隐藏 contractType/amount/pricingMode/settleCycle/remark 但编辑原样回传防整份替换误清;ManageModal 列重排契约固定集、SIGNED→已签约、有效期直拼上海日历日、附件预览带登录态 preview-by-url/下载直开永久地址;api/file.js 加 getContractPreviewBlobUrl。spec 编辑 16 例+管理 6 例绿。当前状态:后端已就绪,前端已交付。 | 2026-09-01 | dev-v3 |
供应商补充合同字段与附件
供应商补充合同新增 businessLine、relatedMainContract、autoRenew,并允许写入 SIGNED(已签约)。所有合同业务字段均可为空,只有 changeReason 继续必填。
管理端登记页仅展示补合同编号、状态、合同名称、业务线、有效期、签署日期、关联主合同、自动续约和单个 Word/PDF 附件;其他兼容字段隐藏。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | 独立登记供应商合同 | POST | /admin/supplier/items/{supplierId}/contracts/add |
扩展请求与响应 | 增加三个字段,状态支持 SIGNED |
| 2 | 独立更新供应商合同 | PUT | /admin/supplier/items/{supplierId}/contracts/{contractId}/update |
扩展请求与响应 | 新字段支持补录、清空和 false |
| 3 | 查询供应商基本信息 | GET | /admin/supplier/items/{supplierId}/basic-info/view |
扩展响应 | contracts[] 完整回读补充合同字段 |
三、接口详情
1. 独立登记供应商合同 POST /admin/supplier/items/{supplierId}/contracts/add
VO: SupplierContractCreateReqVO / SupplierContractRespVO
使用场景
供应商已创建后登记一份补充合同;业务资料未齐时也可只提交审计原因,稍后再补录。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
supplierId |
Path | String | 是 | 正整数 ID 字符串 | 目标供应商 |
contractNo |
Body | String/null | 否 | 最长 100 | 补合同编号 |
status |
Body | String/null | 否 | DRAFT / ACTIVE / SIGNED / EXPIRED |
SIGNED 显示为“已签约” |
contractName |
Body | String/null | 否 | 最长 500 | 合同名称 |
businessLine |
Body | String/null | 否 | 最长 100 | 业务线,自由文本 |
startDate |
Body | String/null | 否 | yyyy-MM-dd |
有效期开始日 |
endDate |
Body | String/null | 否 | yyyy-MM-dd |
有效期结束日;两端都有值时不得早于开始日 |
signDate |
Body | String/null | 否 | yyyy-MM-dd |
合同签署日期 |
relatedMainContract |
Body | String/null | 否 | 最长 100 | 关联主合同外部引用 |
autoRenew |
Body | Boolean/null | 否 | true / false / null |
是 / 否 / 未登记 |
scanFileUrl |
Body | String/null | 否 | 最长 1000 | 文件中心确认上传后返回的永久 ossUrl |
changeReason |
Body | String | 是 | 去空白后非空,最长 500 | 登记原因,写入审计 |
contractType、amount、pricingMode、settleCycle、remark 仍兼容但本页面隐藏,也均可为空。
出参
| 字段 | 类型 | 说明 |
|---|---|---|
data.contractId |
String | 合同 ID |
data.contractNo |
String/null | 补合同编号 |
data.status |
String/null | 包含新增可写值 SIGNED |
data.contractName |
String/null | 合同名称 |
data.businessLine |
String/null | 业务线 |
data.startDate / data.endDate |
String/null | 有效期日期 |
data.signDate |
String/null | 签署日期 |
data.relatedMainContract |
String/null | 关联主合同 |
data.autoRenew |
Boolean/null | 自动续约三态值 |
data.scanFileUrl |
String/null | 合同附件永久地址 |
data.updateTime |
String | 当前合同版本,格式 yyyy-MM-dd HH:mm:ss |
请求示例
{
"contractNo": "SHCT2025070102599446",
"status": "SIGNED",
"contractName": "内蒙古牵手草原国际旅行社有限公司额外后返",
"businessLine": null,
"startDate": "2010-01-01",
"endDate": "2099-12-31",
"signDate": "2025-07-01",
"relatedMainContract": "2185933",
"autoRenew": true,
"scanFileUrl": "https://files.example.com/supplier-contract/example.pdf",
"changeReason": "补录已签约合同"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"contractId": "2095000000000000001",
"contractNo": "SHCT2025070102599446",
"status": "SIGNED",
"contractName": "内蒙古牵手草原国际旅行社有限公司额外后返",
"businessLine": null,
"startDate": "2010-01-01",
"endDate": "2099-12-31",
"signDate": "2025-07-01",
"relatedMainContract": "2185933",
"autoRenew": true,
"scanFileUrl": "https://files.example.com/supplier-contract/example.pdf",
"updateTime": "2026-08-31 12:00:00"
}
}
空数据 / 降级响应
仅提交 changeReason 也可成功;所有合同业务字段返回 null,前端不得补默认状态或日期。
错误响应
{
"code": 400,
"message": "变更原因不能为空",
"success": false,
"data": null
}
业务边界
- 所有合同业务字段可空;
changeReason不属于业务展示字段,继续必填。 startDate、endDate同时有值时才校验日期先后。scanFileUrl只保存一个附件永久地址;上传、预览、下载复用文件中心。
2. 独立更新供应商合同 PUT /admin/supplier/items/{supplierId}/contracts/{contractId}/update
VO: SupplierContractUpdateReqVO / SupplierContractRespVO
使用场景
补齐、修改或清空已登记合同。该接口为完整替换,省略或传 null 会清空对应字段。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
supplierId |
Path | String | 是 | 正整数 ID 字符串 | 目标供应商 |
contractId |
Path | String | 是 | 正整数 ID 字符串 | 目标合同 |
| 新增接口全部业务字段 | Body | 对应类型/null | 否 | 与新增一致 | 完整替换;autoRenew=false 会保留为否 |
expectedUpdateTime |
Body | String/null | 否 | yyyy-MM-dd HH:mm:ss |
提供时必须匹配当前版本 |
changeReason |
Body | String | 是 | 去空白后非空,最长 500 | 更新原因 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
data.contractId |
String | 原合同 ID |
data.businessLine |
String/null | 更新后的业务线,空白规范为 null |
data.relatedMainContract |
String/null | 更新后的关联主合同 |
data.autoRenew |
Boolean/null | 精确保留 true、false 或 null |
data.status |
String/null | 可返回 SIGNED |
| 其余合同业务字段 | 对应类型/null | 完整替换后的值 |
data.updateTime |
String | 更新后的合同版本 |
请求示例
{
"contractNo": "SHCT2025070102599446",
"status": "SIGNED",
"contractName": "内蒙古牵手草原国际旅行社有限公司额外后返",
"businessLine": null,
"startDate": "2010-01-01",
"endDate": "2099-12-31",
"signDate": "2025-07-01",
"relatedMainContract": null,
"autoRenew": false,
"scanFileUrl": "https://files.example.com/supplier-contract/example.pdf",
"changeReason": "调整自动续约信息"
}
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"contractId": "2095000000000000001",
"contractNo": "SHCT2025070102599446",
"status": "SIGNED",
"businessLine": null,
"relatedMainContract": null,
"autoRenew": false,
"updateTime": "2026-08-31 12:00:01"
}
}
空数据 / 降级响应
仅提交 changeReason 可把全部业务字段清空;与当前内容完全相同时拒绝空更新,不生成新版本。
错误响应
{
"code": 395054,
"message": "合同有效期开始日期不能晚于结束日期",
"success": false,
"data": null
}
业务边界
- 页面隐藏兼容字段时,编辑既有合同应从详情原样回传其
contractType、amount、pricingMode、settleCycle、remark,避免完整替换误清历史值。 autoRenew=false是有效业务值,不能按空值过滤。expectedUpdateTime可省略;提供过期值时返回395014,合同保持不变。
3. 查询供应商基本信息 GET /admin/supplier/items/{supplierId}/basic-info/view
VO: SupplierBasicInfoRespVO / SupplierContractRespVO
使用场景
进入供应商编辑或详情页时,从 data.contracts[] 回显合同表格和附件操作。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
supplierId |
Path | String | 是 | 正整数 ID 字符串 | 目标供应商 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
data.contracts |
Array | 当前有效合同,按合同 ID 升序 |
data.contracts[].businessLine |
String/null | 业务线 |
data.contracts[].relatedMainContract |
String/null | 关联主合同 |
data.contracts[].autoRenew |
Boolean/null | 自动续约三态值 |
data.contracts[].status |
String/null | SIGNED 显示为“已签约” |
data.contracts[].scanFileUrl |
String/null | 单个合同附件永久地址 |
| 其余合同字段 | 对应类型/null | 与新增、更新响应一致 |
请求示例
GET /admin/supplier/items/2095000000000000000/basic-info/view
Authorization: Bearer <admin-token>
响应示例
{
"code": 200,
"message": "成功",
"success": true,
"data": {
"supplierId": "2095000000000000000",
"contracts": [
{
"contractId": "2095000000000000001",
"contractNo": "SHCT2025070102599446",
"status": "SIGNED",
"contractName": "内蒙古牵手草原国际旅行社有限公司额外后返",
"businessLine": null,
"startDate": "2010-01-01",
"endDate": "2099-12-31",
"signDate": "2025-07-01",
"relatedMainContract": "2185933",
"autoRenew": true,
"scanFileUrl": "https://files.example.com/supplier-contract/example.pdf"
}
]
}
}
空数据 / 降级响应
没有合同记录时 contracts=[];合同存在但某项未登记时,对应字段为 null。
错误响应
{
"code": 395001,
"message": "供应商不存在",
"success": false,
"data": null
}
业务边界
- 日期均为上海业务日字符串,前端按
yyyy-MM-dd原样展示,不做 UTC 日期转换。 - 查询只返回未删除合同;附件为空时隐藏预览、下载操作。
- 未登录请求由 Gateway 返回业务码
401。
四、契约约束与正确调用方式
- 表格列固定映射为
contractNo、status、contractName、businessLine、startDate/endDate、signDate、relatedMainContract、autoRenew、scanFileUrl;SIGNED展示“已签约”。 startDate/endDate直接按上海日历日拼成有效期;autoRenew=true可显示“到期自动续约”,false显示“否”,null显示未登记占位。- 附件复用文件中心:申请上传凭证
POST /admin/file/upload/token,按返回模式上传后调用POST /admin/file/upload/confirm,把确认响应的data.ossUrl写入scanFileUrl。组件仅保留一个.doc、.docx或.pdf文件。 - 预览使用带登录态的
GET /admin/file/preview-by-url?url={encodeURIComponent(scanFileUrl)};下载直接访问scanFileUrl。 - 本页面隐藏
contractType、amount、pricingMode、settleCycle、remark;编辑历史合同时仍从详情原样回传,避免完整替换清空旧值。
五、数据库行为
这里只约定外部可观察结果:新增或更新成功后,再次请求基本信息详情可读到相同字段;未填写值返回 null,autoRenew=false 不会丢失。失败响应不产生部分合同变更。
六、边界行为
- 所有合同业务字段可空,只有新增、更新、删除操作的
changeReason必填。 SIGNED仅是新增可写状态,不改变既有DRAFT、ACTIVE、EXPIRED和历史TERMINATED的兼容读取。- 日期两端都有值且开始日晚于结束日时返回
395054,整次更新零写入。 - 附件字段为单值;前端负责限制为一个 Word/PDF,并在替换附件后提交新的永久地址。
- 写接口沿用既有角色、权限、幂等、锁和审计规则,无新增错误码。
六.6、修改前后对比
| 项目 | 修改前 | 修改后 |
|---|---|---|
| 业务线、关联主合同、自动续约 | 无字段 | 新增 businessLine、relatedMainContract、autoRenew,均可空 |
| 合同状态 | 可写 DRAFT / ACTIVE / EXPIRED |
追加可写 SIGNED(已签约) |
| 详情回读 | 无新增三字段 | contracts[] 完整回读新增三字段 |
| 其他合同业务字段 | 可空 | 继续可空,语义不变 |
六.7、影响评估
- 是否破坏向后兼容:否,均为可选字段和状态枚举扩展。
- 前端是否必须同步上线:是,需要新增列、附件控件和
SIGNED中文映射,并隐藏非目标字段。 - 前端 workaround 清理点:不要在本地拼装缺失字段;以详情
contracts[]为回显真相。
七、不影响范围
- 不修改供应商主体、联系人、资质、结算账户、审批和归档接口。
- 不把合同并回供应商注册聚合;仍先取得
supplierId,再调用独立合同接口。 - 不新增 Gateway 路由、权限点、配置、Redis 或 MQ 契约。
八、测试环境已验证
- 已在 TEST Gateway 验证完整字段和仅含
changeReason的合同均可新增并跨请求回读;SIGNED、null、false、日期错误零写入均符合本契约。 - 已验证一个 PDF 经文件中心上传后可预览、下载,验收产生的合同、附件和会话均已清理。
当前状态
- 后端:已部署并已验证。
- 前端:待处理。