文件
hl-api-changelog/changelogs-v2/2026-08/24_6275_供应商联系人默认规则与角色字典校验-修改接口-管理后台.md
T
2026-08-24 22:49:05 +08:00

8.7 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 6275 供应商联系人默认规则与角色字典校验 admin lc(GIT) 修改接口 deployed verified verified mmg f8a0d72d PR #6276 已合并 dev-v3,合并提交 f7b442b67 已由部署任务 #785ce882 发布到 TEST 并经 Gateway 验证。非空联系人快照现在始终归一为且仅为一个默认联系人;联系人角色按 sup_content_role 当前 ACTIVE 字典值校验。管理端待将角色/职务改为动态下拉并适配新的默认联系人规则。 2026-08-24 dev-v3

供应商联系人默认规则与角色字典校验

供应商创建、草稿更新和注册提交统一收紧联系人契约:联系人列表非空时,服务端保证最终恰好一个默认联系人;联系人角色必须使用字典 sup_content_role 当前启用项的 dictValue。本记录覆盖 #6258 中“允许没有默认联系人、取消或删除后不自动选举”的旧语义。

变更接口

方法 路径 行为变化
POST /admin/supplier/items/add 非空 contacts 未显式选择默认项时,服务端将请求第一项设为默认;联系人角色按生效字典校验
PUT /admin/supplier/items/{supplierId}/update 非空联系人快照最终未保留或选中默认项时,请求第一项自动成为默认;显式提交的角色按生效字典校验
POST /admin/supplier/items/{supplierId}/submit 完整联系人快照执行相同的唯一默认归一和角色字典校验;失败发生在主体、联系人和审批写入前
GET /admin/supplier/items/{supplierId}/basic-info/view 返回服务端归一后的 contacts[].isPrimary 和已保存的 contacts[].contactRole;电话仍仅返回 contactPhoneMask

管理端角色下拉继续使用既有通用字典接口,该接口本工单未修改:

方法 路径 用途
GET /admin/dict/data/sup_content_role 获取联系人角色选项;展示 dictLabel,提交 dictValue,仅使用 status=ACTIVE 的项

业务失败可能仍返回 HTTP 200,调用方必须同时判断统一响应中的 code、success、message 和 data。

默认联系人规则

  • contacts 为非空列表时,保存后必须且只会有一个 isPrimary=true。
  • 只有一个联系人时,即使请求传 false、null 或省略 isPrimary,该联系人也会成为默认联系人。
  • 多个联系人且没有任何项传 true 时,按请求数组顺序将第一项设为默认联系人。
  • 恰好一个联系人传 true 时保留该选择。
  • 两个及以上联系人传 true 时返回业务码 400、消息 同一供应商只能设置一个默认联系人,整次请求零写入。
  • 草稿增量更新中,已有联系人省略 isPrimary 时优先保留原默认状态;显式传 false 表示取消。若删除或取消原默认联系人后没有其他默认项,则请求列表第一项自动成为默认。
  • 增量更新的 contacts=null 或省略字段表示联系人不变;contacts=[] 表示清空联系人,空列表允许零默认联系人。
  • 客户端应在提交后重新读取详情,以服务端返回的 isPrimary 为最终状态。

创建或完整提交示例(两个联系人均未选择默认):

{
  "contacts": [
    {
      "contactName": "联系人甲",
      "contactPhone": "13800000001",
      "contactRole": "contentBus",
      "isPrimary": false
    },
    {
      "contactName": "联系人乙",
      "contactPhone": "13800000002",
      "contactRole": "contentMoney",
      "isPrimary": false
    }
  ]
}

保存后详情中的第一项为默认联系人:

{
  "contacts": [
    {
      "contactName": "联系人甲",
      "contactPhoneMask": "138****0001",
      "contactRole": "contentBus",
      "isPrimary": true
    },
    {
      "contactName": "联系人乙",
      "contactPhoneMask": "138****0002",
      "contactRole": "contentMoney",
      "isPrimary": false
    }
  ]
}

Long 类型的 contactId 继续按字符串传输;更新已有联系人仍需携带详情返回的 expectedUpdateTime。

联系人角色字典规则

  • 创建和注册提交的每个联系人都必须提供非空 contactRole,值必须精确匹配 sup_content_role 当前 status=ACTIVE 项的 dictValue。
  • 草稿增量更新已有联系人时,省略 contactRole 表示保持原值,不会因为本次无关更新而额外依赖字典;新增联系人或显式修改角色时必须提交生效的 dictValue。
  • 空白、未知或已停用值返回业务码 400、消息 联系人角色不合法或已停用,失败请求不修改供应商或联系人。
  • 字典服务异常、响应失败、空数据或没有启用项时失败关闭,返回“联系人角色字典暂不可用,请稍后重试”,不降级为硬编码选项。
  • TEST 当前可见项为 contentBus(业务人员)和 contentMoney(财务人员),仅用于联调示例;客户端必须动态读取字典,不能将这些值固化在代码中。

字典响应示例:

{
  "code": 200,
  "success": true,
  "data": [
    {
      "dictType": "sup_content_role",
      "dictLabel": "业务人员",
      "dictValue": "contentBus",
      "sortOrder": 1,
      "status": "ACTIVE"
    }
  ]
}

管理端接入事项

  1. “角色/职务”字段改为下拉框,进入联系人页面时请求 /admin/dict/data/sup_content_role,展示 dictLabel、提交 dictValue,过滤非 ACTIVE 项。
  2. 单联系人场景将该联系人呈现为默认;多联系人可选择一个默认联系人,但不可同时选择多个。未选择时服务端会把请求第一项设为默认。
  3. 新增、删除、拖动或调整联系人顺序后,提交数组顺序应与界面顺序一致;保存成功后重新读取详情并以服务端返回值刷新默认标识。
  4. 更新已有联系人时,未修改角色可省略 contactRole;新增联系人必须提交从字典选择的角色值。

未变化范围

  • 不新增接口、Gateway 路由、数据库 migration、字典数据、菜单权限、角色、状态机或审批节点。
  • 不改变联系人电话加密存储、脱敏输出、软删除、审计、聚合锁、幂等与乐观版本语义。
  • 不修改配置、Redis Key 或 MQ 契约,也不回填历史联系人数据。
  • 本工单只交付后端;管理端代码未在后端仓库修改,前端状态保持 pending 直至完成上述接入并提供验证提交。

验证证据

  • 自动化:默认联系人写入 16 项、应用服务 14 项、角色字典 11 项、聚合校验 6 项,共 47 项定向测试零失败;Resource 全量 1966 项零失败,38 项仓库既有条件跳过。
  • 合并后独立审计:在目标提交上重新执行 47 项定向测试,零失败且未发现确定性缺口。
  • TEST 部署:部署任务 #785ce882 成功,hl-resource-service 的 8082、8182 实例滚动重启并恢复健康;部署服务器 HEAD 1f2e0ac6d 包含目标合并提交 f7b442b67。
  • TEST Gateway:使用真实管理员会话验证单联系人自动默认、多联系人无选择时第一项默认、删除默认后重新选举、角色省略保持原值、清空联系人、重复默认与非法角色零写入、提交失败零审批副作用;未认证请求返回业务码 401。
  • 清理:合成供应商草稿已通过既有删除接口清理,精确查询结果为 0;未产生外部文件、Redis、MQ 或配置副作用。

撤回

  1. 从最新 dev-v3 创建回退分支,执行 git revert -m 1 --no-edit f7b442b67f4d989fac6b29a771331ca6d66148e3,经独立 PR 合入。
  2. 重新构建并滚动部署 hl-resource-service;本次没有数据库、字典数据、配置、Redis 或 MQ 变更,无需执行 DDL、DML 或数据恢复。
  3. 回退后恢复 #6258 的旧语义:允许联系人列表非空但没有默认联系人,角色不再由后端按 sup_content_role 动态校验;接口路径和字段结构不变。
  4. 经 Gateway 复测创建、更新、提交和详情接口,确认回退后的默认联系人语义、角色传值、电话脱敏、权限和失败零写入符合目标版本。
  5. 若管理端已上线本次交互,应同步停止依赖“服务端必定选出一个默认联系人”的保证;字典下拉仍可继续使用既有通用字典接口,但需按回退版本确认提交兼容性。

关联 / 联系人