Files
2026-03-18 11:34:02 +08:00

5.1 KiB

Contract 领域重构指南

1. 范围

本文档只做 Contract 领域的项目侧梳理。

当前优先关注:

  • contract.contract_type
  • contract.code
  • contract.currency

2. 字段盘点

2.1 contract_type

当前实现:

  • app/modules/contract/enums.py 定义了 ContractType
  • 取值:productserviceproject
  • Contract 模型里是 String
  • ContractCreate 里是 str | None
  • 同步 schema schemas/contract/contract.py 里也是 str

当前使用:

  • 是合同主表核心分类字段
  • 合同结算服务里会按 contract_type == "project" 分支处理工程类合同

项目侧取值范围:

  • product
  • service
  • project

集团侧差异:

  • 集团侧 enum_config.Contract.contract_type 当前只有 productservice
  • 项目侧比集团侧多一个 project
  • 同步 schema 当前没有把它收紧成 enum

结论:

  • 保留为代码 enum
  • 先统一“是否正式保留 project

2.2 code

当前实现:

  • 模型里是普通 String
  • 没有本地正式 enum
  • 初始化侧实际依赖 contract_config / contract_code_dict / supply_chain_group

当前使用:

  • 初始化合同时,code 承担业务子类型编码职责,例如 EPCPCKYJL
  • 不是单纯的“自由合同编号”

项目侧取值范围:

  • 当前无法从单一代码 enum 列出权威全集
  • 本地已明确出现的典型值包括:EPCPCPFCGOSCKYJLESCYWZJTYNBXBZBGSCNQT

集团侧差异:

  • 集团侧 enum_config.Contract.code 已明确把这类值当成正式候选项,并且按项目类型变化
  • 同步 schema 里的 code 仍是普通 str
  • 项目侧现在没有把这组值沉成统一的字段配置或正式 enum

结论:

  • 不建议继续当自由字符串处理
  • 更适合迁到 field_config,或至少统一走配置表来源

2.3 currency

当前实现:

  • 模型里是 String
  • 默认值 CNY
  • schema 里是普通字符串

当前使用:

  • 当前主要是合同基础信息字段
  • 没看到复杂分支逻辑

项目侧取值范围:

  • 当前代码里唯一明确值是默认值 CNY

集团侧差异:

  • 当前没看到集团侧 enum_config 对这个字段给出正式候选项
  • 同步 schema 里也是 str

结论:

  • 先保持字符串字段
  • 如果未来真的出现多币种,再决定是否需要正式枚举

3. 重点结论

  • contract_type 应保留为代码 enum,但要先明确是否保留 project
  • code 当前实际上承担合同业务子类型职责,不应继续当自由字符串处理。
  • currency 当前没有足够证据说明要做枚举化。

4. 待修改项清单

  1. 统一 ContractType 的正式定义源。
  2. 确认 contract_type=project 是否继续作为正式值保留。
  3. contract_type 在 schema 层补 enum 校验。
  4. contract.code 从“自由字符串”改成统一配置来源。
  5. 评估 contract.code 是否直接迁到 field_config
  6. 区分清楚 contract.code 与“合同编号/contract_sn”的职责,避免一个字段同时承担两层语义。

5. 按本轮要求的改造落点

contract 领域本轮要直接收口 3 条链路:

  • 初始化
  • create 校验
  • 下拉列表

5.1 初始化

当前合同初始化已经走 contract_config

因此这轮初始化改造的核心不是重做合同初始化,而是:

  • contract.code 明确成正式字段级配置来源
  • 后续让合同初始化、物资初始化、前端下拉都围绕这套配置工作

contract_type 继续保留为代码 enum,不迁到 field_config

5.2 Create 校验

当前 ContractService.create() 的校验主要依赖:

  • contarct_type_dict
  • contract_code_dict
  • service / product 的硬编码白名单

这和初始化使用的 contract_config 不是同一真源。

本轮目标是:

  • contract_type 继续按代码 enum 校验
  • contract.code 改成通过新的 config 工具校验
  • 避免继续新增 if contract_type == ... and code in [...] 这种硬编码白名单

5.3 下拉列表

当前合同下拉接口:

  • /contract/type/list
  • /contract/sub-type/list

其中:

  • type/list 直接读代码字典
  • sub-type/list 先写死过滤列表,再读代码字典

这和初始化 contract_config 不一致。

本轮目标是:

  • 合同类型列表继续由代码 enum 提供
  • 合同子类型列表改为动态读取 config
  • 保证前端看到的 code 列表和初始化、create 校验同源

5.4 清理项

本轮 contract 领域改造完成后,应清理:

  • 只用于 contract.code 下拉和校验的旧硬编码 code 白名单
  • 只承担旧合同子类型翻译的代码字典入口

但下面这些不应误删:

  • ContractType enum
  • 其它真正稳定的固定语义 enum

6. 测试关注点

contract 领域 service 层集成测试至少覆盖:

  1. 初始化:contract_config 能正确初始化合同,并继续驱动下游结算/物资链路。
  2. 下拉:合同子类型下拉是否来自目标 config,且与初始化 code 集一致。
  3. Create:合法 contract_type + code 创建成功,非法 code 明确报错。