Files
zkxw/docs/superpowers/specs/2026-10-12-presign-protocol-no-auto-allocate-design.md
T
2026-10-13 15:18:01 +08:00

3.7 KiB
Raw Blame History

预签约订单协议编号自动发号 — 设计说明

日期: 2026-10-12
状态: 已确认
范围: Web 管理端预签约、市场移动端(微信小程序 WebView / mobile-oa-h5)、后端发号与唯一性

1. 背景与目标

预签约订单「协议编号」当前为可选手填;未填时列表显示 -,仅在转正式协议时才可能自动生成。业务需要:

  1. 新增保存时自动生成协议编号(与正式采集协议同一发号规则)。
  2. 编辑不可改号;历史空号在编辑保存时补发。
  3. 新增/编辑弹窗不再展示该字段;列表仍展示并可搜索。
  4. 租户内全局唯一:采集协议号、科研捐赠号、预签约协议号互斥占用。
  5. 转正式直接使用预签订单上已有编号。

2. 决策摘要

项 决策
发号时机 新增保存必发;编辑保存仅空号补发
客户端改号 忽略请求体中的 protocolNo / protocol_no
发号实现 复用 allocate_next_biz_no(kind="collection")(XBCC + YYYYMMDD + 6 位序号)
唯一性 扩展 assert_biz_no_available,纳入未删除预签约 protocol_no
UI Web / 移动端表单隐藏字段;列表保留
转正式 继续 protocol_no=order.protocol_no or "";空号兜底发号不变

3. 后端行为

3.1 创建 create_presign_order

  • 不读取客户端协议编号。
  • 在写入前:protocol_no = allocate_next_biz_no(..., kind="collection")(已含唯一性断言)。
  • 保证创建成功后订单必有非空 protocol_no。

3.2 更新 update_presign_order

  • 从可写 mapping 中移除 protocol_no / protocolNo。
  • 若当前 obj.protocol_no 为空(或仅空白):补发号并写回。
  • 若已有非空号:保持不变。

3.3 唯一性 assert_biz_no_available

在现有「采集协议 + 科研捐赠」校验之外:

  • 查询同租户、del_flag=0 且 protocol_no 相等的预签约订单。
  • 新增参数 exclude_presign_order_id:更新/转正式时排除自身。
  • 冲突时抛出与现有一致风格的 ValueError(如「协议编号已存在」)。

发号路径(allocate_next_biz_no)与转正式创建协议路径共用该函数,从而预占号不会被正式单或其它预签单占用。

3.4 转正式 convert_to_protocol

保持现逻辑:优先用订单号;空号时由 create_collection_protocol 发号并回写预签订单。新建单不应再走空号分支。

4. 前端

4.1 Web(web-admin)

  • PresignOrderFormDialog.vue:移除「协议编号」表单项;提交 payload 不再传 protocolNo。
  • 列表页:保留「协议编号」列与搜索关键字。

4.2 移动端 / 小程序 WebView(mobile-oa-h5)

  • PresignOrderForm.vue:移除协议编号输入。
  • presign-form-state.js 及契约测试:表单字段列表去掉可编辑的 protocolNo(详情/列表展示仍可用接口返回值)。
  • 列表卡片继续展示协议编号。

5. 测试要点

  • 创建预签:返回非空 protocolNo;客户端传入自定义号被忽略。
  • 更新:已有号不被客户端篡改;空号更新后补齐。
  • assert_biz_no_available:预签已占号时,正式协议/捐赠/另一预签均不可再用同一号。
  • 转正式:使用预签上已有号,正式协议 protocolNo 一致。
  • 前端契约:表单视图字段不含协议编号输入。

6. 非目标

  • 不为历史未编辑空号单做离线批量补号脚本(依赖编辑保存或转正式兜底)。
  • 不改发号格式前缀/位数。
  • 不在 DB 层新增唯一索引(软删除下多 NULL 与历史空号使强制唯一索引复杂;以应用层校验为准,与正式协议现状一致)。