# Material 领域重构指南 ## 1. 范围 本文档只做 Material 主表梳理。 当前优先关注: - `material.material_type` - `material.status` - `material.supply_status` - `material.approval_party` ## 2. 字段盘点 ### 2.1 `material_type` 当前实现: - 本地没有独立 enum 类 - 主要来源是 `contract_product_type_list` - 模型里是 `String` - 创建 schema 里是 `str` - 同步 schema 里也是 `str` 当前使用: - 是物资主类型字段 - schema 示例和业务逻辑都直接依赖 `contract_product_type_list` 项目侧取值范围: - 当前本地明确值:`TY`、`ZJ`、`NB`、`XB`、`ZB`、`GS`、`CN`、`DL`、`XT`、`CBJDB`、`SX`、`ECXT`、`QT` 集团侧差异: - 集团侧 `enum_config.Material.material_type` 是按项目类型变化的 - 光伏下有:`ZJ`、`TY`、`NB`、`XB`、`ZB`、`GS`、`CN`、`QT` - 陆风/海风下有:`FJ`、`TT`、`XB`、`ZB`、`GS`、`CN`、`QT` - 项目侧当前使用的本地列表明显偏光伏,且代码里还存在命名差异:例如本地用 `XT` / `CBJDB` / `SX` / `ECXT`,集团侧常见的是 `35KV` / `CYJD` / `SVG` / `ECPG` - 同步 schema 里 `material_type` 仍是 `str` 结论: - 应迁到 `field_config` - 不能继续只靠本地 `contract_product_type_list` ### 2.2 `status` 当前实现: - 模型里是 `SmallInteger` - 同步 schema 里是 `Optional[int]` 项目侧取值范围: - 当前未看到单独 enum 类 - 现有注释和使用都表明它是数值状态字段 集团侧差异: - 集团侧 `enum_config.Material.status` 给的是 `-1`、`0`、`1` - 项目侧没有在 material 模块里沉成统一常量 结论: - 应统一正式状态定义源 ### 2.3 `supply_status` 当前实现: - 模型里是 `SmallInteger` - 本地有 `SupplyStatus` enum:`-1`、`0`、`1`、`None` 项目侧取值范围: - `-1` - `0` - `1` - `None` 集团侧差异: - 集团侧 Material.status 也是按 `-1`、`0`、`1` 表达进度状态 - 项目侧存在 `status` 和 `supply_status` 两个相近字段,语义有重叠 结论: - 需要明确 `status` 和 `supply_status` 哪个才是正式推送字段 ### 2.4 `approval_party` 当前实现: - 模型里是 `String` - schema 里是 `str` - 当前示例值是 `jiagong`、`yigong` 项目侧取值范围: - `jiagong` - `yigong` 集团侧差异: - 当前没看到集团侧 `enum_config` 对这个字段给出正式候选项 - 同步 schema 里也没有这个字段 结论: - 先保留本地代码级候选项 - 后续如需推送再决定是否外提 ## 3. 重点结论 - `material_type` 是标准的 `field_config` 候选字段,不能再继续绑死在本地光伏型列表上。 - `status` 与 `supply_status` 当前语义重叠,必须先定正式推送字段。 - `approval_party` 暂时还是本地专有字段,不需要现在就硬并到集团侧。 ## 4. 待修改项清单 1. 将 `material_type` 正式迁到 `field_config`。 2. 按项目类型重建 `material_type` 候选项,不再只用本地光伏型列表。 3. 统一 `35KV/XT`、`CYJD/CBJDB`、`SVG/SX`、`ECPG/ECXT` 这类命名差异。 4. 明确 `status` 与 `supply_status` 的职责边界。 5. 为 `material_type` 在 schema 层增加统一校验入口。 ## 5. 按本轮要求的改造落点 material 是本轮最需要针对性改造的领域之一,因为它当前同时存在: - 初始化来源分叉 - create 校验分叉 - 下拉来源分叉 ### 5.1 初始化 当前 material 初始化不是单源: - 候选项来自 `contract_config` 里的 product 合同 - 单位和部分展示信息来自 `material_contract_{project_type}` dict 而且 `unit` 现在还挂在 dict `remark` 上。 本轮目标是: - 明确 `material.material_type` 的正式配置来源 - 把 `label`、`unit`、`parts` 等附属字段纳入正式 config 结构 - 去掉“从 dict remark 补单位”这种不适当用法 ### 5.2 Create 校验 当前 create 路径里: - `material_type` 入参本身没有正式 config 校验 - `show_name`、`unit` 由 `contract_product_type_list` 反查 - 随后又会调用合同创建,由合同 service 再做一层 code 白名单校验 这说明 material create 现在不是单一入口校验。 本轮目标是: - 在 `MaterialService.create()` 开头基于 config 校验 `material_type` - 用 `get_field_option_map()` 之类的方法直接拿 `label`、`unit`、`parts` - 不再依赖 `contract_product_type_list` 和默认兜底值 ### 5.3 下拉列表 当前物资下拉已经部分走 config: - `/material/material-types` 读 `material_types` - `/material-detail/contract-product-type/list` 也读 `material_types` 但模块里仍保留了旧的硬编码路径: - `get_material_info_by_code()` - `get_kit_options()` - `contract_product_type_list` 本轮目标是: - 让物资类型和部件列表统一从新的 config 工具返回 - 下拉、初始化、create 校验全部围绕同一套 `material_type` 配置 ### 5.4 清理项 material 领域这轮改造完成后,应优先清理: - `material_contract_*` 中用 `remark` 承载单位的旧逻辑 - `contract_product_type_list` 里只服务于 `material_type` 真源的旧定义 - `get_material_info_by_code()` 这类旧反查入口 ## 6. 测试关注点 material 领域 service 层集成测试至少覆盖: 1. 初始化:项目初始化后 material 的 `material_type`、`show_name`、`unit` 是否来自目标 config。 2. 下拉:物资类型和部件列表是否来自同一 config,且与初始化同源。 3. Create:合法 `material_type` 能创建,非法 `material_type` 明确报错,不再依赖默认兜底。