diff --git a/docs/plans/2026-03-06-model-param-config-backend.md b/docs/plans/2026-03-06-model-param-config-backend.md new file mode 100644 index 0000000..a224888 --- /dev/null +++ b/docs/plans/2026-03-06-model-param-config-backend.md @@ -0,0 +1,745 @@ +# 模型参数配置优化 - 后端实施计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**目标:** 实现模型参数批量查询和批量保存接口,支持前端统一展示和保存所有模型参数 + +**技术栈:** Spring Boot 3.5.8 + MyBatis Plus 3.0.5 + Java 21 + +**依赖模块:** ccdi-project + +**预计时间:** 2-3小时 + +--- + +## 📋 任务概览 + +| 任务组 | 任务数 | 说明 | +|--------|--------|------| +| DTO/VO 创建 | 6个 | 数据传输对象 | +| Mapper 层 | 2个 | 数据访问层 | +| Service 层 | 5个 | 业务逻辑层 | +| Controller 层 | 2个 | API接口层 | +| 测试 | 1个 | Swagger测试 | +| **总计** | **16个** | | + +--- + +## 任务列表 + +### Task 1: 创建批量查询请求DTO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamAllQueryDTO.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.dto; + +import lombok.Data; + +/** + * 批量查询所有模型参数DTO + */ +@Data +public class ModelParamAllQueryDTO { + + /** 项目ID(0表示全局配置,>0表示项目配置) */ + private Long projectId; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamAllQueryDTO.java +git commit -m "feat(ccdi-project): 添加批量查询所有模型参数DTO" +``` + +--- + +### Task 2: 创建模型分组VO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/ModelGroupVO.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.vo; + +import lombok.Data; +import java.util.List; + +/** + * 模型分组VO(用于按模型分组展示参数) + */ +@Data +public class ModelGroupVO { + + /** 模型编码 */ + private String modelCode; + + /** 模型名称 */ + private String modelName; + + /** 参数列表 */ + private List params; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/ModelGroupVO.java +git commit -m "feat(ccdi-project): 添加模型分组VO" +``` + +--- + +### Task 3: 创建批量查询响应VO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/ModelParamAllVO.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.vo; + +import lombok.Data; +import java.util.List; + +/** + * 批量查询所有模型参数响应VO + */ +@Data +public class ModelParamAllVO { + + /** 模型列表(包含每个模型及其参数) */ + private List models; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/ModelParamAllVO.java +git commit -m "feat(ccdi-project): 添加批量查询所有模型参数响应VO" +``` + +--- + +### Task 4: 创建批量保存参数项DTO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ParamValueItem.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.dto; + +import lombok.Data; + +/** + * 参数值项DTO + */ +@Data +public class ParamValueItem { + + /** 参数编码 */ + private String paramCode; + + /** 参数值 */ + private String paramValue; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ParamValueItem.java +git commit -m "feat(ccdi-project): 添加参数值项DTO" +``` + +--- + +### Task 5: 创建批量保存模型参数组DTO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamGroupDTO.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.dto; + +import lombok.Data; +import java.util.List; + +/** + * 模型参数分组DTO(用于批量保存) + */ +@Data +public class ModelParamGroupDTO { + + /** 模型编码 */ + private String modelCode; + + /** 该模型下修改过的参数 */ + private List params; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamGroupDTO.java +git commit -m "feat(ccdi-project): 添加模型参数分组DTO" +``` + +--- + +### Task 6: 创建批量保存请求DTO + +**文件:** +- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamSaveAllDTO.java` + +**步骤 1: 创建类文件** + +```java +package com.ruoyi.ccdi.project.domain.dto; + +import lombok.Data; +import java.util.List; + +/** + * 批量保存所有模型参数DTO + */ +@Data +public class ModelParamSaveAllDTO { + + /** 项目ID */ + private Long projectId; + + /** 所有模型的参数修改(只包含修改过的参数) */ + private List models; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/ModelParamSaveAllDTO.java +git commit -m "feat(ccdi-project): 添加批量保存所有模型参数DTO" +``` + +--- + +### Task 7: 在Mapper接口中添加批量查询方法 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiModelParamMapper.java` + +**步骤 1: 添加方法签名** + +在接口中添加: + +```java +/** + * 根据项目ID查询所有模型参数 + * + * @param projectId 项目ID + * @return 参数列表 + */ +List selectByProjectId(@Param("projectId") Long projectId); +``` + +**步骤 2: 检查导入** + +确保包含必要的导入: +```java +import org.apache.ibatis.annotations.Param; +import java.util.List; +``` + +**步骤 3: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiModelParamMapper.java +git commit -m "feat(ccdi-project): 在Mapper接口中添加批量查询方法" +``` + +--- + +### Task 8: 在Mapper XML中添加SQL查询 + +**文件:** +- Modify: `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiModelParamMapper.xml` + +**步骤 1: 添加SQL语句** + +在 `` 标签内添加: + +```xml + + +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/resources/mapper/ccdi/project/CcdiModelParamMapper.xml +git commit -m "feat(ccdi-project): 在Mapper XML中添加批量查询SQL" +``` + +--- + +### Task 9: 在Service接口中添加批量查询方法 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiModelParamService.java` + +**步骤 1: 添加方法签名** + +```java +/** + * 查询所有模型及其参数(按模型分组) + * + * @param projectId 项目ID(0表示全局配置) + * @return 所有模型的参数配置 + */ +ModelParamAllVO selectAllParams(Long projectId); +``` + +**步骤 2: 添加导入** + +```java +import com.ruoyi.ccdi.project.domain.vo.ModelParamAllVO; +``` + +**步骤 3: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiModelParamService.java +git commit -m "feat(ccdi-project): 在Service接口中添加批量查询方法" +``` + +--- + +### Task 10: 在Service接口中添加批量保存方法 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiModelParamService.java` + +**步骤 1: 添加方法签名** + +```java +/** + * 批量保存所有模型的参数修改 + * + * @param saveAllDTO 所有模型的参数修改数据 + */ +void saveAllParams(ModelParamSaveAllDTO saveAllDTO); +``` + +**步骤 2: 添加导入** + +```java +import com.ruoyi.ccdi.project.domain.dto.ModelParamSaveAllDTO; +``` + +**步骤 3: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiModelParamService.java +git commit -m "feat(ccdi-project): 在Service接口中添加批量保存方法" +``` + +--- + +### Task 11: 添加Service实现所需的导入语句 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java` + +**步骤 1: 添加导入语句** + +在文件顶部导入区域添加: + +```java +import com.ruoyi.ccdi.project.domain.dto.ModelParamSaveAllDTO; +import com.ruoyi.ccdi.project.domain.dto.ModelParamGroupDTO; +import com.ruoyi.ccdi.project.domain.dto.ParamValueItem; +import com.ruoyi.ccdi.project.domain.vo.ModelParamAllVO; +import com.ruoyi.ccdi.project.domain.vo.ModelGroupVO; +import java.util.Comparator; +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java +git commit -m "feat(ccdi-project): 添加批量操作所需的导入语句" +``` + +--- + +### Task 12: 实现批量查询方法 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java` + +**步骤 1: 实现 selectAllParams 方法** + +在 `CcdiModelParamServiceImpl` 类中添加方法: + +```java +@Override +public ModelParamAllVO selectAllParams(Long projectId) { + // 1. 参数验证 + if (projectId == null) { + projectId = 0L; + } + + // 2. 如果是项目查询,根据 configType 决定查询哪组参数 + Long effectiveProjectId = projectId; + if (projectId > 0) { + CcdiProject project = projectMapper.selectById(projectId); + if (project == null) { + throw new ServiceException("项目不存在"); + } + if ("default".equals(project.getConfigType())) { + effectiveProjectId = 0L; + } + } + + // 3. 查询所有模型的参数 + List allParams = modelParamMapper.selectByProjectId(effectiveProjectId); + + // 4. 按模型分组 + Map> groupedParams = allParams.stream() + .collect(Collectors.groupingBy(CcdiModelParam::getModelCode)); + + // 5. 转换为VO + ModelParamAllVO result = new ModelParamAllVO(); + List models = new ArrayList<>(); + + groupedParams.forEach((modelCode, params) -> { + ModelGroupVO groupVO = new ModelGroupVO(); + groupVO.setModelCode(modelCode); + groupVO.setModelName(params.get(0).getModelName()); + + List paramVOs = params.stream() + .map(param -> { + ModelParamVO vo = new ModelParamVO(); + BeanUtils.copyProperties(param, vo); + return vo; + }) + .collect(Collectors.toList()); + + groupVO.setParams(paramVOs); + models.add(groupVO); + }); + + // 6. 按模型编码排序(保证固定顺序) + models.sort(Comparator.comparing(ModelGroupVO::getModelCode)); + + result.setModels(models); + return result; +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java +git commit -m "feat(ccdi-project): 实现批量查询所有模型参数方法" +``` + +--- + +### Task 13: 实现批量保存方法 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java` + +**步骤 1: 实现 saveAllParams 方法** + +在 `CcdiModelParamServiceImpl` 类中添加方法: + +```java +@Override +@Transactional(rollbackFor = Exception.class) +public void saveAllParams(ModelParamSaveAllDTO saveAllDTO) { + try { + // 1. 参数验证 + if (saveAllDTO.getProjectId() == null) { + throw new ServiceException("项目ID不能为空"); + } + if (saveAllDTO.getModels() == null || saveAllDTO.getModels().isEmpty()) { + throw new ServiceException("参数列表不能为空"); + } + + Long projectId = saveAllDTO.getProjectId(); + + // 2. 如果是项目保存,检查是否需要复制默认参数 + if (projectId > 0) { + CcdiProject project = projectMapper.selectById(projectId); + if (project == null) { + throw new ServiceException("项目不存在"); + } + + // 如果是首次保存(configType=default),需要复制所有模型的系统默认参数 + if ("default".equals(project.getConfigType())) { + for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) { + copyDefaultParamsToProject(projectId, modelGroup.getModelCode()); + } + + // 更新项目配置类型为 custom + project.setConfigType("custom"); + projectMapper.updateById(project); + } + } + + // 3. 批量更新所有模型的参数值 + for (ModelParamGroupDTO modelGroup : saveAllDTO.getModels()) { + for (ParamValueItem item : modelGroup.getParams()) { + int updated = modelParamMapper.updateParamValue( + projectId, + modelGroup.getModelCode(), + item.getParamCode(), + item.getParamValue() + ); + if (updated == 0) { + log.warn("参数不存在或未更新,modelCode={}, paramCode={}", + modelGroup.getModelCode(), item.getParamCode()); + } + } + } + + } catch (ServiceException e) { + throw e; + } catch (Exception e) { + log.error("批量保存模型参数失败", e); + throw new ServiceException("批量保存模型参数失败:" + e.getMessage()); + } +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java +git commit -m "feat(ccdi-project): 实现批量保存所有模型参数方法" +``` + +--- + +### Task 14: 在Controller中添加批量查询接口 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiModelParamController.java` + +**步骤 1: 添加导入语句** + +在文件顶部添加: + +```java +import com.ruoyi.ccdi.project.domain.dto.ModelParamAllQueryDTO; +import com.ruoyi.ccdi.project.domain.dto.ModelParamSaveAllDTO; +import com.ruoyi.ccdi.project.domain.vo.ModelParamAllVO; +``` + +**步骤 2: 添加接口方法** + +在 `CcdiModelParamController` 类中添加: + +```java +/** + * 查询所有模型及其参数(按模型分组) + */ +@Operation(summary = "查询所有模型及其参数") +@GetMapping("/listAll") +public AjaxResult listAll(@Validated ModelParamAllQueryDTO queryDTO) { + ModelParamAllVO result = modelParamService.selectAllParams(queryDTO.getProjectId()); + return success(result); +} +``` + +**步骤 3: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiModelParamController.java +git commit -m "feat(ccdi-project): 在Controller中添加批量查询接口" +``` + +--- + +### Task 15: 在Controller中添加批量保存接口 + +**文件:** +- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiModelParamController.java` + +**步骤 1: 添加接口方法** + +在 `CcdiModelParamController` 类中添加: + +```java +/** + * 批量保存所有模型的参数修改 + */ +@Operation(summary = "批量保存所有模型参数") +@Log(title = "模型参数配置", businessType = BusinessType.UPDATE) +@PostMapping("/saveAll") +public AjaxResult saveAll(@Validated @RequestBody ModelParamSaveAllDTO saveAllDTO) { + modelParamService.saveAllParams(saveAllDTO); + return success("保存成功"); +} +``` + +**步骤 2: 提交代码** + +```bash +git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/controller/CcdiModelParamController.java +git commit -m "feat(ccdi-project): 在Controller中添加批量保存接口" +``` + +--- + +### Task 16: 使用Swagger测试后端接口 + +**检查点:后端开发完成** + +**步骤 1: 启动后端应用** + +提示用户手动启动: +```bash +mvn spring-boot:run +``` + +**步骤 2: 访问Swagger UI** + +打开浏览器:`http://localhost:8080/swagger-ui/index.html` + +**步骤 3: 测试批量查询接口** + +1. 找到"模型参数配置"分组 +2. 找到 `GET /ccdi/modelParam/listAll` 接口 +3. 点击 "Try it out" +4. 输入参数:`projectId: 0` +5. 点击 "Execute" +6. 验证响应: + - 状态码:200 + - 返回数据包含 `models` 数组 + - 每个模型包含 `modelCode`, `modelName`, `params` + +**预期结果:** +```json +{ + "code": 200, + "msg": "操作成功", + "data": { + "models": [ + { + "modelCode": "LARGE_TRANSACTION", + "modelName": "大额交易模型", + "params": [ + { + "paramCode": "THRESHOLD_AMOUNT", + "paramName": "单笔交易金额阈值", + "paramDesc": "单笔交易金额超过此值触发预警", + "paramValue": "50000", + "paramUnit": "元" + } + ] + } + ] + } +} +``` + +**步骤 4: 测试批量保存接口** + +1. 找到 `POST /ccdi/modelParam/saveAll` 接口 +2. 点击 "Try it out" +3. 输入请求体: +```json +{ + "projectId": 0, + "models": [ + { + "modelCode": "LARGE_TRANSACTION", + "params": [ + { + "paramCode": "THRESHOLD_AMOUNT", + "paramValue": "60000" + } + ] + } + ] +} +``` +4. 点击 "Execute" +5. 验证响应:状态码 200,msg 为 "保存成功" + +**步骤 5: 测试其他场景** + +- 测试项目配置查询(projectId > 0) +- 测试首次保存参数复制 +- 测试多模型同时保存 + +**步骤 6: 提交测试记录** + +```bash +mkdir -p docs/test-records +git add docs/test-records/ +git commit -m "test(ccdi-project): 记录后端接口测试结果" +``` + +--- + +## ✅ 完成标志 + +后端实施完成的标志: +- ✅ 所有16个任务执行完成 +- ✅ Swagger接口测试通过 +- ✅ 代码已提交到git +- ✅ 可以响应前端的批量查询和保存请求 + +## 📝 后端API说明 + +### 批量查询接口 +- **URL**: `GET /ccdi/modelParam/listAll?projectId=0` +- **返回**: 所有模型的参数配置(按模型分组) + +### 批量保存接口 +- **URL**: `POST /ccdi/modelParam/saveAll` +- **请求体**: +```json +{ + "projectId": 0, + "models": [ + { + "modelCode": "MODEL_CODE", + "params": [ + { + "paramCode": "PARAM_CODE", + "paramValue": "NEW_VALUE" + } + ] + } + ] +} +``` +- **返回**: `{"code": 200, "msg": "保存成功"}` + +--- + +**后端实施计划完成!准备前端开发时,使用前端实施计划。** diff --git a/docs/plans/2026-03-06-model-param-config-frontend.md b/docs/plans/2026-03-06-model-param-config-frontend.md new file mode 100644 index 0000000..7f5fe19 --- /dev/null +++ b/docs/plans/2026-03-06-model-param-config-frontend.md @@ -0,0 +1,888 @@ +# 模型参数配置优化 - 前端实施计划 + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**目标:** 重构全局配置页面和项目配置页面,取消模型下拉切换,改为垂直堆叠展示所有模型参数,实现统一保存 + +**技术栈:** Vue 2.6.12 + Element UI 2.15.14 + Axios 0.28.1 + +**依赖:** 后端接口已完成(参考后端实施计划) + +**预计时间:** 2-3小时 + +--- + +## 📋 任务概览 + +| 任务组 | 任务数 | 说明 | +|--------|--------|------| +| API 层 | 2个 | 添加批量接口方法 | +| 全局配置页面 | 4个 | 重构页面结构 | +| 项目配置页面 | 4个 | 重构页面结构 | +| 测试 | 2个 | 功能测试和集成测试 | +| **总计** | **12个** | | + +--- + +## 前置条件 + +**在开始前端开发前,确保:** +- ✅ 后端接口已部署完成 +- ✅ 后端接口测试通过(Swagger测试) +- ✅ 后端服务正常运行(http://localhost:8080) + +--- + +## 任务列表 + +### Task 1: 在API层添加批量查询方法 + +**文件:** +- Modify: `ruoyi-ui/src/api/ccdi/modelParam.js` + +**步骤 1: 打开API文件** + +找到并打开 `ruoyi-ui/src/api/ccdi/modelParam.js` 文件 + +**步骤 2: 添加批量查询方法** + +在文件末尾添加: + +```javascript +/** + * 查询所有模型及其参数(按模型分组) + * @param {Object} query - 查询参数 + * @param {Number} query.projectId - 项目ID(0表示全局配置) + * @returns {Promise} 返回所有模型的参数配置 + */ +export function listAllParams(query) { + return request({ + url: '/ccdi/modelParam/listAll', + method: 'get', + params: query + }) +} +``` + +**步骤 3: 验证导入** + +确保文件顶部有: +```javascript +import request from '@/utils/request' +``` + +**步骤 4: 提交代码** + +```bash +git add ruoyi-ui/src/api/ccdi/modelParam.js +git commit -m "feat(ui): 在API层添加批量查询方法" +``` + +--- + +### Task 2: 在API层添加批量保存方法 + +**文件:** +- Modify: `ruoyi-ui/src/api/ccdi/modelParam.js` + +**步骤 1: 添加批量保存方法** + +在文件末尾添加: + +```javascript +/** + * 批量保存所有模型的参数修改 + * @param {Object} data - 保存数据 + * @param {Number} data.projectId - 项目ID + * @param {Array} data.models - 模型参数列表 + * @returns {Promise} + */ +export function saveAllParams(data) { + return request({ + url: '/ccdi/modelParam/saveAll', + method: 'post', + data: data + }) +} +``` + +**步骤 2: 提交代码** + +```bash +git add ruoyi-ui/src/api/ccdi/modelParam.js +git commit -m "feat(ui): 在API层添加批量保存方法" +``` + +--- + +### Task 3: 重构全局配置页面 - 模板部分 + +**文件:** +- Modify: `ruoyi-ui/src/views/ccdi/modelParam/index.vue` + +**步骤 1: 备份原文件(可选)** + +```bash +cp ruoyi-ui/src/views/ccdi/modelParam/index.vue ruoyi-ui/src/views/ccdi/modelParam/index.vue.backup +``` + +**步骤 2: 替换整个 template 部分** + +找到 `