Files
ccdi/docs/plans/2026-03-06-model-param-config-backend.md

746 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 模型参数配置优化 - 后端实施计划
> **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 {
/** 项目ID0表示全局配置>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<ModelParamVO> 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<ModelGroupVO> 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<ParamValueItem> 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<ModelParamGroupDTO> 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<CcdiModelParam> 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语句**
`<mapper>` 标签内添加:
```xml
<!-- 根据项目ID查询所有模型参数 -->
<select id="selectByProjectId" resultType="CcdiModelParam">
SELECT * FROM ccdi_model_param
WHERE project_id = #{projectId}
ORDER BY model_code, sort_order
</select>
```
**步骤 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 项目ID0表示全局配置
* @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<CcdiModelParam> allParams = modelParamMapper.selectByProjectId(effectiveProjectId);
// 4. 按模型分组
Map<String, List<CcdiModelParam>> groupedParams = allParams.stream()
.collect(Collectors.groupingBy(CcdiModelParam::getModelCode));
// 5. 转换为VO
ModelParamAllVO result = new ModelParamAllVO();
List<ModelGroupVO> models = new ArrayList<>();
groupedParams.forEach((modelCode, params) -> {
ModelGroupVO groupVO = new ModelGroupVO();
groupVO.setModelCode(modelCode);
groupVO.setModelName(params.get(0).getModelName());
List<ModelParamVO> 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. 验证响应:状态码 200msg 为 "保存成功"
**步骤 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": "保存成功"}`
---
**后端实施计划完成!准备前端开发时,使用前端实施计划。**