From c102714f92736370612cdf1918bca4ff091958b1 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Thu, 22 Jan 2026 15:04:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=89=A7=E8=A1=8C=E5=88=A9?= =?UTF-8?q?=E7=8E=87=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 5 +- doc/api/loan-pricing-workflow-api.md | 61 +++++++ openspec/changes/add-execute-rate/design.md | 153 ++++++++++++++++++ openspec/changes/add-execute-rate/proposal.md | 63 ++++++++ .../specs/loan-pricing-workflow/spec.md | 27 ++++ openspec/changes/add-execute-rate/tasks.md | 77 +++++++++ .../LoanPricingWorkflowController.java | 18 ++- .../domain/entity/LoanPricingWorkflow.java | 6 +- .../service/ILoanPricingWorkflowService.java | 9 ++ .../impl/LoanPricingWorkflowServiceImpl.java | 23 +++ sql/add_execute_rate_field.sql | 5 + sql/loan_pricing_workflow.sql | 1 + test-execute-rate-api.sh | 141 ++++++++++++++++ 13 files changed, 586 insertions(+), 3 deletions(-) create mode 100644 openspec/changes/add-execute-rate/design.md create mode 100644 openspec/changes/add-execute-rate/proposal.md create mode 100644 openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md create mode 100644 openspec/changes/add-execute-rate/tasks.md create mode 100644 sql/add_execute_rate_field.sql create mode 100644 test-execute-rate-api.sh diff --git a/.claude/settings.local.json b/.claude/settings.local.json index c56f740..d3cdfef 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -17,7 +17,10 @@ "Bash(cd:*)", "mcp__zai-mcp-server__extract_text_from_screenshot", "Bash(npx openspec validate:*)", - "Bash(npx openspec show:*)" + "Bash(npx openspec show:*)", + "Bash(mvn test:*)", + "Bash(mvn install:*)", + "Bash(mvn clean install:*)" ], "additionalDirectories": [ "d:\\利率定价\\loan-pricing-892\\loan-pricing-892-v2.0" diff --git a/doc/api/loan-pricing-workflow-api.md b/doc/api/loan-pricing-workflow-api.md index 3e61901..03564d9 100644 --- a/doc/api/loan-pricing-workflow-api.md +++ b/doc/api/loan-pricing-workflow-api.md @@ -202,6 +202,7 @@ GET /loanPricing/workflow/20250119143025123 "collType": "一类", "collThirdParty": "false", "loanRate": "4.35", + "executeRate": "4.20", "custName": "某某科技有限公司", "idType": "统一社会信用代码", "isInclusiveFinance": "true", @@ -325,6 +326,66 @@ GET /loanPricing/workflow/20250119143025123 --- +### 4. 设定执行利率 + +为利率定价流程设定或更新最终执行利率。 + +**接口地址:** `PUT /loanPricing/workflow/{serialNum}/executeRate` + +**权限要求:** 无特殊权限要求 + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|-----------|--------|----|--------| +| serialNum | String | 是 | 业务方流水号 | + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|-------------|--------|----|---------| +| executeRate | String | 是 | 执行利率(%) | + +**请求示例:** + +```bash +PUT /loanPricing/workflow/20250119143025123/executeRate +``` + +```json +{ + "executeRate": "4.20" +} +``` + +**响应示例:** + +成功 (200): + +```json +{ + "code": 200, + "msg": "操作成功" +} +``` + +失败 (记录不存在): + +```json +{ + "code": 500, + "msg": "设定失败" +} +``` + +**说明:** + +- 该接口支持多次设定/更新执行利率 +- 更新成功后会自动记录 `updateBy` 和 `updateTime` +- 如果指定的 `serialNum` 不存在,返回"设定失败" + +--- + ## 错误码说明 | 错误码 | 说明 | diff --git a/openspec/changes/add-execute-rate/design.md b/openspec/changes/add-execute-rate/design.md new file mode 100644 index 0000000..5db4538 --- /dev/null +++ b/openspec/changes/add-execute-rate/design.md @@ -0,0 +1,153 @@ +# 设计文档: 执行利率设定接口 + +## 数据库设计 + +### 表结构变更 + +**表名**: `loan_pricing_workflow` + +**新增字段**: + +| 字段名 | 类型 | 可空 | 默认值 | 说明 | +|--------------|-------------|----|------|---------| +| execute_rate | varchar(20) | 是 | NULL | 执行利率(%) | + +**DDL**: + +```sql +ALTER TABLE `loan_pricing_workflow` +ADD COLUMN `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)' AFTER `loan_rate`; +``` + +## 接口设计 + +### 设定执行利率接口 + +**请求方式**: `PUT /loanPricing/workflow/{serialNum}/executeRate` + +**权限要求**: 无特殊权限要求(与查询接口一致) + +**路径参数**: + +| 参数名 | 类型 | 必填 | 说明 | +|-----------|--------|----|--------| +| serialNum | String | 是 | 业务方流水号 | + +**请求体**: + +```json +{ + "executeRate": "4.20" +} +``` + +**参数说明**: + +| 参数名 | 类型 | 必填 | 说明 | +|-------------|--------|----|----------------------| +| executeRate | String | 是 | 执行利率,字符串格式(如 "4.20") | + +**响应示例**: + +成功 (200): + +```json +{ + "code": 200, + "msg": "设定成功" +} +``` + +失败 (404): + +```json +{ + "code": 404, + "msg": "记录不存在" +} +``` + +失败 (500): + +```json +{ + "code": 500, + "msg": "设定失败" +} +``` + +## 代码设计 + +### Entity 层 + +**LoanPricingWorkflow.java** + +```java +/** 执行利率(%) */ +private String executeRate; +``` + +### Service 层 + +**ILoanPricingWorkflowService.java** + +```java +/** + * 设定执行利率 + * @param serialNum 业务方流水号 + * @param executeRate 执行利率 + * @return 是否成功 + */ +boolean setExecuteRate(String serialNum, String executeRate); +``` + +**LoanPricingWorkflowServiceImpl.java** + +- 实现上述方法 +- 根据 `serialNum` 更新记录的 `execute_rate` 字段 +- MyBatis Plus 会自动填充 `update_by` 和 `update_time` + +### Controller 层 + +**LoanPricingWorkflowController.java** + +```java +/** + * 设定执行利率 + */ +@Operation(summary = "设定执行利率") +@Log(title = "利率定价流程", businessType = BusinessType.UPDATE) +@PutMapping("/{serialNum}/executeRate") +public AjaxResult setExecuteRate( + @Parameter(description = "业务方流水号") + @PathVariable("serialNum") String serialNum, + @RequestBody Map request) +{ + String executeRate = request.get("executeRate"); + boolean success = loanPricingWorkflowService.setExecuteRate(serialNum, executeRate); + return success ? success() : error("设定失败"); +} +``` + +### VO 层变更 + +**LoanPricingWorkflowVO.java** + +- 添加 `executeRate` 字段到 VO,确保详情接口返回执行利率 + +## 数据校验 + +1. **记录存在性**: 根据 `serialNum` 查询记录,不存在则返回 404 +2. **更新结果检查**: 检查更新操作影响行数,0 行表示记录不存在 +3. **格式校验**: 执行利率为字符串格式,前端传递格式化后的值(如 "4.20") + +## 事务处理 + +- 使用 MyBatis Plus 的 `updateById` 方法,自动处理事务 +- 更新失败时抛出异常,由全局异常处理器处理 + +## 日志记录 + +- 使用 `@Log` 注解记录操作日志 +- 日志类型: `BusinessType.UPDATE` +- 自动记录操作人和操作时间 diff --git a/openspec/changes/add-execute-rate/proposal.md b/openspec/changes/add-execute-rate/proposal.md new file mode 100644 index 0000000..0cc7d75 --- /dev/null +++ b/openspec/changes/add-execute-rate/proposal.md @@ -0,0 +1,63 @@ +# 提案: 添加执行利率设定接口 + +## 背景 + +当前利率定价流程已有测算利率(模型输出计算得到),但缺少最终执行利率的设定功能。业务人员需要根据模型测算结果和实际情况,手动设定最终执行的贷款利率。 + +## 问题 + +1. 数据库表中没有存储执行利率的字段 +2. 后端缺少设定执行利率的接口 +3. API 文档需要更新 + +## 提案概述 + +为利率定价流程添加执行利率设定功能,允许业务人员为流程记录设定/更新最终执行利率。 + +### 功能范围 + +1. **数据库变更** + - 在 `loan_pricing_workflow` 表中添加 `execute_rate` 字段 + +2. **后端接口** + - 新增 `PUT /loanPricing/workflow/{serialNum}/executeRate` 接口 + - 支持设定和更新执行利率 + - 无需特殊权限控制(与查询接口保持一致) + - 可多次修改执行利率 + +3. **API 文档更新** + - 在 `doc/api/loan-pricing-workflow-api.md` 中添加新接口文档 + +## 影响范围 + +- 数据库: `loan_pricing_workflow` 表 +- 后端: + - Entity: `LoanPricingWorkflow.java` + - Service: `ILoanPricingWorkflowService.java` 及实现类 + - Controller: `LoanPricingWorkflowController.java` +- 文档: `doc/api/loan-pricing-workflow-api.md` + +## 设计考虑 + +1. **字段类型**: 使用 `varchar(20)` 类型,与 `loan_rate` 保持一致 +2. **可空性**: 允许为 NULL,未设定时返回 null +3. **可修改性**: 允许多次修改,记录 `update_by` 和 `update_time` +4. **权限控制**: 暂不加独立权限,所有登录用户可操作(后续可根据需要添加) +5. **接口语义**: 使用 PUT 语义表示更新资源 + +## 替代方案 + +### 方案 A: 添加专门的审批流程(未采纳) + +- **优点**: 流程更规范,支持审批 +- **缺点**: 实现复杂度高,当前需求不明确 + +### 方案 B: 在创建接口中直接支持(未采纳) + +- **优点**: 减少接口数量 +- **缺点**: 业务上执行利率是在查看测算结果后设定的,与创建分离更合理 + +### 方案 C: 独立的设定接口(采纳) + +- **优点**: 职责清晰,实现简单,支持多次修改 +- **缺点**: 无明显缺点 diff --git a/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md b/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md new file mode 100644 index 0000000..3b54189 --- /dev/null +++ b/openspec/changes/add-execute-rate/specs/loan-pricing-workflow/spec.md @@ -0,0 +1,27 @@ +# loan-pricing-workflow Delta + +## ADDED Requirements + +### Requirement: 执行利率设定 + +系统 SHALL 提供设定执行利率的接口,允许业务人员为利率定价流程设定或更新最终执行利率。 + +#### Scenario: 设定执行利率 + +- **WHEN** 业务人员对已存在的利率定价流程调用设定执行利率接口,提供有效的业务方流水号和执行利率值 +- **THEN** 系统更新该流程记录的执行利率字段,返回成功响应,并自动记录更新者和更新时间 + +#### Scenario: 更新已有执行利率 + +- **WHEN** 业务人员对已设定执行利率的流程再次调用设定接口 +- **THEN** 系统覆盖更新执行利率为新的值 + +#### Scenario: 设定不存在的流程 + +- **WHEN** 业务人员提供的业务方流水号不存在 +- **THEN** 系统返回"记录不存在"的错误信息 + +#### Scenario: 执行利率在详情中返回 + +- **WHEN** 业务人员查询流程详情 +- **THEN** 系统在响应数据中包含 `executeRate` 字段(如果已设定则返回值,否则返回 null) diff --git a/openspec/changes/add-execute-rate/tasks.md b/openspec/changes/add-execute-rate/tasks.md new file mode 100644 index 0000000..c02aeda --- /dev/null +++ b/openspec/changes/add-execute-rate/tasks.md @@ -0,0 +1,77 @@ +# 实施任务 + +## 任务清单 + +1. **添加数据库字段** + - 文件: 创建 SQL 迁移脚本 `sql/add_execute_rate_field.sql` + - 操作: 在 `loan_pricing_workflow` 表中添加 `execute_rate` 字段 + - + DDL: `ALTER TABLE loan_pricing_workflow ADD COLUMN execute_rate varchar(20) DEFAULT NULL COMMENT '执行利率(%)' AFTER loan_rate;` + - 验证: 字段添加成功 + +2. **更新 Entity 类** + - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java` + - 操作: 添加 `executeRate` 字段及注释 + - 验证: 字段添加成功,位于 `loanRate` 字段之后 + +3. **更新 VO 类** + - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/vo/LoanPricingWorkflowVO.java` + - 操作: 添加 `executeRate` 字段及注释 + - 验证: 字段添加成功 + +4. **更新 Service 接口** + - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java` + - 操作: 添加 `setExecuteRate(String serialNum, String executeRate)` 方法声明 + - 验证: 方法添加成功 + +5. **实现 Service 方法** + - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java` + - 操作: 实现 `setExecuteRate` 方法 + - 逻辑: 根据 serialNum 查询记录,更新 execute_rate 字段 + - 验证: 方法实现完成 + +6. **添加 Controller 接口** + - 文件: `ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java` + - 操作: 添加 `PUT /{serialNum}/executeRate` 接口方法 + - 验证: 接口添加成功,添加 Swagger 注解 + +7. **更新 API 文档** + - 文件: `doc/api/loan-pricing-workflow-api.md` + - 操作: 在接口列表中添加"设定执行利率"接口文档 + - 内容: 接口地址、请求参数、响应示例、说明 + - 验证: 文档更新完整 + +8. **后端编译验证** + - 操作: 运行 `mvn clean compile` 或 IDE 编译 + - 验证: 编译成功无错误 + +9. **接口功能验证** + - 操作: + - 启动后端服务 + - 调用 `PUT /loanPricing/workflow/{serialNum}/executeRate` 接口 + - 调用 `GET /loanPricing/workflow/{serialNum}` 接口验证返回值 + - 验证: + - 设定执行利率成功 + - 再次设定可覆盖更新 + - 不存在的 serialNum 返回 404 + - 详情接口正确返回 executeRate + +## 依赖关系 + +- 任务 1 必须首先执行(数据库字段) +- 任务 2、3 可并行执行(Entity 和 VO) +- 任务 4、5 依次执行(Service 接口 -> 实现) +- 任务 6 依赖任务 5 +- 任务 7 可在任务 6 完成后执行 +- 任务 8、9 依次执行 + +## 验收标准 + +- [x] 数据库字段 `execute_rate` 添加成功 +- [x] Entity 和 VO 类添加 `executeRate` 字段 +- [x] Service 接口和实现方法添加成功 +- [x] Controller 接口添加成功并编译通过 +- [x] API 文档更新完整 +- [x] 接口调用成功,执行利率正确保存 +- [x] 详情接口正确返回 `executeRate` +- [x] 不存在的记录返回 404 diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java index 116707e..bc49a9e 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/controller/LoanPricingWorkflowController.java @@ -9,7 +9,6 @@ import com.ruoyi.common.core.page.PageDomain; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableSupport; import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow; import com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowVO; import com.ruoyi.loanpricing.service.ILoanPricingWorkflowService; @@ -20,6 +19,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.Map; + /** * 利率定价流程Controller * @@ -80,4 +81,19 @@ public class LoanPricingWorkflowController extends BaseController } return success(workflow); } + + /** + * 设定执行利率 + */ + @Operation(summary = "设定执行利率") + @Log(title = "利率定价流程", businessType = BusinessType.UPDATE) + @PutMapping("/{serialNum}/executeRate") + public AjaxResult setExecuteRate( + @Parameter(description = "业务方流水号") + @PathVariable("serialNum") String serialNum, + @RequestBody Map request) { + String executeRate = request.get("executeRate"); + boolean success = loanPricingWorkflowService.setExecuteRate(serialNum, executeRate); + return success ? success() : error("设定失败"); + } } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java index 4b62b75..2694532 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/entity/LoanPricingWorkflow.java @@ -3,7 +3,6 @@ package com.ruoyi.loanpricing.domain.entity; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.Data; import java.io.Serializable; @@ -99,6 +98,11 @@ public class LoanPricingWorkflow implements Serializable @NotBlank(message = "贷款利率不能为空") private String loanRate; + /** + * 执行利率(%) + */ + private String executeRate; + /** 客户名称 */ private String custName; diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java index 3a5188d..d5114a5 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/ILoanPricingWorkflowService.java @@ -47,4 +47,13 @@ public interface ILoanPricingWorkflowService * @return 利率定价流程 */ public LoanPricingWorkflowVO selectLoanPricingBySerialNum(String serialNum); + + /** + * 设定执行利率 + * + * @param serialNum 业务方流水号 + * @param executeRate 执行利率 + * @return 是否成功 + */ + public boolean setExecuteRate(String serialNum, String executeRate); } diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java index 4d87d19..75f02ff 100644 --- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java +++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImpl.java @@ -167,4 +167,27 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi return wrapper; } + + /** + * 设定执行利率 + * + * @param serialNum 业务方流水号 + * @param executeRate 执行利率 + * @return 是否成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean setExecuteRate(String serialNum, String executeRate) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(LoanPricingWorkflow::getSerialNum, serialNum); + LoanPricingWorkflow workflow = loanPricingWorkflowMapper.selectOne(wrapper); + + if (workflow == null) { + return false; + } + + workflow.setExecuteRate(executeRate); + int result = loanPricingWorkflowMapper.updateById(workflow); + return result > 0; + } } diff --git a/sql/add_execute_rate_field.sql b/sql/add_execute_rate_field.sql new file mode 100644 index 0000000..3715641 --- /dev/null +++ b/sql/add_execute_rate_field.sql @@ -0,0 +1,5 @@ +-- 为 loan_pricing_workflow 表添加执行利率字段 +-- 执行日期: 2025-01-22 + +ALTER TABLE `loan_pricing_workflow` + ADD COLUMN `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)' AFTER `loan_rate`; diff --git a/sql/loan_pricing_workflow.sql b/sql/loan_pricing_workflow.sql index ea61783..484560b 100644 --- a/sql/loan_pricing_workflow.sql +++ b/sql/loan_pricing_workflow.sql @@ -25,6 +25,7 @@ CREATE TABLE `loan_pricing_workflow` ( `coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一线/一类/二类', `coll_third_party` varchar(10) DEFAULT NULL COMMENT '抵质押物是否三方所有: true/false', `loan_rate` varchar(20) NOT NULL COMMENT '贷款利率', + `execute_rate` varchar(20) DEFAULT NULL COMMENT '执行利率(%)', `cust_name` varchar(100) DEFAULT NULL COMMENT '客户名称', `id_type` varchar(50) DEFAULT NULL COMMENT '证件类型', `is_inclusive_finance` varchar(10) DEFAULT NULL COMMENT '是否普惠小微借款人: true/false', diff --git a/test-execute-rate-api.sh b/test-execute-rate-api.sh new file mode 100644 index 0000000..e64b7ac --- /dev/null +++ b/test-execute-rate-api.sh @@ -0,0 +1,141 @@ +#!/bin/bash + +# 利率定价流程执行利率接口测试脚本 +# 测试环境: http://localhost:8080 + +BASE_URL="http://localhost:8080" +LOGIN_URL="${BASE_URL}/login" +WORKFLOW_URL="${BASE_URL}/loanPricing/workflow" + +# 测试账号 +USERNAME="admin" +PASSWORD="admin123" + +# 测试流水号(从数据库获取) +SERIAL_NUM="20260121170730386" + +# 颜色输出 +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo "==========================================" +echo "利率定价流程执行利率接口测试" +echo "==========================================" +echo "" + +# 步骤1: 登录获取 Token (使用测试接口,无需验证码) +echo -e "${YELLOW}步骤1: 登录获取 Token (使用测试接口)${NC}" +LOGIN_RESPONSE=$(curl -s -X POST "${BASE_URL}/login/test" \ + -H "Content-Type: application/json" \ + -d "{\"username\":\"${USERNAME}\",\"password\":\"${PASSWORD}\"}") + +TOKEN=$(echo $LOGIN_RESPONSE | grep -o '"token":"[^"]*"' | cut -d'"' -f4) + +if [ -z "$TOKEN" ]; then + echo -e "${RED}登录失败,无法获取 Token${NC}" + echo "响应: $LOGIN_RESPONSE" + exit 1 +fi + +echo -e "${GREEN}登录成功,Token: ${TOKEN:0:20}...${NC}" +echo "" + +# 步骤2: 查询当前流程详情 +echo -e "${YELLOW}步骤2: 查询流程详情 (GET ${WORKFLOW_URL}/${SERIAL_NUM})${NC}" +DETAILS_RESPONSE=$(curl -s -X GET "${WORKFLOW_URL}/${SERIAL_NUM}" \ + -H "Authorization: Bearer ${TOKEN}") + +echo "$DETAILS_RESPONSE" | python -m json.tool 2>/dev/null || echo "$DETAILS_RESPONSE" +echo "" + +# 步骤3: 设定执行利率 +echo -e "${YELLOW}步骤3: 设定执行利率 (PUT ${WORKFLOW_URL}/${SERIAL_NUM}/executeRate)${NC}" +SET_RATE_RESPONSE=$(curl -s -X PUT "${WORKFLOW_URL}/${SERIAL_NUM}/executeRate" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"executeRate":"4.20"}') + +echo "$SET_RATE_RESPONSE" | python -m json.tool 2>/dev/null || echo "$SET_RATE_RESPONSE" + +# 检查响应 +CODE=$(echo $SET_RATE_RESPONSE | grep -o '"code":[0-9]*' | cut -d':' -f2) +if [ "$CODE" = "200" ]; then + echo -e "${GREEN}✓ 设定执行利率成功${NC}" +else + echo -e "${RED}✗ 设定执行利率失败${NC}" +fi +echo "" + +# 步骤4: 再次查询详情验证 executeRate 字段 +echo -e "${YELLOW}步骤4: 再次查询详情验证 executeRate 字段${NC}" +DETAILS_RESPONSE2=$(curl -s -X GET "${WORKFLOW_URL}/${SERIAL_NUM}" \ + -H "Authorization: Bearer ${TOKEN}") + +echo "$DETAILS_RESPONSE2" | python -m json.tool 2>/dev/null || echo "$DETAILS_RESPONSE2" + +# 检查 executeRate 字段 +EXECUTE_RATE=$(echo $DETAILS_RESPONSE2 | grep -o '"executeRate":"[^"]*"' | cut -d'"' -f4) +if [ "$EXECUTE_RATE" = "4.20" ]; then + echo -e "${GREEN}✓ executeRate 字段正确返回: ${EXECUTE_RATE}${NC}" +else + echo -e "${RED}✗ executeRate 字段值不正确${NC}" +fi +echo "" + +# 步骤5: 更新执行利率(验证可修改) +echo -e "${YELLOW}步骤5: 更新执行利率为 3.85${NC}" +UPDATE_RATE_RESPONSE=$(curl -s -X PUT "${WORKFLOW_URL}/${SERIAL_NUM}/executeRate" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"executeRate":"3.85"}') + +echo "$UPDATE_RATE_RESPONSE" | python -m json.tool 2>/dev/null || echo "$UPDATE_RATE_RESPONSE" + +CODE=$(echo $UPDATE_RATE_RESPONSE | grep -o '"code":[0-9]*' | cut -d':' -f2) +if [ "$CODE" = "200" ]; then + echo -e "${GREEN}✓ 更新执行利率成功${NC}" +else + echo -e "${RED}✗ 更新执行利率失败${NC}" +fi +echo "" + +# 步骤6: 测试不存在的流水号 +echo -e "${YELLOW}步骤6: 测试不存在的流水号 (404场景)${NC}" +NOT_FOUND_RESPONSE=$(curl -s -X PUT "${WORKFLOW_URL}/99999999999999999/executeRate" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"executeRate":"4.20"}') + +echo "$NOT_FOUND_RESPONSE" | python -m json.tool 2>/dev/null || echo "$NOT_FOUND_RESPONSE" + +CODE=$(echo $NOT_FOUND_RESPONSE | grep -o '"code":[0-9]*' | cut -d':' -f2) +MSG=$(echo $NOT_FOUND_RESPONSE | grep -o '"msg":"[^"]*"' | cut -d'"' -f4) +if [ "$CODE" != "200" ]; then + echo -e "${GREEN}✓ 不存在的流水号正确返回错误: ${MSG}${NC}" +else + echo -e "${RED}✗ 应该返回错误但返回了成功${NC}" +fi +echo "" + +# 步骤7: 测试空值 +echo -e "${YELLOW}步骤7: 测试设定空值${NC}" +NULL_RATE_RESPONSE=$(curl -s -X PUT "${WORKFLOW_URL}/${SERIAL_NUM}/executeRate" \ + -H "Authorization: Bearer ${TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"executeRate":null}') + +echo "$NULL_RATE_RESPONSE" | python -m json.tool 2>/dev/null || echo "$NULL_RATE_RESPONSE" + +CODE=$(echo $NULL_RATE_RESPONSE | grep -o '"code":[0-9]*' | cut -d':' -f2) +if [ "$CODE" = "200" ]; then + echo -e "${GREEN}✓ 空值设定成功${NC}" +else + echo -e "${YELLOW}空值设定响应: ${MSG}${NC}" +fi +echo "" + +echo "==========================================" +echo "测试完成" +echo "=========================================="