From 6ef3cfcaea168ec900fca02f2044bf6803848442 Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Mon, 11 May 2026 18:02:04 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=B8=8A=E8=99=9E=E5=88=A9?=
=?UTF-8?q?=E7=8E=87=E5=AE=9A=E4=BB=B7=E5=AD=97=E6=AE=B5=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...-05-11-shangyu-pricing-field-adjustment.md | 76 +++++++++
.../dto/CorporateLoanPricingCreateDTO.java | 11 +-
.../domain/dto/ModelInvokeDTO.java | 5 +
.../dto/PersonalLoanPricingCreateDTO.java | 17 +--
.../domain/entity/LoanPricingWorkflow.java | 5 +-
.../impl/LoanPricingWorkflowServiceImpl.java | 56 ++++++-
.../util/LoanPricingConverter.java | 4 +-
...PricingModelServicePersonalParamsTest.java | 19 +--
.../service/LoanPricingModelServiceTest.java | 4 +
.../LoanPricingWorkflowServiceImplTest.java | 144 ++++++++++++++++++
.../components/CorporateCreateDialog.vue | 54 ++++++-
.../components/PersonalCreateDialog.vue | 78 ++++++----
.../personal-create-input-params.test.js | 23 +--
sql/add_coupon_rate_20260511.sql | 3 +
sql/loan_pricing_prod_init_20260331.sql | 1 +
sql/loan_pricing_schema_20260328.sql | 1 +
sql/loan_pricing_workflow.sql | 1 +
17 files changed, 430 insertions(+), 72 deletions(-)
create mode 100644 doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md
create mode 100644 sql/add_coupon_rate_20260511.sql
diff --git a/doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md b/doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md
new file mode 100644
index 0000000..8c88101
--- /dev/null
+++ b/doc/implementation-report-2026-05-11-shangyu-pricing-field-adjustment.md
@@ -0,0 +1,76 @@
+# 上虞利率定价字段调整实施记录
+
+## 基本信息
+
+- 日期:2026-05-11
+- 范围:上虞利率定价个人/企业新增链路、服务端校验、模型入参、表结构脚本
+- 目标:按已确认需求调整业务种类、抵质押类型、存单票面利率字段,以及对私新增入口字段剔除
+
+## 修改内容
+
+### 后端
+
+- 个人新增 DTO:
+ - 业务种类调整为 `新增/存量新增/存量转贷`。
+ - 移除 `loanPurpose`、`bizProof` 新增入口字段。
+ - 新增 `couponRate`。
+- 企业新增 DTO:
+ - 业务种类调整为 `新增/存量新增/存量转贷`。
+ - 企业抵押类型调整为 `一类/二类/三类/四类/排污权抵押/设备等其他不动产抵押`。
+ - 企业质押类型调整为 `存单质押/股权质押/其他质押`。
+ - 新增 `couponRate`。
+- 流程实体和模型入参:
+ - `LoanPricingWorkflow` 新增 `couponRate`。
+ - `ModelInvokeDTO` 新增 `couponRate`,未增加 `businessType` 模型入参。
+- 转换器:
+ - 个人/企业新增 DTO 均映射 `couponRate`。
+ - 个人新增 DTO 不再映射 `loanPurpose`、`bizProof`。
+- 服务校验:
+ - 业务种类仅允许 `新增/存量新增/存量转贷`。
+ - 仅 `存量转贷` 要求历史贷款合同。
+ - 抵押/质押时要求选择抵质押类型。
+ - 对私/对公按客户类型和担保方式校验各自抵质押类型。
+ - `质押 + 存单质押` 时要求填写 `couponRate`。
+- SQL:
+ - 新增 `sql/add_coupon_rate_20260511.sql`。
+ - 同步更新 `loan_pricing_workflow` 建表脚本中的 `coupon_rate` 字段。
+
+### 前端
+
+- 个人新增弹窗:
+ - 业务种类调整为 `新增/存量新增/存量转贷`。
+ - 移除 `贷款用途` 和 `是否有经营佐证`。
+ - 抵押类型调整为 `一线/一类/二类/三类`。
+ - 质押类型调整为 `存单质押/其他质押`。
+ - `质押 + 存单质押` 时显示并必填 `存单票面利率`。
+- 企业新增弹窗:
+ - 业务种类调整为 `新增/存量新增/存量转贷`。
+ - 抵押类型调整为 `一类/二类/三类/四类/排污权抵押/设备等其他不动产抵押`。
+ - 质押类型调整为 `存单质押/股权质押/其他质押`。
+ - `质押 + 存单质押` 时显示并必填 `存单票面利率`。
+- 共同逻辑:
+ - 仅 `存量转贷` 触发历史贷款合同查询。
+ - 非存单质押提交时清理 `couponRate`。
+
+## 验证结果
+
+- 后端单元测试:
+ - `mvn -pl ruoyi-loan-pricing -am -Dtest=LoanPricingWorkflowServiceImplTest,LoanPricingModelServicePersonalParamsTest,LoanPricingModelServiceTest -Dsurefire.failIfNoSpecifiedTests=false test`
+ - 结果:通过,23 个测试全部成功。
+- 前端静态断言:
+ - `zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run test:personal-create-input-params && npm --prefix ruoyi-ui run test:corporate-create-input-params && npm --prefix ruoyi-ui run test:business-type-history-rate'`
+ - 结果:通过。
+- 前端生产构建:
+ - `zsh -lic 'nvm use 14.21.3 >/dev/null && npm --prefix ruoyi-ui run build:prod'`
+ - 结果:构建通过,仅存在既有包体积 warning。
+- 真实页面验证:
+ - 使用 Playwright 打开 `http://localhost:1024/index`。
+ - 使用 `/login/test` 获取登录 token 后访问真实流程列表页面。
+ - 个人新增弹窗验证:已移除 `贷款用途/是否有经营佐证`;业务种类仅 `存量转贷` 触发历史利率逻辑;个人抵押/质押选项正确;`存单质押` 下 `couponRate` 显示并进入必填校验。
+ - 企业新增弹窗验证:抵押/质押选项正确;`存单质押` 下 `couponRate` 显示并进入必填校验;业务种类仅 `存量转贷` 触发历史利率逻辑。
+ - 验证后已关闭 Playwright 浏览器会话;本次未新启动前后端进程。
+
+## 注意事项
+
+- 控制台中的 `sockjs-node` 报错来自本地 dev-server HMR 连接内网地址失败,不影响本次页面功能验证。
+- 表单校验 warning 来自验证时故意触发必填校验。
diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java
index 2d5d63b..1465827 100644
--- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java
+++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/CorporateLoanPricingCreateDTO.java
@@ -41,9 +41,9 @@ public class CorporateLoanPricingCreateDTO implements Serializable {
@NotBlank(message = "申请金额不能为空")
private String applyAmt;
- @Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新客", "存量新增", "存量转贷"})
+ @Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新增", "存量新增", "存量转贷"})
@NotBlank(message = "业务种类不能为空")
- @Pattern(regexp = "^(新客|存量新增|存量转贷)$", message = "业务种类必须是:新客、存量新增、存量转贷之一")
+ @Pattern(regexp = "^(新增|存量新增|存量转贷)$", message = "业务种类必须是:新增、存量新增、存量转贷之一")
private String businessType;
@Schema(description = "历史贷款利率", example = "3.65")
@@ -62,10 +62,13 @@ public class CorporateLoanPricingCreateDTO implements Serializable {
@Schema(description = "贸易和建筑业企业标识", example = "0")
private String isTradeBuildEnt;
- @Schema(description = "抵质押类型", example = "一类", allowableValues = {"一类", "二类", "三类", "四类", "其他", "存单质押"})
- @Pattern(regexp = "^(一类|二类|三类|四类|其他|存单质押)$", message = "抵质押类型必须是:一类、二类、三类、四类、其他、存单质押之一")
+ @Schema(description = "抵质押类型", example = "一类", allowableValues = {"一类", "二类", "三类", "四类", "排污权抵押", "设备等其他不动产抵押", "存单质押", "股权质押", "其他质押"})
+ @Pattern(regexp = "^(一类|二类|三类|四类|排污权抵押|设备等其他不动产抵押|存单质押|股权质押|其他质押)$", message = "抵质押类型必须是:一类、二类、三类、四类、排污权抵押、设备等其他不动产抵押、存单质押、股权质押、其他质押之一")
private String collType;
@Schema(description = "抵质押物是否三方所有", example = "0")
private String collThirdParty;
+
+ @Schema(description = "存单票面利率", example = "2.15")
+ private String couponRate;
}
diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java
index 4492ac7..7a65b75 100644
--- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java
+++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/ModelInvokeDTO.java
@@ -158,6 +158,11 @@ public class ModelInvokeDTO {
*/
private String loanRateHistory;
+ /**
+ * 存单票面利率
+ */
+ private String couponRate;
+
// /**
// * 贷款利率(必填)
// */
diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java
index 76b6e0d..c8ca9c3 100644
--- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java
+++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/domain/dto/PersonalLoanPricingCreateDTO.java
@@ -41,14 +41,9 @@ public class PersonalLoanPricingCreateDTO implements Serializable {
@NotBlank(message = "申请金额不能为空")
private String applyAmt;
- @Schema(description = "贷款用途", requiredMode = Schema.RequiredMode.REQUIRED, example = "business", allowableValues = {"consumer", "business"})
- @NotBlank(message = "贷款用途不能为空")
- @Pattern(regexp = "^(consumer|business)$", message = "贷款用途必须是:consumer、business之一")
- private String loanPurpose;
-
- @Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新客", "存量新增", "存量转贷"})
+ @Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新增", "存量新增", "存量转贷"})
@NotBlank(message = "业务种类不能为空")
- @Pattern(regexp = "^(新客|存量新增|存量转贷)$", message = "业务种类必须是:新客、存量新增、存量转贷之一")
+ @Pattern(regexp = "^(新增|存量新增|存量转贷)$", message = "业务种类必须是:新增、存量新增、存量转贷之一")
private String businessType;
@Schema(description = "历史贷款利率", example = "3.65")
@@ -58,15 +53,15 @@ public class PersonalLoanPricingCreateDTO implements Serializable {
@NotBlank(message = "借款期限不能为空")
private String loanTerm;
- @Schema(description = "是否有经营佐证", example = "1")
- private String bizProof;
-
@Schema(description = "循环功能", example = "0")
private String loanLoop;
- @Schema(description = "抵质押类型", example = "一类")
+ @Schema(description = "抵质押类型", example = "一类", allowableValues = {"一线", "一类", "二类", "三类", "存单质押", "其他质押"})
private String collType;
@Schema(description = "抵质押物是否三方所有", example = "0")
private String collThirdParty;
+
+ @Schema(description = "存单票面利率", example = "2.15")
+ private String couponRate;
}
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 da13512..6644311 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
@@ -103,12 +103,15 @@ public class LoanPricingWorkflow implements Serializable
/** 贷款用途: consumer-消费/business-经营 */
private String loanPurpose;
- /** 业务种类: 新客/存量新增/存量转贷 */
+ /** 业务种类: 新增/存量新增/存量转贷 */
private String businessType;
/** 历史贷款利率 */
private String loanRateHistory;
+ /** 存单票面利率 */
+ private String couponRate;
+
/** 是否有经营佐证: true/false */
private String bizProof;
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 046c90f..c2cfc65 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
@@ -67,6 +67,7 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
public LoanPricingWorkflow createLoanPricing(LoanPricingWorkflow loanPricingWorkflow)
{
validateBusinessTypeAndHistoryRate(loanPricingWorkflow);
+ validateCollateralTypeAndCouponRate(loanPricingWorkflow);
// 自动生成业务方流水号(时间戳)
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
@@ -95,10 +96,10 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
if (!StringUtils.hasText(workflow.getBusinessType())) {
throw new ServiceException("业务种类不能为空");
}
- if (!"新客".equals(workflow.getBusinessType())
+ if (!"新增".equals(workflow.getBusinessType())
&& !"存量新增".equals(workflow.getBusinessType())
&& !"存量转贷".equals(workflow.getBusinessType())) {
- throw new ServiceException("业务种类必须是:新客、存量新增、存量转贷之一");
+ throw new ServiceException("业务种类必须是:新增、存量新增、存量转贷之一");
}
if ("存量转贷".equals(workflow.getBusinessType())
&& !StringUtils.hasText(workflow.getLoanRateHistory())) {
@@ -106,6 +107,57 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
}
}
+ private void validateCollateralTypeAndCouponRate(LoanPricingWorkflow workflow) {
+ if (!"抵押".equals(workflow.getGuarType()) && !"质押".equals(workflow.getGuarType())) {
+ return;
+ }
+ if (!StringUtils.hasText(workflow.getCollType())) {
+ throw new ServiceException("请选择抵质押类型");
+ }
+ if ("个人".equals(workflow.getCustType())) {
+ validatePersonalCollateralType(workflow);
+ }
+ if ("企业".equals(workflow.getCustType())) {
+ validateCorporateCollateralType(workflow);
+ }
+ if ("质押".equals(workflow.getGuarType())
+ && "存单质押".equals(workflow.getCollType())
+ && !StringUtils.hasText(workflow.getCouponRate())) {
+ throw new ServiceException("存单票面利率不能为空");
+ }
+ }
+
+ private void validatePersonalCollateralType(LoanPricingWorkflow workflow) {
+ if ("抵押".equals(workflow.getGuarType())
+ && !isOneOf(workflow.getCollType(), "一线", "一类", "二类", "三类")) {
+ throw new ServiceException("个人抵押抵质押类型必须是:一线、一类、二类、三类之一");
+ }
+ if ("质押".equals(workflow.getGuarType())
+ && !isOneOf(workflow.getCollType(), "存单质押", "其他质押")) {
+ throw new ServiceException("个人质押抵质押类型必须是:存单质押、其他质押之一");
+ }
+ }
+
+ private void validateCorporateCollateralType(LoanPricingWorkflow workflow) {
+ if ("抵押".equals(workflow.getGuarType())
+ && !isOneOf(workflow.getCollType(), "一类", "二类", "三类", "四类", "排污权抵押", "设备等其他不动产抵押")) {
+ throw new ServiceException("企业抵押抵质押类型必须是:一类、二类、三类、四类、排污权抵押、设备等其他不动产抵押之一");
+ }
+ if ("质押".equals(workflow.getGuarType())
+ && !isOneOf(workflow.getCollType(), "存单质押", "股权质押", "其他质押")) {
+ throw new ServiceException("企业质押抵质押类型必须是:存单质押、股权质押、其他质押之一");
+ }
+ }
+
+ private boolean isOneOf(String value, String... allowedValues) {
+ for (String allowedValue : allowedValues) {
+ if (allowedValue.equals(value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* 发起个人客户利率定价流程
*
diff --git a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java
index 9ac0fa1..44ada46 100644
--- a/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java
+++ b/ruoyi-loan-pricing/src/main/java/com/ruoyi/loanpricing/util/LoanPricingConverter.java
@@ -28,14 +28,13 @@ public class LoanPricingConverter {
entity.setIdNum(dto.getIdNum());
entity.setGuarType(dto.getGuarType());
entity.setApplyAmt(dto.getApplyAmt());
- entity.setLoanPurpose(dto.getLoanPurpose());
entity.setBusinessType(dto.getBusinessType());
entity.setLoanRateHistory(dto.getLoanRateHistory());
+ entity.setCouponRate(dto.getCouponRate());
entity.setLoanTerm(dto.getLoanTerm());
entity.setCollType(dto.getCollType());
entity.setCollThirdParty(dto.getCollThirdParty());
// 映射个人特有字段
- entity.setBizProof(dto.getBizProof());
entity.setLoanLoop(dto.getLoanLoop());
return entity;
}
@@ -58,6 +57,7 @@ public class LoanPricingConverter {
entity.setApplyAmt(dto.getApplyAmt());
entity.setBusinessType(dto.getBusinessType());
entity.setLoanRateHistory(dto.getLoanRateHistory());
+ entity.setCouponRate(dto.getCouponRate());
entity.setRepayMethod(dto.getRepayMethod());
entity.setCollType(dto.getCollType());
entity.setCollThirdParty(dto.getCollThirdParty());
diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java
index 202aa67..31ac3dd 100644
--- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java
+++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServicePersonalParamsTest.java
@@ -18,6 +18,7 @@ import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
@@ -46,24 +47,28 @@ class LoanPricingModelServicePersonalParamsTest {
private LoanPricingModelService loanPricingModelService;
@Test
- void shouldContainLoanPurposeAndLoanTermInPersonalCreateDto() throws NoSuchFieldException {
- assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
+ void shouldRemoveLoanPurposeAndKeepLoanTermInPersonalCreateDto() throws NoSuchFieldException {
+ assertThrows(NoSuchFieldException.class,
+ () -> PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
+ assertThrows(NoSuchFieldException.class,
+ () -> PersonalLoanPricingCreateDTO.class.getDeclaredField("bizProof"));
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanTerm"));
}
@Test
- void shouldMapLoanPurposeAndLoanTermFromPersonalDto() {
+ void shouldNotMapLoanPurposeAndBizProofFromPersonalDto() {
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
dto.setCustIsn("CUST001");
dto.setCustName("张三");
dto.setGuarType("信用");
dto.setApplyAmt("100000");
- dto.setLoanPurpose("business");
+ dto.setBusinessType("新增");
dto.setLoanTerm("3");
LoanPricingWorkflow workflow = LoanPricingConverter.toEntity(dto);
- assertEquals("business", workflow.getLoanPurpose());
+ assertNull(workflow.getLoanPurpose());
+ assertNull(workflow.getBizProof());
assertEquals("3", workflow.getLoanTerm());
}
@@ -87,9 +92,7 @@ class LoanPricingModelServicePersonalParamsTest {
workflow.setIdNum("cipher-id");
workflow.setGuarType("信用");
workflow.setApplyAmt("100000");
- workflow.setLoanPurpose("business");
workflow.setLoanTerm("3");
- workflow.setBizProof("true");
workflow.setLoanLoop("false");
workflow.setCollThirdParty("true");
workflow.setCollType("一类");
@@ -115,9 +118,7 @@ class LoanPricingModelServicePersonalParamsTest {
&& Objects.equals("110101199001011234", dto.getIdNum())
&& Objects.equals("信用", dto.getGuarType())
&& Objects.equals("100000", dto.getApplyAmt())
- && Objects.equals("business", dto.getLoanPurpose())
&& Objects.equals("3", dto.getLoanTerm())
- && Objects.equals("1", dto.getBizProof())
&& Objects.equals("0", dto.getLoanLoop())
&& Objects.equals("1", dto.getCollThirdParty())
&& Objects.equals("一类", dto.getCollType())));
diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java
index 7aa060d..5a2dfa4 100644
--- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java
+++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/LoanPricingModelServiceTest.java
@@ -29,6 +29,7 @@ class LoanPricingModelServiceTest
assertEquals("张三", context.modelService.personalRequest.getCustName());
assertEquals("110101199001011234", context.modelService.personalRequest.getIdNum());
+ assertEquals("2.15", context.modelService.personalRequest.getCouponRate());
assertEquals(1, context.modelService.personalCalls.get());
assertEquals(0, context.modelService.corporateCalls.get());
assertEquals(1, context.retailInsertCount.get());
@@ -59,6 +60,7 @@ class LoanPricingModelServiceTest
workflow.setIsGreenLoan("true");
workflow.setIsTradeBuildEnt("false");
workflow.setCollThirdParty("true");
+ workflow.setCouponRate("2.35");
TestContext context = createContext(workflow);
context.service.invokeModelAsync(3L);
@@ -68,6 +70,7 @@ class LoanPricingModelServiceTest
assertEquals("1", request.getIsGreenLoan());
assertEquals("0", request.getIsTradeBuildEnt());
assertEquals("1", request.getCollThirdParty());
+ assertEquals("2.35", request.getCouponRate());
assertEquals(0, context.modelService.personalCalls.get());
assertEquals(1, context.modelService.corporateCalls.get());
assertEquals(0, context.retailInsertCount.get());
@@ -81,6 +84,7 @@ class LoanPricingModelServiceTest
workflow.setCustType("个人");
workflow.setCustName("cipher-name");
workflow.setIdNum("cipher-id");
+ workflow.setCouponRate("2.15");
return workflow;
}
diff --git a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java
index dac8aa5..640563e 100644
--- a/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java
+++ b/ruoyi-loan-pricing/src/test/java/com/ruoyi/loanpricing/service/impl/LoanPricingWorkflowServiceImplTest.java
@@ -1,6 +1,7 @@
package com.ruoyi.loanpricing.service.impl;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
@@ -12,6 +13,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.loanpricing.domain.dto.CorporateLoanPricingCreateDTO;
+import com.ruoyi.loanpricing.domain.dto.PersonalLoanPricingCreateDTO;
import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow;
import com.ruoyi.loanpricing.domain.entity.ModelCorpOutputFields;
import com.ruoyi.loanpricing.domain.entity.ModelRetailOutputFields;
@@ -65,6 +69,7 @@ class LoanPricingWorkflowServiceImplTest
workflow.setCustName("张三");
workflow.setIdNum("110101199001011234");
workflow.setCustIsn("CUST001");
+ workflow.setBusinessType("新增");
when(sensitiveFieldCryptoService.encrypt("张三")).thenReturn("cipher-name");
when(sensitiveFieldCryptoService.encrypt("110101199001011234")).thenReturn("cipher-id");
@@ -133,6 +138,134 @@ class LoanPricingWorkflowServiceImplTest
assertTrue(!sqlSegment.contains("cust_name"), sqlSegment);
}
+ @Test
+ void shouldRejectOldBusinessType()
+ {
+ LoanPricingWorkflow workflow = validWorkflow();
+ workflow.setBusinessType("新客");
+
+ ServiceException exception = assertThrows(ServiceException.class,
+ () -> loanPricingWorkflowService.createLoanPricing(workflow));
+
+ assertEquals("业务种类必须是:新增、存量新增、存量转贷之一", exception.getMessage());
+ }
+
+ @Test
+ void shouldRequireHistoryRateForStockTransfer()
+ {
+ LoanPricingWorkflow workflow = validWorkflow();
+ workflow.setBusinessType("存量转贷");
+
+ ServiceException exception = assertThrows(ServiceException.class,
+ () -> loanPricingWorkflowService.createLoanPricing(workflow));
+
+ assertEquals("请选择历史贷款合同", exception.getMessage());
+ }
+
+ @Test
+ void shouldRequireCouponRateForCertificatePledge()
+ {
+ LoanPricingWorkflow workflow = validWorkflow();
+ workflow.setCustType("企业");
+ workflow.setGuarType("质押");
+ workflow.setCollType("存单质押");
+
+ ServiceException exception = assertThrows(ServiceException.class,
+ () -> loanPricingWorkflowService.createLoanPricing(workflow));
+
+ assertEquals("存单票面利率不能为空", exception.getMessage());
+ }
+
+ @Test
+ void shouldAllowPersonalMortgageOneLineAndRejectOldOther()
+ {
+ LoanPricingWorkflow allowedWorkflow = validWorkflow();
+ allowedWorkflow.setCustType("个人");
+ allowedWorkflow.setGuarType("抵押");
+ allowedWorkflow.setCollType("一线");
+
+ loanPricingWorkflowService.createLoanPricing(allowedWorkflow);
+
+ LoanPricingWorkflow rejectedWorkflow = validWorkflow();
+ rejectedWorkflow.setCustType("个人");
+ rejectedWorkflow.setGuarType("抵押");
+ rejectedWorkflow.setCollType("其他");
+
+ ServiceException exception = assertThrows(ServiceException.class,
+ () -> loanPricingWorkflowService.createLoanPricing(rejectedWorkflow));
+
+ assertEquals("个人抵押抵质押类型必须是:一线、一类、二类、三类之一", exception.getMessage());
+ }
+
+ @Test
+ void shouldAllowCorporateMortgagePollutionRightAndPledgeEquity()
+ {
+ LoanPricingWorkflow mortgageWorkflow = validWorkflow();
+ mortgageWorkflow.setCustType("企业");
+ mortgageWorkflow.setGuarType("抵押");
+ mortgageWorkflow.setCollType("排污权抵押");
+
+ loanPricingWorkflowService.createLoanPricing(mortgageWorkflow);
+
+ LoanPricingWorkflow pledgeWorkflow = validWorkflow();
+ pledgeWorkflow.setCustType("企业");
+ pledgeWorkflow.setGuarType("质押");
+ pledgeWorkflow.setCollType("股权质押");
+
+ loanPricingWorkflowService.createLoanPricing(pledgeWorkflow);
+
+ LoanPricingWorkflow rejectedWorkflow = validWorkflow();
+ rejectedWorkflow.setCustType("企业");
+ rejectedWorkflow.setGuarType("质押");
+ rejectedWorkflow.setCollType("其他");
+
+ ServiceException exception = assertThrows(ServiceException.class,
+ () -> loanPricingWorkflowService.createLoanPricing(rejectedWorkflow));
+
+ assertEquals("企业质押抵质押类型必须是:存单质押、股权质押、其他质押之一", exception.getMessage());
+ }
+
+ @Test
+ void shouldCreatePersonalWorkflowWithCouponRateAndWithoutRemovedFields()
+ {
+ PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
+ dto.setCustIsn("CUST001");
+ dto.setGuarType("质押");
+ dto.setApplyAmt("100000");
+ dto.setBusinessType("新增");
+ dto.setLoanTerm("3");
+ dto.setCollType("存单质押");
+ dto.setCouponRate("2.15");
+
+ loanPricingWorkflowService.createPersonalLoanPricing(dto);
+
+ verify(loanPricingWorkflowMapper).insert(argThat((LoanPricingWorkflow entity) ->
+ Objects.equals("个人", entity.getCustType())
+ && Objects.equals("2.15", entity.getCouponRate())
+ && Objects.isNull(entity.getLoanPurpose())
+ && Objects.isNull(entity.getBizProof())));
+ }
+
+ @Test
+ void shouldCreateCorporateWorkflowWithCouponRateAndBusinessType()
+ {
+ CorporateLoanPricingCreateDTO dto = new CorporateLoanPricingCreateDTO();
+ dto.setCustIsn("CORP001");
+ dto.setGuarType("质押");
+ dto.setApplyAmt("1000000");
+ dto.setBusinessType("新增");
+ dto.setLoanTerm("3");
+ dto.setCollType("存单质押");
+ dto.setCouponRate("2.35");
+
+ loanPricingWorkflowService.createCorporateLoanPricing(dto);
+
+ verify(loanPricingWorkflowMapper).insert(argThat((LoanPricingWorkflow entity) ->
+ Objects.equals("企业", entity.getCustType())
+ && Objects.equals("新增", entity.getBusinessType())
+ && Objects.equals("2.35", entity.getCouponRate())));
+ }
+
@Test
void shouldUseRetailModelOutputFinalCalculateRateForWorkflowDetail()
{
@@ -255,4 +388,15 @@ class LoanPricingWorkflowServiceImplTest
assertEquals("测试****公司", result.getModelCorpOutputFields().getCustName());
assertEquals("91*************00X", result.getModelCorpOutputFields().getIdNum());
}
+
+ private LoanPricingWorkflow validWorkflow()
+ {
+ LoanPricingWorkflow workflow = new LoanPricingWorkflow();
+ workflow.setCustIsn("CUST001");
+ workflow.setCustType("个人");
+ workflow.setGuarType("信用");
+ workflow.setApplyAmt("100000");
+ workflow.setBusinessType("新增");
+ return workflow;
+ }
}
diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue
index 8b5b74a..02f04d3 100644
--- a/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue
+++ b/ruoyi-ui/src/views/loanPricing/workflow/components/CorporateCreateDialog.vue
@@ -64,7 +64,7 @@
-
+
@@ -107,6 +107,11 @@
+
+
+
+
+
{
+ if (this.isCertificatePledge && !value) {
+ callback(new Error('存单票面利率不能为空'))
+ return
+ }
+ callback()
+ }
+
// 贷款期限验证
const validateLoanTerm = (rule, value, callback) => {
if (!value && value !== 0) {
@@ -196,7 +209,8 @@ export default {
isGreenLoan: false,
isTradeBuildEnt: false,
collType: undefined,
- collThirdParty: false
+ collThirdParty: false,
+ couponRate: undefined
},
rules: {
custIsn: [
@@ -230,6 +244,9 @@ export default {
],
collType: [
{required: true, message: "请选择抵质押类型", trigger: "change"}
+ ],
+ couponRate: [
+ {validator: validateCouponRate, trigger: "blur"}
]
}
}
@@ -249,12 +266,15 @@ export default {
isStockTransfer() {
return this.form.businessType === '存量转贷'
},
+ isCertificatePledge() {
+ return this.form.guarType === '质押' && this.form.collType === '存单质押'
+ },
collateralTypeOptions() {
if (this.form.guarType === '抵押') {
- return ['一类', '二类', '三类', '四类', '其他']
+ return ['一类', '二类', '三类', '四类', '排污权抵押', '设备等其他不动产抵押']
}
if (this.form.guarType === '质押') {
- return ['存单质押', '其他']
+ return ['存单质押', '股权质押', '其他质押']
}
return []
}
@@ -269,6 +289,9 @@ export default {
if (val !== oldVal) {
this.resetCollateralFields()
}
+ },
+ 'form.collType'() {
+ this.resetCouponRateIfNotCertificatePledge()
}
},
methods: {
@@ -289,7 +312,8 @@ export default {
isGreenLoan: false,
isTradeBuildEnt: false,
collType: undefined,
- collThirdParty: false
+ collThirdParty: false,
+ couponRate: undefined
}
this.submitting = false
this.showHistorySelector = false
@@ -315,12 +339,23 @@ export default {
resetCollateralFields() {
this.form.collType = undefined
this.form.collThirdParty = false
+ this.resetCouponRateIfNotCertificatePledge()
this.$nextTick(() => {
if (this.$refs.form) {
- this.$refs.form.clearValidate(['collType', 'collThirdParty'])
+ this.$refs.form.clearValidate(['collType', 'collThirdParty', 'couponRate'])
}
})
},
+ resetCouponRateIfNotCertificatePledge() {
+ if (!this.isCertificatePledge) {
+ this.form.couponRate = undefined
+ this.$nextTick(() => {
+ if (this.$refs.form) {
+ this.$refs.form.clearValidate(['couponRate'])
+ }
+ })
+ }
+ },
handleBusinessTypeChange(value) {
this.clearHistoryContract()
if (value === '存量转贷') {
@@ -370,6 +405,10 @@ export default {
this.$modal.msgWarning("请选择历史贷款合同")
return
}
+ if (this.isCertificatePledge && !this.form.couponRate) {
+ this.$modal.msgWarning("存单票面利率不能为空")
+ return
+ }
this.submitting = true
// 转换开关值为字符串
const data = {
@@ -386,6 +425,9 @@ export default {
if (!this.isStockTransfer) {
delete data.loanRateHistory
}
+ if (!this.isCertificatePledge) {
+ delete data.couponRate
+ }
createCorporateWorkflow(data).then(response => {
this.$modal.msgSuccess("新增成功")
diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue
index 261e782..15309e2 100644
--- a/ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue
+++ b/ruoyi-ui/src/views/loanPricing/workflow/components/PersonalCreateDialog.vue
@@ -52,14 +52,6 @@
-
-
-
-
-
-
-
-
@@ -72,7 +64,7 @@
-
+
@@ -85,11 +77,6 @@
-
-
-
-
-
@@ -112,6 +99,11 @@
+
+
+
+
+
{
+ if (this.isCertificatePledge && !value) {
+ callback(new Error('存单票面利率不能为空'))
+ return
+ }
+ callback()
+ }
+
return {
loanTermOptions: [
'1', '2', '3', '4', '5', '6'
@@ -181,14 +181,13 @@ export default {
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
guarType: undefined,
applyAmt: undefined,
- loanPurpose: undefined,
loanTerm: undefined,
businessType: undefined,
loanRateHistory: undefined,
- bizProof: false,
loanLoop: false,
collType: undefined,
- collThirdParty: false
+ collThirdParty: false,
+ couponRate: undefined
},
rules: {
custIsn: [
@@ -211,9 +210,6 @@ export default {
applyAmt: [
{required: true, validator: validateApplyAmt, trigger: "blur"}
],
- loanPurpose: [
- {required: true, message: "请选择贷款用途", trigger: "change"}
- ],
loanTerm: [
{required: true, message: "请选择借款期限", trigger: "change"}
],
@@ -222,6 +218,12 @@ export default {
],
loanRateHistory: [
{required: true, message: "请选择历史贷款合同", trigger: "change"}
+ ],
+ collType: [
+ {required: true, message: "请选择抵质押类型", trigger: "change"}
+ ],
+ couponRate: [
+ {validator: validateCouponRate, trigger: "blur"}
]
}
}
@@ -241,12 +243,15 @@ export default {
isStockTransfer() {
return this.form.businessType === '存量转贷'
},
+ isCertificatePledge() {
+ return this.form.guarType === '质押' && this.form.collType === '存单质押'
+ },
collateralTypeOptions() {
if (this.form.guarType === '抵押') {
- return ['一类', '二类', '三类', '四类', '其他']
+ return ['一线', '一类', '二类', '三类']
}
if (this.form.guarType === '质押') {
- return ['存单质押', '其他']
+ return ['存单质押', '其他质押']
}
return []
}
@@ -261,6 +266,9 @@ export default {
if (val !== oldVal) {
this.resetCollateralFields()
}
+ },
+ 'form.collType'() {
+ this.resetCouponRateIfNotCertificatePledge()
}
},
methods: {
@@ -275,14 +283,13 @@ export default {
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
guarType: undefined,
applyAmt: undefined,
- loanPurpose: undefined,
loanTerm: undefined,
businessType: undefined,
loanRateHistory: undefined,
- bizProof: false,
loanLoop: false,
collType: undefined,
- collThirdParty: false
+ collThirdParty: false,
+ couponRate: undefined
}
this.submitting = false
this.showHistorySelector = false
@@ -308,12 +315,23 @@ export default {
resetCollateralFields() {
this.form.collType = undefined
this.form.collThirdParty = false
+ this.resetCouponRateIfNotCertificatePledge()
this.$nextTick(() => {
if (this.$refs.form) {
- this.$refs.form.clearValidate(['collType', 'collThirdParty'])
+ this.$refs.form.clearValidate(['collType', 'collThirdParty', 'couponRate'])
}
})
},
+ resetCouponRateIfNotCertificatePledge() {
+ if (!this.isCertificatePledge) {
+ this.form.couponRate = undefined
+ this.$nextTick(() => {
+ if (this.$refs.form) {
+ this.$refs.form.clearValidate(['couponRate'])
+ }
+ })
+ }
+ },
handleBusinessTypeChange(value) {
this.clearHistoryContract()
if (value === '存量转贷') {
@@ -363,11 +381,14 @@ export default {
this.$modal.msgWarning("请选择历史贷款合同")
return
}
+ if (this.isCertificatePledge && !this.form.couponRate) {
+ this.$modal.msgWarning("存单票面利率不能为空")
+ return
+ }
this.submitting = true
// 转换开关值为字符串
const data = {
...this.form,
- bizProof: this.form.bizProof ? '1' : '0',
loanLoop: this.form.loanLoop ? '1' : '0'
}
if (this.isCollateralGuarantee) {
@@ -379,6 +400,9 @@ export default {
if (!this.isStockTransfer) {
delete data.loanRateHistory
}
+ if (!this.isCertificatePledge) {
+ delete data.couponRate
+ }
createPersonalWorkflow(data).then(response => {
this.$modal.msgSuccess("新增成功")
diff --git a/ruoyi-ui/tests/personal-create-input-params.test.js b/ruoyi-ui/tests/personal-create-input-params.test.js
index 4ee6149..332bc52 100644
--- a/ruoyi-ui/tests/personal-create-input-params.test.js
+++ b/ruoyi-ui/tests/personal-create-input-params.test.js
@@ -10,8 +10,10 @@ const personalCreateDialog = read('src/views/loanPricing/workflow/components/Per
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
assert(
- personalCreateDialog.includes('label="贷款用途"') && personalCreateDialog.includes('prop="loanPurpose"'),
- '个人新增弹窗缺少贷款用途字段'
+ !personalCreateDialog.includes('label="贷款用途"') &&
+ !personalCreateDialog.includes('prop="loanPurpose"') &&
+ !personalCreateDialog.includes('loanPurpose:'),
+ '个人新增弹窗不应继续保留贷款用途字段'
)
assert(
@@ -20,8 +22,8 @@ assert(
)
assert(
- personalCreateDialog.includes("value=\"consumer\"") && personalCreateDialog.includes("value=\"business\""),
- '个人新增弹窗缺少贷款用途选项'
+ !personalCreateDialog.includes("value=\"consumer\"") && !personalCreateDialog.includes("value=\"business\""),
+ '个人新增弹窗不应继续保留贷款用途选项'
)
assert(
@@ -41,19 +43,20 @@ assert(
assert(
personalCreateDialog.includes('collateralTypeOptions') &&
- personalCreateDialog.includes("return ['一类', '二类', '三类', '四类', '其他']") &&
- personalCreateDialog.includes("return ['存单质押', '其他']") &&
- !personalCreateDialog.includes('label="一线"'),
+ personalCreateDialog.includes("return ['一线', '一类', '二类', '三类']") &&
+ personalCreateDialog.includes("return ['存单质押', '其他质押']"),
'个人新增弹窗抵质押类型选项未按担保方式动态切换'
)
assert(
- !personalCreateDialog.includes('{required: true, message: "请选择抵质押类型", trigger: "change"}'),
- '个人新增弹窗仍将抵质押类型设为必填'
+ personalCreateDialog.includes('{required: true, message: "请选择抵质押类型", trigger: "change"}'),
+ '个人新增弹窗抵质押类型应为必填'
)
assert(
- personalCreateDialog.includes("bizProof: this.form.bizProof ? '1' : '0'") &&
+ !personalCreateDialog.includes('label="是否有经营佐证"') &&
+ !personalCreateDialog.includes('prop="bizProof"') &&
+ !personalCreateDialog.includes('bizProof:') &&
personalCreateDialog.includes("loanLoop: this.form.loanLoop ? '1' : '0'") &&
personalCreateDialog.includes("data.collThirdParty = this.form.collThirdParty ? '1' : '0'") &&
personalCreateDialog.includes('delete data.collType') &&
diff --git a/sql/add_coupon_rate_20260511.sql b/sql/add_coupon_rate_20260511.sql
new file mode 100644
index 0000000..ca1e181
--- /dev/null
+++ b/sql/add_coupon_rate_20260511.sql
@@ -0,0 +1,3 @@
+-- 上虞利率定价存单票面利率字段
+ALTER TABLE `loan_pricing_workflow`
+ ADD COLUMN `coupon_rate` varchar(100) DEFAULT NULL COMMENT '存单票面利率' AFTER `loan_rate_history`;
diff --git a/sql/loan_pricing_prod_init_20260331.sql b/sql/loan_pricing_prod_init_20260331.sql
index dbea035..6367ce1 100644
--- a/sql/loan_pricing_prod_init_20260331.sql
+++ b/sql/loan_pricing_prod_init_20260331.sql
@@ -765,6 +765,7 @@ CREATE TABLE `loan_pricing_workflow` (
`loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营',
`business_type` varchar(20) DEFAULT NULL COMMENT '业务种类',
`loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史贷款利率',
+ `coupon_rate` varchar(100) DEFAULT NULL COMMENT '存单票面利率',
`biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false',
`loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)',
`coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类',
diff --git a/sql/loan_pricing_schema_20260328.sql b/sql/loan_pricing_schema_20260328.sql
index 5ba3769..2c9d5d1 100644
--- a/sql/loan_pricing_schema_20260328.sql
+++ b/sql/loan_pricing_schema_20260328.sql
@@ -347,6 +347,7 @@ CREATE TABLE `loan_pricing_workflow` (
`loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营',
`business_type` varchar(20) DEFAULT NULL COMMENT '业务种类',
`loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史贷款利率',
+ `coupon_rate` varchar(100) DEFAULT NULL COMMENT '存单票面利率',
`biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false',
`loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)',
`coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类',
diff --git a/sql/loan_pricing_workflow.sql b/sql/loan_pricing_workflow.sql
index 7f3fc18..4bea856 100644
--- a/sql/loan_pricing_workflow.sql
+++ b/sql/loan_pricing_workflow.sql
@@ -28,6 +28,7 @@ CREATE TABLE `loan_pricing_workflow` (
`loan_purpose` varchar(20) DEFAULT NULL COMMENT '贷款用途: consumer-消费/business-经营',
`business_type` varchar(20) DEFAULT NULL COMMENT '业务种类',
`loan_rate_history` varchar(100) DEFAULT NULL COMMENT '历史贷款利率',
+ `coupon_rate` varchar(100) DEFAULT NULL COMMENT '存单票面利率',
`biz_proof` varchar(10) DEFAULT NULL COMMENT '是否有经营佐证: true/false',
`loan_loop` varchar(10) DEFAULT NULL COMMENT '循环功能: true/false(贷款合同是否开通循环功能)',
`coll_type` varchar(20) DEFAULT NULL COMMENT '抵质押类型: 一类/二类/三类/四类',