Files
loan-pricing/doc/2026-04-09-shangyu-retail-input-params-backend-plan.md

239 lines
9.3 KiB
Markdown
Raw Normal View History

# 上虞个人利率测算输入参数后端 Implementation Plan
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 补齐个人创建 DTO、流程转换和模型调用参数使个人模型请求完整覆盖 Excel 要求的输入字段。
**Architecture:** 维持现有“页面提交 -> DTO -> Workflow -> ModelInvokeDTO -> form-urlencoded 调用”的链路,只在个人创建与模型调用相关文件中补齐字段和转换规则。通过后端单元测试与真实接口联调覆盖必填、正常和分支场景。
**Tech Stack:** Spring Boot、MyBatis-Plus、Lombok、JUnit、Maven
---
## 后端模型输入参数确认
个人链路最终需要发给模型的 16 个参数如下:
- `serialNum`:服务层自动生成
- `orgCode`:服务层默认值,当前代码为 `892000`
- `runType`:服务层默认值 `1`
- `custIsn`:页面输入透传
- `custType`:个人链路固定 `个人`
- `custName`:页面输入,调用模型前解密后透传
- `idType`:页面输入透传
- `idNum`:页面输入,调用模型前解密后透传
- `guarType`:页面输入透传
- `applyAmt`:页面输入透传
- `loanPurpose`:页面输入透传
- `loanTerm`:页面输入透传
- `bizProof`:页面开关,调用模型前转 `0/1`
- `loanLoop`:页面开关,调用模型前转 `0/1`
- `collThirdParty`:页面开关,调用模型前转 `0/1`
- `collType`:页面下拉透传
调用方式确认:
- 参数载体:`ModelInvokeDTO`
- 组装方式:`BeanUtils.copyProperties(loanPricingWorkflow, modelInvokeDTO)`
- 请求格式:`application/x-www-form-urlencoded`
- 发送入口:`ModelService#invokeModel`
## 文件结构
- Modify: [ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java](/Users/wkc/Desktop/loan-pricing/loan-pricing/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java)
- 增加 `loanPurpose``loanTerm`
- Modify: [ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java](/Users/wkc/Desktop/loan-pricing/loan-pricing/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java)
- 将新增字段映射到 `LoanPricingWorkflow`
- Modify: [ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java](/Users/wkc/Desktop/loan-pricing/loan-pricing/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java)
- 增加 `loanTerm``loanLoop`
- Modify: [ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java](/Users/wkc/Desktop/loan-pricing/loan-pricing/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java)
- 在个人模型调用前规范化 `0/1`
- Create: [ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java](/Users/wkc/Desktop/loan-pricing/loan-pricing/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java)
- 覆盖字段存在与值转换
### Task 1: 为新增字段补失败测试
**Files:**
- Create: `ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java`
- [ ] **Step 1: 编写字段与转换测试**
```java
@Test
void shouldContainLoanPurposeLoanTermAndLoanLoop() {
assertThat(ModelInvokeDTO.class.getDeclaredField("loanTerm")).isNotNull();
assertThat(ModelInvokeDTO.class.getDeclaredField("loanLoop")).isNotNull();
}
```
```java
@Test
void shouldConvertPersonalBooleanFlagsToZeroOne() {
// 构造个人流程对象,断言模型请求中的 bizProof/loanLoop/collThirdParty 为 1/0
}
```
- [ ] **Step 2: 运行测试并确认先失败**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServicePersonalParamsTest test`
Expected: FAIL提示字段不存在或转换逻辑未实现
- [ ] **Step 3: 保持测试只覆盖本次改动相关链路**
```java
// 仅断言 PersonalLoanPricingCreateDTO / LoanPricingConverter / ModelInvokeDTO / LoanPricingModelService
```
- [ ] **Step 4: 增加最终模型请求参数断言**
```java
// 断言 requestBody 包含 serialNum、orgCode、runType、custIsn、custType、custName、
// idType、idNum、guarType、applyAmt、loanPurpose、loanTerm、bizProof、
// loanLoop、collThirdParty、collType
```
- [ ] **Step 5: 再次运行测试确认失败原因稳定**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServicePersonalParamsTest test`
Expected: FAIL失败点与新增字段缺失一致
- [ ] **Step 6: 提交**
```bash
git add ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java
git commit -m "新增个人测算输入参数后端测试"
```
### Task 2: 补齐个人创建 DTO 与流程映射
**Files:**
- Modify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java`
- Modify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java`
- [ ] **Step 1: 在个人 DTO 中增加 `loanPurpose`**
```java
@NotBlank(message = "贷款用途不能为空")
@Pattern(regexp = "^(consumer|business)$", message = "贷款用途必须是 consumer 或 business")
private String loanPurpose;
```
- [ ] **Step 2: 在个人 DTO 中增加 `loanTerm`**
```java
@NotBlank(message = "借款期限不能为空")
private String loanTerm;
```
- [ ] **Step 3: 在转换器中映射新增字段**
```java
entity.setLoanPurpose(dto.getLoanPurpose());
entity.setLoanTerm(dto.getLoanTerm());
```
- [ ] **Step 4: 运行相关测试确认 DTO 与映射通过**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServicePersonalParamsTest test`
Expected: 仍可能 FAIL但失败点已推进到模型调用层
- [ ] **Step 5: 提交**
```bash
git add ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java
git commit -m "补齐个人测算创建参数字段"
```
### Task 3: 补齐模型调用 DTO 与个人参数规范化
**Files:**
- Modify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java`
- Modify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java`
- [ ] **Step 1: 在模型调用 DTO 中增加缺失字段**
```java
private String loanTerm;
private String loanLoop;
```
- [ ] **Step 2: 在个人模型调用前做 `0/1` 转换**
```java
if ("个人".equals(loanPricingWorkflow.getCustType())) {
modelInvokeDTO.setBizProof(toZeroOne(modelInvokeDTO.getBizProof()));
modelInvokeDTO.setLoanLoop(toZeroOne(modelInvokeDTO.getLoanLoop()));
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
}
```
- [ ] **Step 3: 抽出最小辅助方法,避免散落重复逻辑**
```java
private String toZeroOne(String value) {
if ("true".equals(value) || "1".equals(value)) return "1";
if ("false".equals(value) || "0".equals(value)) return "0";
return value;
}
```
- [ ] **Step 4: 运行测试确认通过**
Run: `mvn -pl ruoyi-loan-pricing -Dtest=LoanPricingModelServicePersonalParamsTest test`
Expected: PASS
- [ ] **Step 5: 提交**
```bash
git add ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java
git commit -m "规范个人测算模型调用参数"
```
### Task 4: 后端联调与接口验证
**Files:**
- Verify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java`
- Verify: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java`
- [ ] **Step 1: 重新编译并重启后端进程**
Run: `mvn -pl ruoyi-admin -am package -DskipTests`
Expected: 打包成功,随后重启运行中的后端服务使最新代码生效
- [ ] **Step 2: 验证正常场景**
Run: 调用 `POST /loanPricing/workflow/create/personal`
Expected:
- 返回创建成功
- 请求体包含 `loanPurpose``loanTerm`
- 模型请求中完整带出 16 个参数
- 其中 `bizProof``loanLoop``collThirdParty``0/1`
- [ ] **Step 3: 验证必填缺失场景**
Run: 缺少 `loanPurpose``loanTerm` 分别调用接口
Expected: 返回参数校验失败
- [ ] **Step 4: 验证分支场景**
Run: 以不同开关组合调用接口
Expected:
- `bizProof=true` -> 模型入参 `1`
- `bizProof=false` -> 模型入参 `0`
- `loanLoop=true/false``collThirdParty=true/false` 同理
- [ ] **Step 5: 验证结束后停止后端进程并提交**
```bash
git add ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/LoanPricingModelService.java ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java
git commit -m "完成个人测算输入参数后端联调"
```