# 增加材料类型(material_type)支持的详细实施方案 根据现有的系统架构和需求,为算法模型增加“材料类型(material_type)”维度的支持,需要从数据库、实体类、核心业务逻辑(特别是路径解析与模型发布)以及状态控制等方面进行细化和落地。以下是详细的分析与实施细则: ## 1. 数据库层面修改 (Database) - **目标表**: `algorithm_model` - **操作**: 增加 `material_type` 字段,用于区分该模型适用的材料(如 `Pu` 等)。 - **SQL 参考**: ```sql ALTER TABLE algorithm_model ADD COLUMN material_type VARCHAR(50) DEFAULT NULL COMMENT '材料类型' AFTER device_type; ``` ## 2. 实体类及映射修改 (Domain) - **目标文件**: `AlgorithmModel.java` - **操作**: 增加对应的 Java 属性,并使用 MyBatis-Plus 的 `@TableField` 进行映射。 - **代码参考**: ```java /** * 材料类型 (例如: Pu) */ @TableField("material_type") private String materialType; ``` ## 3. 核心业务逻辑修改 (Service) ### 3.1 提取材料类型 (Path Parsing) - **目标文件**: `ModelTrainServiceImpl.java` -> `publishModel` 方法。 - **逻辑细化**: `ModelTrainTask` 中保存的相对路径(如 `runs/GPR/AnnularTank/Pu/edb0e340-51e6-46bb-9c08-5ba38762089e/pipeline.pkl`)包含了材料信息。 - **解析规则**: 需要对 `task.getModelOutputPath()` 或 `task.getModelRelativePath()` 进行字符串分割(兼容 `/` 和 `\`)。 标准的目录层级为:`runs` / `{算法类型}` / `{设备类型}` / `{材料类型}` / `{TaskID}` / `{文件名}`。 - 第 0 层: `runs` - 第 1 层: `algorithm_type` (如 `GPR`) - 第 2 层: `device_type` (如 `AnnularTank`) - **第 3 层**: `material_type` (如 `Pu`) <- **需要提取的字段** - 第 4 层: `task_id` ### 3.2 更新模型发布路径 (Publish Path Assembly) - **目标文件**: `ModelTrainServiceImpl.java` -> `publishModel` 方法。 - **旧路径结构**: `{modelRoot}/{algorithmType}/{deviceType}/{versionTag}/` - **新路径结构**: 将提取出的 `materialType` 拼接到发布路径中,使发布目录也具备材料维度。 **新结构**: `{modelRoot}/{algorithmType}/{deviceType}/{materialType}/{versionTag}/` - **持久化**: 在构建要插入到 `algorithm_model` 表的记录时,不仅要保存新拼接出的模型绝对/相对路径,还要将解析出的 `materialType` 赋值给 `AlgorithmModel` 对象。 ### 3.3 激活模型的唯一性约束控制 (Active Model Logic) - **业务规则**: “每种设备 + 每种算法类型 + 每种材料类型” 只能由一个激活(`is_active = 1` 或者对应状态码)的算法。 - **目标文件**: 处理模型发布或激活的 Service 方法(如 `AlgorithmModelServiceImpl` 中如果存在独立激活方法,或直接在 `publishModel` 之后的操作)。 - **逻辑细化**: 在将某模型记录标记为激活前,需要执行排他更新: ```java UpdateWrapper updateWrapper = new UpdateWrapper<>(); updateWrapper.eq("device_type", model.getDeviceType()) .eq("algorithm_type", model.getAlgorithmType()) .eq("material_type", model.getMaterialType()) // 新增材料类型维度限制 .set("is_active", 0); // 假设 0 为未激活,1 为激活 algorithmModelMapper.update(null, updateWrapper); ``` ## 4. API 接口层面 (Controller) - **目标文件**: `ModelTrainController.java` - **接口定义**: ```java @PostMapping("/publish") public ResponseResult publish(@RequestBody Map body) { String taskId = body.get("taskId"); String versionTag = body.get("versionTag"); boolean success = modelTrainService.publishModel(taskId, versionTag); return success ? ResponseResult.success() : ResponseResult.error("发布失败"); } ``` - **结论**: 接口的入参定义**无需修改**。材料类型信息属于内部推导数据,完全可以由 Service 层通过 `taskId` 找到对应的 Task 数据,再解析路径得到 `material_type`,对前端调用保持透明。