Compare commits
13 Commits
83e1959b94
...
892-withou
| Author | SHA1 | Date | |
|---|---|---|---|
| dd10192c18 | |||
| 3afff5d942 | |||
| b769180bb1 | |||
| cb29c38bf1 | |||
| 9552e2acb8 | |||
| a8ed8472f3 | |||
| 30a1d9771f | |||
| 6b5d31fb92 | |||
| 9d48d4b688 | |||
| 86b50f057e | |||
| 3667a3cf78 | |||
| 739a73c6ee | |||
| 39c7b716cd |
@@ -25,16 +25,16 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:mysql://116.62.17.81:3307/loan-pricing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
url: jdbc:mysql://116.62.17.81:53306/loan_pricing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||||
username: root
|
username: znsj
|
||||||
password: Kfcx@1234
|
password: Znsj@123456
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
slave:
|
slave:
|
||||||
# 从数据源开关/默认关闭
|
# 从数据源开关/默认关闭
|
||||||
enabled: false
|
enabled: false
|
||||||
url:
|
url:
|
||||||
username:
|
username:
|
||||||
password:
|
password:
|
||||||
# 初始连接数
|
# 初始连接数
|
||||||
initialSize: 5
|
initialSize: 5
|
||||||
# 最小连接池数量
|
# 最小连接池数量
|
||||||
|
|||||||
@@ -65,8 +65,16 @@ public class CorporateLoanPricingCreateDTO implements Serializable {
|
|||||||
@Schema(description = "贸易和建筑业企业标识", example = "0")
|
@Schema(description = "贸易和建筑业企业标识", example = "0")
|
||||||
private String isTradeBuildEnt;
|
private String isTradeBuildEnt;
|
||||||
|
|
||||||
@Schema(description = "抵质押类型", example = "一类", allowableValues = {"一类", "二类", "三类", "四类", "排污权抵押", "设备等其他不动产抵押", "存单质押", "股权质押", "其他质押"})
|
@Schema(description = "抵押物性质", example = "普通住宅、土地、厂房", allowableValues = {"普通住宅、土地、厂房", "商业性质不动产", "排污权", "其他不动产"})
|
||||||
@Pattern(regexp = "^(一类|二类|三类|四类|排污权抵押|设备等其他不动产抵押|存单质押|股权质押|其他质押)$", message = "抵质押类型必须是:一类、二类、三类、四类、排污权抵押、设备等其他不动产抵押、存单质押、股权质押、其他质押之一")
|
@Pattern(regexp = "^(普通住宅、土地、厂房|商业性质不动产|排污权|其他不动产)$", message = "抵押物性质必须是:普通住宅、土地、厂房、商业性质不动产、排污权、其他不动产之一")
|
||||||
|
private String collateralNature;
|
||||||
|
|
||||||
|
@Schema(description = "是否属于九地", example = "是", allowableValues = {"是", "否"})
|
||||||
|
@Pattern(regexp = "^(是|否)$", message = "是否属于九地必须是:是、否之一")
|
||||||
|
private String isNineArea;
|
||||||
|
|
||||||
|
@Schema(description = "抵质押类型", example = "一类", allowableValues = {"一类", "二类", "三类", "排污权抵押", "其他不动产抵押", "存单质押", "股权质押", "其他质押"})
|
||||||
|
@Pattern(regexp = "^(一类|二类|三类|排污权抵押|其他不动产抵押|存单质押|股权质押|其他质押)$", message = "抵质押类型必须是:一类、二类、三类、排污权抵押、其他不动产抵押、存单质押、股权质押、其他质押之一")
|
||||||
private String collType;
|
private String collType;
|
||||||
|
|
||||||
@Schema(description = "抵质押物是否三方所有", example = "0")
|
@Schema(description = "抵质押物是否三方所有", example = "0")
|
||||||
|
|||||||
@@ -125,12 +125,12 @@ public class ModelInvokeDTO {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 贷款用途(非必填)
|
* 贷款用途(非必填)
|
||||||
* 可选值:consumer/business
|
* 可选值:经营/消费
|
||||||
*/
|
*/
|
||||||
private String loanPurpose;
|
private String loanPurpose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否有经营佐证(非必填)
|
* 是否有营业执照(非必填)
|
||||||
* 可选值:0/1
|
* 可选值:0/1
|
||||||
*/
|
*/
|
||||||
private String bizProof;
|
private String bizProof;
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ public class PersonalLoanPricingCreateDTO implements Serializable {
|
|||||||
@NotBlank(message = "申请金额不能为空")
|
@NotBlank(message = "申请金额不能为空")
|
||||||
private String applyAmt;
|
private String applyAmt;
|
||||||
|
|
||||||
|
@Schema(description = "贷款用途", requiredMode = Schema.RequiredMode.REQUIRED, example = "business", allowableValues = {"business", "consumer"})
|
||||||
|
@NotBlank(message = "贷款用途不能为空")
|
||||||
|
@Pattern(regexp = "^(business|consumer)$", message = "贷款用途必须是:business、consumer之一")
|
||||||
|
private String loanPurpose;
|
||||||
|
|
||||||
@Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新增", "存量新增", "存量转贷"})
|
@Schema(description = "业务种类", requiredMode = Schema.RequiredMode.REQUIRED, example = "存量转贷", allowableValues = {"新增", "存量新增", "存量转贷"})
|
||||||
@NotBlank(message = "业务种类不能为空")
|
@NotBlank(message = "业务种类不能为空")
|
||||||
@Pattern(regexp = "^(新增|存量新增|存量转贷)$", message = "业务种类必须是:新增、存量新增、存量转贷之一")
|
@Pattern(regexp = "^(新增|存量新增|存量转贷)$", message = "业务种类必须是:新增、存量新增、存量转贷之一")
|
||||||
@@ -53,10 +58,22 @@ public class PersonalLoanPricingCreateDTO implements Serializable {
|
|||||||
@NotBlank(message = "借款期限不能为空")
|
@NotBlank(message = "借款期限不能为空")
|
||||||
private String loanTerm;
|
private String loanTerm;
|
||||||
|
|
||||||
|
@Schema(description = "是否有营业执照", example = "0", allowableValues = {"0", "1"})
|
||||||
|
@Pattern(regexp = "^[01]$", message = "是否有营业执照必须是:0或1")
|
||||||
|
private String bizProof;
|
||||||
|
|
||||||
@Schema(description = "循环功能", example = "0")
|
@Schema(description = "循环功能", example = "0")
|
||||||
private String loanLoop;
|
private String loanLoop;
|
||||||
|
|
||||||
@Schema(description = "抵质押类型", example = "一类", allowableValues = {"一线", "一类", "二类", "三类", "存单质押", "其他质押"})
|
@Schema(description = "抵押物性质", example = "普通住宅、土地、厂房", allowableValues = {"普通住宅、土地、厂房", "商业性质不动产", "其他抵押财产"})
|
||||||
|
@Pattern(regexp = "^(普通住宅、土地、厂房|商业性质不动产|其他抵押财产)$", message = "抵押物性质必须是:普通住宅、土地、厂房、商业性质不动产、其他抵押财产之一")
|
||||||
|
private String collateralNature;
|
||||||
|
|
||||||
|
@Schema(description = "是否属于九地", example = "是", allowableValues = {"是", "否"})
|
||||||
|
@Pattern(regexp = "^(是|否)$", message = "是否属于九地必须是:是、否之一")
|
||||||
|
private String isNineArea;
|
||||||
|
|
||||||
|
@Schema(description = "抵质押类型", example = "一类", allowableValues = {"一类", "二类", "三类", "四类", "存单质押", "其他质押"})
|
||||||
private String collType;
|
private String collType;
|
||||||
|
|
||||||
@Schema(description = "抵质押物是否三方所有", example = "0")
|
@Schema(description = "抵质押物是否三方所有", example = "0")
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
|
|||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -115,7 +116,7 @@ public class LoanPricingWorkflow implements Serializable
|
|||||||
/** 余值覆盖: 0/1 */
|
/** 余值覆盖: 0/1 */
|
||||||
private String resCover;
|
private String resCover;
|
||||||
|
|
||||||
/** 是否有经营佐证: true/false */
|
/** 是否有营业执照: true/false */
|
||||||
private String bizProof;
|
private String bizProof;
|
||||||
|
|
||||||
/** 循环功能: true/false */
|
/** 循环功能: true/false */
|
||||||
@@ -124,6 +125,12 @@ public class LoanPricingWorkflow implements Serializable
|
|||||||
/** 抵质押类型: 一类/二类/三类/四类 */
|
/** 抵质押类型: 一类/二类/三类/四类 */
|
||||||
private String collType;
|
private String collType;
|
||||||
|
|
||||||
|
/** 抵押物性质 */
|
||||||
|
private String collateralNature;
|
||||||
|
|
||||||
|
/** 是否属于九地: 是/否 */
|
||||||
|
private String isNineArea;
|
||||||
|
|
||||||
/** 抵质押物是否三方所有: true/false */
|
/** 抵质押物是否三方所有: true/false */
|
||||||
private String collThirdParty;
|
private String collThirdParty;
|
||||||
|
|
||||||
@@ -164,6 +171,16 @@ public class LoanPricingWorkflow implements Serializable
|
|||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private Long dataScopeDeptId;
|
private Long dataScopeDeptId;
|
||||||
|
|
||||||
|
/** 创建时间查询起始值 */
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Date beginCreateTime;
|
||||||
|
|
||||||
|
/** 创建时间查询结束值 */
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Date endCreateTime;
|
||||||
|
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
|
|||||||
@@ -106,10 +106,20 @@ public class ModelCorpOutputFields {
|
|||||||
private String bpCollateral;
|
private String bpCollateral;
|
||||||
// 灰名单客户
|
// 灰名单客户
|
||||||
private String greyCust;
|
private String greyCust;
|
||||||
|
// 黑名单客户
|
||||||
|
private String blackCust;
|
||||||
// 本金逾期
|
// 本金逾期
|
||||||
private String prinOverdue;
|
private String prinOverdue;
|
||||||
|
// BP_本金逾期
|
||||||
|
private String bpPrinOverdue;
|
||||||
// 利息逾期
|
// 利息逾期
|
||||||
private String interestOverdue;
|
private String interestOverdue;
|
||||||
|
// BP_利息逾期
|
||||||
|
private String bpIinterestOverdue;
|
||||||
|
// 信用卡逾期
|
||||||
|
private String cardOverdue;
|
||||||
|
// BP_信用卡逾期
|
||||||
|
private String bpCardOverdue;
|
||||||
// BP_灰名单与逾期
|
// BP_灰名单与逾期
|
||||||
private String bpGreyOverdue;
|
private String bpGreyOverdue;
|
||||||
// TOTAL_BP_风险度
|
// TOTAL_BP_风险度
|
||||||
@@ -129,6 +139,8 @@ public class ModelCorpOutputFields {
|
|||||||
private String finalCalculateRate;
|
private String finalCalculateRate;
|
||||||
// 参考利率
|
// 参考利率
|
||||||
private String referenceRate;
|
private String referenceRate;
|
||||||
|
// 行社下调BP
|
||||||
|
private String branchBp;
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class ModelRetailOutputFields {
|
|||||||
// 贷款用途
|
// 贷款用途
|
||||||
private String loanPurpose;
|
private String loanPurpose;
|
||||||
|
|
||||||
// 是否有经营佐证
|
// 是否有营业执照
|
||||||
private String bizProof;
|
private String bizProof;
|
||||||
|
|
||||||
// BP_贷款用途
|
// BP_贷款用途
|
||||||
@@ -153,15 +153,27 @@ public class ModelRetailOutputFields {
|
|||||||
// 灰名单客户
|
// 灰名单客户
|
||||||
private String greyCust;
|
private String greyCust;
|
||||||
|
|
||||||
|
// 黑名单客户
|
||||||
|
private String blackCust;
|
||||||
|
|
||||||
// 本金逾期
|
// 本金逾期
|
||||||
private String prinOverdue;
|
private String prinOverdue;
|
||||||
|
|
||||||
|
// BP_本金逾期
|
||||||
|
private String bpPrinOverdue;
|
||||||
|
|
||||||
// 利息逾期
|
// 利息逾期
|
||||||
private String interestOverdue;
|
private String interestOverdue;
|
||||||
|
|
||||||
|
// BP_利息逾期
|
||||||
|
private String bpIinterestOverdue;
|
||||||
|
|
||||||
// 信用卡逾期
|
// 信用卡逾期
|
||||||
private String cardOverdue;
|
private String cardOverdue;
|
||||||
|
|
||||||
|
// BP_信用卡逾期
|
||||||
|
private String bpCardOverdue;
|
||||||
|
|
||||||
// BP_灰名单与逾期
|
// BP_灰名单与逾期
|
||||||
private String bpGreyOverdue;
|
private String bpGreyOverdue;
|
||||||
|
|
||||||
@@ -190,6 +202,9 @@ public class ModelRetailOutputFields {
|
|||||||
// 参考利率
|
// 参考利率
|
||||||
private String referenceRate;
|
private String referenceRate;
|
||||||
|
|
||||||
|
// 行社下调BP
|
||||||
|
private String branchBp;
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
@TableField(fill = FieldFill.INSERT)
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ public class LoanPricingWorkflowListVO
|
|||||||
{
|
{
|
||||||
private String serialNum;
|
private String serialNum;
|
||||||
|
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
private String custIsn;
|
private String custIsn;
|
||||||
|
|
||||||
private String custName;
|
private String custName;
|
||||||
|
|||||||
@@ -102,11 +102,25 @@ public class LoanPricingModelService {
|
|||||||
|
|
||||||
private void normalizePersonalModelInvokeDTO(ModelInvokeDTO modelInvokeDTO)
|
private void normalizePersonalModelInvokeDTO(ModelInvokeDTO modelInvokeDTO)
|
||||||
{
|
{
|
||||||
|
modelInvokeDTO.setLoanPurpose(toPersonalModelLoanPurpose(modelInvokeDTO.getLoanPurpose()));
|
||||||
modelInvokeDTO.setBizProof(toZeroOne(modelInvokeDTO.getBizProof()));
|
modelInvokeDTO.setBizProof(toZeroOne(modelInvokeDTO.getBizProof()));
|
||||||
modelInvokeDTO.setLoanLoop(toZeroOne(modelInvokeDTO.getLoanLoop()));
|
modelInvokeDTO.setLoanLoop(toZeroOne(modelInvokeDTO.getLoanLoop()));
|
||||||
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
|
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String toPersonalModelLoanPurpose(String value)
|
||||||
|
{
|
||||||
|
if ("business".equals(value))
|
||||||
|
{
|
||||||
|
return "经营";
|
||||||
|
}
|
||||||
|
if ("consumer".equals(value))
|
||||||
|
{
|
||||||
|
return "消费";
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private void normalizeCorporateModelInvokeDTO(ModelInvokeDTO modelInvokeDTO)
|
private void normalizeCorporateModelInvokeDTO(ModelInvokeDTO modelInvokeDTO)
|
||||||
{
|
{
|
||||||
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
|
modelInvokeDTO.setCollThirdParty(toZeroOne(modelInvokeDTO.getCollThirdParty()));
|
||||||
|
|||||||
@@ -139,8 +139,8 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
|
|||||||
|
|
||||||
private void validatePersonalCollateralType(LoanPricingWorkflow workflow) {
|
private void validatePersonalCollateralType(LoanPricingWorkflow workflow) {
|
||||||
if ("抵押".equals(workflow.getGuarType())
|
if ("抵押".equals(workflow.getGuarType())
|
||||||
&& !isOneOf(workflow.getCollType(), "一线", "一类", "二类", "三类")) {
|
&& !isOneOf(workflow.getCollType(), "一类", "二类", "三类", "四类")) {
|
||||||
throw new ServiceException("个人抵押抵质押类型必须是:一线、一类、二类、三类之一");
|
throw new ServiceException("个人抵押抵质押类型必须是:一类、二类、三类、四类之一");
|
||||||
}
|
}
|
||||||
if ("质押".equals(workflow.getGuarType())
|
if ("质押".equals(workflow.getGuarType())
|
||||||
&& !isOneOf(workflow.getCollType(), "存单质押", "其他质押")) {
|
&& !isOneOf(workflow.getCollType(), "存单质押", "其他质押")) {
|
||||||
@@ -150,8 +150,8 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
|
|||||||
|
|
||||||
private void validateCorporateCollateralType(LoanPricingWorkflow workflow) {
|
private void validateCorporateCollateralType(LoanPricingWorkflow workflow) {
|
||||||
if ("抵押".equals(workflow.getGuarType())
|
if ("抵押".equals(workflow.getGuarType())
|
||||||
&& !isOneOf(workflow.getCollType(), "一类", "二类", "三类", "四类", "排污权抵押", "设备等其他不动产抵押")) {
|
&& !isOneOf(workflow.getCollType(), "一类", "二类", "三类", "排污权抵押", "其他不动产抵押")) {
|
||||||
throw new ServiceException("企业抵押抵质押类型必须是:一类、二类、三类、四类、排污权抵押、设备等其他不动产抵押之一");
|
throw new ServiceException("企业抵押抵质押类型必须是:一类、二类、三类、排污权抵押、其他不动产抵押之一");
|
||||||
}
|
}
|
||||||
if ("质押".equals(workflow.getGuarType())
|
if ("质押".equals(workflow.getGuarType())
|
||||||
&& !isOneOf(workflow.getCollType(), "存单质押", "股权质押", "其他质押")) {
|
&& !isOneOf(workflow.getCollType(), "存单质押", "股权质押", "其他质押")) {
|
||||||
@@ -242,12 +242,16 @@ public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowServi
|
|||||||
.set(LoanPricingWorkflow::getIdNum, editingWorkflow.getIdNum())
|
.set(LoanPricingWorkflow::getIdNum, editingWorkflow.getIdNum())
|
||||||
.set(LoanPricingWorkflow::getGuarType, editingWorkflow.getGuarType())
|
.set(LoanPricingWorkflow::getGuarType, editingWorkflow.getGuarType())
|
||||||
.set(LoanPricingWorkflow::getApplyAmt, editingWorkflow.getApplyAmt())
|
.set(LoanPricingWorkflow::getApplyAmt, editingWorkflow.getApplyAmt())
|
||||||
|
.set(LoanPricingWorkflow::getLoanPurpose, editingWorkflow.getLoanPurpose())
|
||||||
.set(LoanPricingWorkflow::getBusinessType, editingWorkflow.getBusinessType())
|
.set(LoanPricingWorkflow::getBusinessType, editingWorkflow.getBusinessType())
|
||||||
.set(LoanPricingWorkflow::getLoanRateHistory, editingWorkflow.getLoanRateHistory())
|
.set(LoanPricingWorkflow::getLoanRateHistory, editingWorkflow.getLoanRateHistory())
|
||||||
.set(LoanPricingWorkflow::getCouponRate, editingWorkflow.getCouponRate())
|
.set(LoanPricingWorkflow::getCouponRate, editingWorkflow.getCouponRate())
|
||||||
.set(LoanPricingWorkflow::getLoanTerm, editingWorkflow.getLoanTerm())
|
.set(LoanPricingWorkflow::getLoanTerm, editingWorkflow.getLoanTerm())
|
||||||
|
.set(LoanPricingWorkflow::getCollateralNature, editingWorkflow.getCollateralNature())
|
||||||
|
.set(LoanPricingWorkflow::getIsNineArea, editingWorkflow.getIsNineArea())
|
||||||
.set(LoanPricingWorkflow::getCollType, editingWorkflow.getCollType())
|
.set(LoanPricingWorkflow::getCollType, editingWorkflow.getCollType())
|
||||||
.set(LoanPricingWorkflow::getCollThirdParty, editingWorkflow.getCollThirdParty())
|
.set(LoanPricingWorkflow::getCollThirdParty, editingWorkflow.getCollThirdParty())
|
||||||
|
.set(LoanPricingWorkflow::getBizProof, editingWorkflow.getBizProof())
|
||||||
.set(LoanPricingWorkflow::getLoanLoop, editingWorkflow.getLoanLoop())
|
.set(LoanPricingWorkflow::getLoanLoop, editingWorkflow.getLoanLoop())
|
||||||
.set(LoanPricingWorkflow::getResCover, editingWorkflow.getResCover())
|
.set(LoanPricingWorkflow::getResCover, editingWorkflow.getResCover())
|
||||||
.set(LoanPricingWorkflow::getRepayMethod, editingWorkflow.getRepayMethod())
|
.set(LoanPricingWorkflow::getRepayMethod, editingWorkflow.getRepayMethod())
|
||||||
|
|||||||
@@ -28,13 +28,17 @@ public class LoanPricingConverter {
|
|||||||
entity.setIdNum(dto.getIdNum());
|
entity.setIdNum(dto.getIdNum());
|
||||||
entity.setGuarType(dto.getGuarType());
|
entity.setGuarType(dto.getGuarType());
|
||||||
entity.setApplyAmt(dto.getApplyAmt());
|
entity.setApplyAmt(dto.getApplyAmt());
|
||||||
|
entity.setLoanPurpose(dto.getLoanPurpose());
|
||||||
entity.setBusinessType(dto.getBusinessType());
|
entity.setBusinessType(dto.getBusinessType());
|
||||||
entity.setLoanRateHistory(dto.getLoanRateHistory());
|
entity.setLoanRateHistory(dto.getLoanRateHistory());
|
||||||
entity.setCouponRate(dto.getCouponRate());
|
entity.setCouponRate(dto.getCouponRate());
|
||||||
entity.setLoanTerm(dto.getLoanTerm());
|
entity.setLoanTerm(dto.getLoanTerm());
|
||||||
|
entity.setCollateralNature(dto.getCollateralNature());
|
||||||
|
entity.setIsNineArea(dto.getIsNineArea());
|
||||||
entity.setCollType(dto.getCollType());
|
entity.setCollType(dto.getCollType());
|
||||||
entity.setCollThirdParty(dto.getCollThirdParty());
|
entity.setCollThirdParty(dto.getCollThirdParty());
|
||||||
// 映射个人特有字段
|
// 映射个人特有字段
|
||||||
|
entity.setBizProof(dto.getBizProof());
|
||||||
entity.setLoanLoop(dto.getLoanLoop());
|
entity.setLoanLoop(dto.getLoanLoop());
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
@@ -60,6 +64,8 @@ public class LoanPricingConverter {
|
|||||||
entity.setCouponRate(dto.getCouponRate());
|
entity.setCouponRate(dto.getCouponRate());
|
||||||
entity.setResCover(dto.getResCover());
|
entity.setResCover(dto.getResCover());
|
||||||
entity.setRepayMethod(dto.getRepayMethod());
|
entity.setRepayMethod(dto.getRepayMethod());
|
||||||
|
entity.setCollateralNature(dto.getCollateralNature());
|
||||||
|
entity.setIsNineArea(dto.getIsNineArea());
|
||||||
entity.setCollType(dto.getCollType());
|
entity.setCollType(dto.getCollType());
|
||||||
entity.setCollThirdParty(dto.getCollThirdParty());
|
entity.setCollThirdParty(dto.getCollThirdParty());
|
||||||
entity.setIsGreenLoan(dto.getIsGreenLoan());
|
entity.setIsGreenLoan(dto.getIsGreenLoan());
|
||||||
|
|||||||
@@ -20,13 +20,13 @@
|
|||||||
"loanAvg": "3000000.00",
|
"loanAvg": "3000000.00",
|
||||||
"derivationRate": "1.8",
|
"derivationRate": "1.8",
|
||||||
"totalBpContribution": "12.3",
|
"totalBpContribution": "12.3",
|
||||||
"midEntConnect": "1",
|
"midEntConnect": "-2",
|
||||||
"midEntEffect": "1",
|
"midEntEffect": "0",
|
||||||
"midEntInter": "1",
|
"midEntInter": "-3",
|
||||||
"midEntAccept": "1",
|
"midEntAccept": "0",
|
||||||
"midEntDiscount": "1",
|
"midEntDiscount": "-1",
|
||||||
"midEntEleDdc": "1",
|
"midEntEleDdc": "0",
|
||||||
"midEntWaterDdc": "1",
|
"midEntWaterDdc": "-1",
|
||||||
"bpMid": "6.8",
|
"bpMid": "6.8",
|
||||||
"payroll": "200",
|
"payroll": "200",
|
||||||
"invLoanAmount": "2500000.00",
|
"invLoanAmount": "2500000.00",
|
||||||
@@ -45,8 +45,13 @@
|
|||||||
"collThirdParty": "0",
|
"collThirdParty": "0",
|
||||||
"bpCollateral": "4.5",
|
"bpCollateral": "4.5",
|
||||||
"greyCust": "0",
|
"greyCust": "0",
|
||||||
|
"blackCust": "1",
|
||||||
"prinOverdue": "0",
|
"prinOverdue": "0",
|
||||||
"interestOverdue": "0",
|
"bpPrinOverdue": "0",
|
||||||
|
"interestOverdue": "3",
|
||||||
|
"bpIinterestOverdue": "0",
|
||||||
|
"cardOverdue": "0",
|
||||||
|
"bpCardOverdue": "0",
|
||||||
"bpGreyOverdue": "0",
|
"bpGreyOverdue": "0",
|
||||||
"totalBpRisk": "1.2",
|
"totalBpRisk": "1.2",
|
||||||
"totalBp": "48.2",
|
"totalBp": "48.2",
|
||||||
@@ -56,7 +61,8 @@
|
|||||||
"minRateProduct": "3.10",
|
"minRateProduct": "3.10",
|
||||||
"smoothRange": "-0.20",
|
"smoothRange": "-0.20",
|
||||||
"finalCalculateRate": "3.732",
|
"finalCalculateRate": "3.732",
|
||||||
"referenceRate": "3.432"
|
"referenceRate": "3.432",
|
||||||
|
"branchBp": "-5"
|
||||||
},
|
},
|
||||||
"extensionMap": {},
|
"extensionMap": {},
|
||||||
"reasonMessage": "Running successfully",
|
"reasonMessage": "Running successfully",
|
||||||
|
|||||||
@@ -22,18 +22,18 @@
|
|||||||
"loanAvg": "100000.00",
|
"loanAvg": "100000.00",
|
||||||
"derivationRate": "1.2",
|
"derivationRate": "1.2",
|
||||||
"totalBpContribution": "88",
|
"totalBpContribution": "88",
|
||||||
"midPerCard": "1000.50",
|
"midPerCard": "-2",
|
||||||
"midPerPass": "500.00",
|
"midPerPass": "0",
|
||||||
"midPerHarvest": "800.20",
|
"midPerHarvest": "-3",
|
||||||
"midPerEffect": "是",
|
"midPerEffect": "0",
|
||||||
"midPerQuickPay": "300.00",
|
"midPerQuickPay": "-1",
|
||||||
"midPerEleDdc": "150.00",
|
"midPerEleDdc": "0",
|
||||||
"midPerWaterDdc": "80.00",
|
"midPerWaterDdc": "-1",
|
||||||
"midPerHuashuDdc": "120.00",
|
"midPerHuashuDdc": "0",
|
||||||
"MidPerGasDdc": "90.00",
|
"MidPerGasDdc": "-1",
|
||||||
"midPerCitizencard": "200.00",
|
"midPerCitizencard": "0",
|
||||||
"midPerFinMan": "5000.00",
|
"midPerFinMan": "-4",
|
||||||
"midPerEtc": "180.00",
|
"midPerEtc": "0",
|
||||||
"bpMid": "45",
|
"bpMid": "45",
|
||||||
"totalBpRelevance": "90",
|
"totalBpRelevance": "90",
|
||||||
"applyAmt": "200000.00",
|
"applyAmt": "200000.00",
|
||||||
@@ -47,9 +47,13 @@
|
|||||||
"collThirdParty": "否",
|
"collThirdParty": "否",
|
||||||
"bpCollateral": "0",
|
"bpCollateral": "0",
|
||||||
"greyCust": "否",
|
"greyCust": "否",
|
||||||
|
"blackCust": "否",
|
||||||
"prinOverdue": "否",
|
"prinOverdue": "否",
|
||||||
|
"bpPrinOverdue": "0",
|
||||||
"interestOverdue": "否",
|
"interestOverdue": "否",
|
||||||
|
"bpIinterestOverdue": "0",
|
||||||
"cardOverdue": "否",
|
"cardOverdue": "否",
|
||||||
|
"bpCardOverdue": "0",
|
||||||
"bpGreyOverdue": "98",
|
"bpGreyOverdue": "98",
|
||||||
"totalBpRisk": "95",
|
"totalBpRisk": "95",
|
||||||
"totalBp": "350",
|
"totalBp": "350",
|
||||||
@@ -58,7 +62,8 @@
|
|||||||
"minRateProduct": "5.50",
|
"minRateProduct": "5.50",
|
||||||
"smoothRange": "-0.10",
|
"smoothRange": "-0.10",
|
||||||
"finalCalculateRate": "6.05",
|
"finalCalculateRate": "6.05",
|
||||||
"referenceRate": "5.95"
|
"referenceRate": "5.95",
|
||||||
|
"branchBp": "-8"
|
||||||
},
|
},
|
||||||
"extensionMap": {},
|
"extensionMap": {},
|
||||||
"reasonMessage": "Running successfully",
|
"reasonMessage": "Running successfully",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
<select id="selectWorkflowPageWithRates" resultType="com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowListVO">
|
<select id="selectWorkflowPageWithRates" resultType="com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowListVO">
|
||||||
SELECT
|
SELECT
|
||||||
lpw.serial_num AS serialNum,
|
lpw.serial_num AS serialNum,
|
||||||
|
lpw.dept_id AS deptId,
|
||||||
lpw.cust_isn AS custIsn,
|
lpw.cust_isn AS custIsn,
|
||||||
lpw.cust_name AS custName,
|
lpw.cust_name AS custName,
|
||||||
lpw.cust_type AS custType,
|
lpw.cust_type AS custType,
|
||||||
@@ -49,6 +50,18 @@
|
|||||||
<if test="query != null and query.deptId != null">
|
<if test="query != null and query.deptId != null">
|
||||||
AND lpw.dept_id = #{query.deptId}
|
AND lpw.dept_id = #{query.deptId}
|
||||||
</if>
|
</if>
|
||||||
|
<if test="query != null and query.custType != null and query.custType != ''">
|
||||||
|
AND lpw.cust_type = #{query.custType}
|
||||||
|
</if>
|
||||||
|
<if test="query != null and query.guarType != null and query.guarType != ''">
|
||||||
|
AND lpw.guar_type = #{query.guarType}
|
||||||
|
</if>
|
||||||
|
<if test="query != null and query.beginCreateTime != null">
|
||||||
|
AND lpw.create_time >= #{query.beginCreateTime}
|
||||||
|
</if>
|
||||||
|
<if test="query != null and query.endCreateTime != null">
|
||||||
|
AND lpw.create_time <= #{query.endCreateTime}
|
||||||
|
</if>
|
||||||
</where>
|
</where>
|
||||||
ORDER BY lpw.update_time DESC
|
ORDER BY lpw.update_time DESC
|
||||||
</select>
|
</select>
|
||||||
|
|||||||
@@ -23,5 +23,10 @@ class ModelRetailOutputFieldsTest
|
|||||||
assertTrue(fieldNames.contains("finalCalculateRate"), "缺少字段 finalCalculateRate");
|
assertTrue(fieldNames.contains("finalCalculateRate"), "缺少字段 finalCalculateRate");
|
||||||
assertTrue(fieldNames.contains("referenceRate"), "缺少字段 referenceRate");
|
assertTrue(fieldNames.contains("referenceRate"), "缺少字段 referenceRate");
|
||||||
assertTrue(fieldNames.contains("greyBlackCust"), "缺少字段 greyBlackCust");
|
assertTrue(fieldNames.contains("greyBlackCust"), "缺少字段 greyBlackCust");
|
||||||
|
assertTrue(fieldNames.contains("blackCust"), "缺少字段 blackCust");
|
||||||
|
assertTrue(fieldNames.contains("branchBp"), "缺少字段 branchBp");
|
||||||
|
assertTrue(fieldNames.contains("bpPrinOverdue"), "缺少字段 bpPrinOverdue");
|
||||||
|
assertTrue(fieldNames.contains("bpIinterestOverdue"), "缺少字段 bpIinterestOverdue");
|
||||||
|
assertTrue(fieldNames.contains("bpCardOverdue"), "缺少字段 bpCardOverdue");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ class LoanPricingWorkflowListVOTest
|
|||||||
void shouldExposeCalculateRateAndExecuteRateFields()
|
void shouldExposeCalculateRateAndExecuteRateFields()
|
||||||
{
|
{
|
||||||
LoanPricingWorkflowListVO vo = new LoanPricingWorkflowListVO();
|
LoanPricingWorkflowListVO vo = new LoanPricingWorkflowListVO();
|
||||||
|
vo.setDeptId(100L);
|
||||||
vo.setCustIsn("CUST001");
|
vo.setCustIsn("CUST001");
|
||||||
vo.setCalculateRate("6.15");
|
vo.setCalculateRate("6.15");
|
||||||
vo.setExecuteRate("5.80");
|
vo.setExecuteRate("5.80");
|
||||||
|
|
||||||
|
assertEquals(100L, vo.getDeptId());
|
||||||
assertEquals("CUST001", vo.getCustIsn());
|
assertEquals("CUST001", vo.getCustIsn());
|
||||||
assertEquals("6.15", vo.getCalculateRate());
|
assertEquals("6.15", vo.getCalculateRate());
|
||||||
assertEquals("5.80", vo.getExecuteRate());
|
assertEquals("5.80", vo.getExecuteRate());
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class LoanPricingWorkflowMapperXmlTest
|
|||||||
|
|
||||||
assertTrue(xml.contains("WHEN lpw.cust_type = '个人' THEN mr.final_calculate_rate"));
|
assertTrue(xml.contains("WHEN lpw.cust_type = '个人' THEN mr.final_calculate_rate"));
|
||||||
assertTrue(xml.contains("WHEN lpw.cust_type = '企业' THEN mc.final_calculate_rate"));
|
assertTrue(xml.contains("WHEN lpw.cust_type = '企业' THEN mc.final_calculate_rate"));
|
||||||
|
assertTrue(xml.contains("lpw.dept_id AS deptId"));
|
||||||
assertTrue(xml.contains("lpw.create_by = #{query.dataScopeCreateBy}"));
|
assertTrue(xml.contains("lpw.create_by = #{query.dataScopeCreateBy}"));
|
||||||
assertTrue(xml.contains("lpw.dept_id IN"));
|
assertTrue(xml.contains("lpw.dept_id IN"));
|
||||||
assertTrue(xml.contains("find_in_set(#{query.dataScopeDeptId}, ancestors)"));
|
assertTrue(xml.contains("find_in_set(#{query.dataScopeDeptId}, ancestors)"));
|
||||||
@@ -27,6 +28,10 @@ class LoanPricingWorkflowMapperXmlTest
|
|||||||
assertTrue(xml.contains("lpw.cust_isn LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
assertTrue(xml.contains("lpw.cust_isn LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
||||||
assertTrue(xml.contains("lpw.id_num LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
assertTrue(xml.contains("lpw.id_num LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
||||||
assertTrue(xml.contains("lpw.cust_name LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
assertTrue(xml.contains("lpw.cust_name LIKE CONCAT('%', #{query.custIsn}, '%')"));
|
||||||
|
assertTrue(xml.contains("lpw.cust_type = #{query.custType}"));
|
||||||
|
assertTrue(xml.contains("lpw.guar_type = #{query.guarType}"));
|
||||||
|
assertTrue(xml.contains("lpw.create_time >= #{query.beginCreateTime}"));
|
||||||
|
assertTrue(xml.contains("lpw.create_time <= #{query.endCreateTime}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ import java.util.Objects;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
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.any;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
@@ -44,28 +42,28 @@ class LoanPricingModelServicePersonalParamsTest {
|
|||||||
private LoanPricingModelService loanPricingModelService;
|
private LoanPricingModelService loanPricingModelService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldRemoveLoanPurposeAndKeepLoanTermInPersonalCreateDto() throws NoSuchFieldException {
|
void shouldContainLoanPurposeAndPersonalModelFieldsInCreateDto() throws NoSuchFieldException {
|
||||||
assertThrows(NoSuchFieldException.class,
|
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
|
||||||
() -> PersonalLoanPricingCreateDTO.class.getDeclaredField("loanPurpose"));
|
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("bizProof"));
|
||||||
assertThrows(NoSuchFieldException.class,
|
|
||||||
() -> PersonalLoanPricingCreateDTO.class.getDeclaredField("bizProof"));
|
|
||||||
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanTerm"));
|
assertNotNull(PersonalLoanPricingCreateDTO.class.getDeclaredField("loanTerm"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldNotMapLoanPurposeAndBizProofFromPersonalDto() {
|
void shouldMapLoanPurposeAndBizProofFromPersonalDto() {
|
||||||
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
||||||
dto.setCustIsn("CUST001");
|
dto.setCustIsn("CUST001");
|
||||||
dto.setCustName("张三");
|
dto.setCustName("张三");
|
||||||
dto.setGuarType("信用");
|
dto.setGuarType("信用");
|
||||||
dto.setApplyAmt("100000");
|
dto.setApplyAmt("100000");
|
||||||
|
dto.setLoanPurpose("business");
|
||||||
dto.setBusinessType("新增");
|
dto.setBusinessType("新增");
|
||||||
dto.setLoanTerm("3");
|
dto.setLoanTerm("3");
|
||||||
|
dto.setBizProof("1");
|
||||||
|
|
||||||
LoanPricingWorkflow workflow = LoanPricingConverter.toEntity(dto);
|
LoanPricingWorkflow workflow = LoanPricingConverter.toEntity(dto);
|
||||||
|
|
||||||
assertNull(workflow.getLoanPurpose());
|
assertEquals("business", workflow.getLoanPurpose());
|
||||||
assertNull(workflow.getBizProof());
|
assertEquals("1", workflow.getBizProof());
|
||||||
assertEquals("3", workflow.getLoanTerm());
|
assertEquals("3", workflow.getLoanTerm());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +87,9 @@ class LoanPricingModelServicePersonalParamsTest {
|
|||||||
workflow.setIdNum("110101199001011234");
|
workflow.setIdNum("110101199001011234");
|
||||||
workflow.setGuarType("信用");
|
workflow.setGuarType("信用");
|
||||||
workflow.setApplyAmt("100000");
|
workflow.setApplyAmt("100000");
|
||||||
|
workflow.setLoanPurpose("consumer");
|
||||||
workflow.setLoanTerm("3");
|
workflow.setLoanTerm("3");
|
||||||
|
workflow.setBizProof("true");
|
||||||
workflow.setLoanLoop("false");
|
workflow.setLoanLoop("false");
|
||||||
workflow.setCollThirdParty("true");
|
workflow.setCollThirdParty("true");
|
||||||
workflow.setCollType("一类");
|
workflow.setCollType("一类");
|
||||||
@@ -113,9 +113,27 @@ class LoanPricingModelServicePersonalParamsTest {
|
|||||||
&& Objects.equals("110101199001011234", dto.getIdNum())
|
&& Objects.equals("110101199001011234", dto.getIdNum())
|
||||||
&& Objects.equals("信用", dto.getGuarType())
|
&& Objects.equals("信用", dto.getGuarType())
|
||||||
&& Objects.equals("100000", dto.getApplyAmt())
|
&& Objects.equals("100000", dto.getApplyAmt())
|
||||||
|
&& Objects.equals("消费", dto.getLoanPurpose())
|
||||||
&& Objects.equals("3", dto.getLoanTerm())
|
&& Objects.equals("3", dto.getLoanTerm())
|
||||||
|
&& Objects.equals("1", dto.getBizProof())
|
||||||
&& Objects.equals("0", dto.getLoanLoop())
|
&& Objects.equals("0", dto.getLoanLoop())
|
||||||
&& Objects.equals("1", dto.getCollThirdParty())
|
&& Objects.equals("1", dto.getCollThirdParty())
|
||||||
&& Objects.equals("一类", dto.getCollType())));
|
&& Objects.equals("一类", dto.getCollType())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldConvertBusinessLoanPurposeForPersonalModel() {
|
||||||
|
LoanPricingWorkflow workflow = new LoanPricingWorkflow();
|
||||||
|
workflow.setId(2L);
|
||||||
|
workflow.setCustType("个人");
|
||||||
|
workflow.setLoanPurpose("business");
|
||||||
|
|
||||||
|
when(loanPricingWorkflowMapper.selectById(2L)).thenReturn(workflow);
|
||||||
|
when(modelService.invokePersonalModel(any())).thenReturn(new ModelRetailOutputFields());
|
||||||
|
|
||||||
|
loanPricingModelService.invokeModelAsync(2L);
|
||||||
|
|
||||||
|
verify(modelService).invokePersonalModel(argThat((ModelInvokeDTO dto) ->
|
||||||
|
Objects.equals("经营", dto.getLoanPurpose())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ class LoanPricingModelServiceTest
|
|||||||
assertEquals("张三", context.modelService.personalRequest.getCustName());
|
assertEquals("张三", context.modelService.personalRequest.getCustName());
|
||||||
assertEquals("110101199001011234", context.modelService.personalRequest.getIdNum());
|
assertEquals("110101199001011234", context.modelService.personalRequest.getIdNum());
|
||||||
assertEquals("2.15", context.modelService.personalRequest.getCouponRate());
|
assertEquals("2.15", context.modelService.personalRequest.getCouponRate());
|
||||||
|
assertEquals("1", context.modelService.personalRequest.getBizProof());
|
||||||
assertEquals(1, context.modelService.personalCalls.get());
|
assertEquals(1, context.modelService.personalCalls.get());
|
||||||
assertEquals(0, context.modelService.corporateCalls.get());
|
assertEquals(0, context.modelService.corporateCalls.get());
|
||||||
assertEquals(1, context.retailInsertCount.get());
|
assertEquals(1, context.retailInsertCount.get());
|
||||||
@@ -105,6 +106,7 @@ class LoanPricingModelServiceTest
|
|||||||
workflow.setCustName("张三");
|
workflow.setCustName("张三");
|
||||||
workflow.setIdNum("110101199001011234");
|
workflow.setIdNum("110101199001011234");
|
||||||
workflow.setCouponRate("2.15");
|
workflow.setCouponRate("2.15");
|
||||||
|
workflow.setBizProof("true");
|
||||||
return workflow;
|
return workflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -290,36 +290,67 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAllowPersonalMortgageOneLineAndRejectOldOther()
|
void shouldAllowPersonalMortgageFourthCategoryAndRejectOldFirstLine()
|
||||||
{
|
{
|
||||||
LoanPricingWorkflow allowedWorkflow = validWorkflow();
|
LoanPricingWorkflow allowedWorkflow = validWorkflow();
|
||||||
allowedWorkflow.setCustType("个人");
|
allowedWorkflow.setCustType("个人");
|
||||||
allowedWorkflow.setGuarType("抵押");
|
allowedWorkflow.setGuarType("抵押");
|
||||||
allowedWorkflow.setCollType("一线");
|
allowedWorkflow.setCollType("四类");
|
||||||
|
|
||||||
loanPricingWorkflowService.createLoanPricing(allowedWorkflow);
|
loanPricingWorkflowService.createLoanPricing(allowedWorkflow);
|
||||||
|
|
||||||
LoanPricingWorkflow rejectedWorkflow = validWorkflow();
|
LoanPricingWorkflow rejectedWorkflow = validWorkflow();
|
||||||
rejectedWorkflow.setCustType("个人");
|
rejectedWorkflow.setCustType("个人");
|
||||||
rejectedWorkflow.setGuarType("抵押");
|
rejectedWorkflow.setGuarType("抵押");
|
||||||
rejectedWorkflow.setCollType("其他");
|
rejectedWorkflow.setCollType("一线");
|
||||||
|
|
||||||
ServiceException exception = assertThrows(ServiceException.class,
|
ServiceException exception = assertThrows(ServiceException.class,
|
||||||
() -> loanPricingWorkflowService.createLoanPricing(rejectedWorkflow));
|
() -> loanPricingWorkflowService.createLoanPricing(rejectedWorkflow));
|
||||||
|
|
||||||
assertEquals("个人抵押抵质押类型必须是:一线、一类、二类、三类之一", exception.getMessage());
|
assertEquals("个人抵押抵质押类型必须是:一类、二类、三类、四类之一", exception.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldAllowCorporateMortgagePollutionRightAndPledgeEquity()
|
void shouldAllowCorporateNewMortgageTypesAndRejectOldMortgageTypes()
|
||||||
{
|
{
|
||||||
LoanPricingWorkflow mortgageWorkflow = validWorkflow();
|
LoanPricingWorkflow pollutionRightWorkflow = validWorkflow();
|
||||||
mortgageWorkflow.setCustType("企业");
|
pollutionRightWorkflow.setCustType("企业");
|
||||||
mortgageWorkflow.setGuarType("抵押");
|
pollutionRightWorkflow.setGuarType("抵押");
|
||||||
mortgageWorkflow.setCollType("排污权抵押");
|
pollutionRightWorkflow.setCollType("排污权抵押");
|
||||||
|
|
||||||
loanPricingWorkflowService.createLoanPricing(mortgageWorkflow);
|
loanPricingWorkflowService.createLoanPricing(pollutionRightWorkflow);
|
||||||
|
|
||||||
|
LoanPricingWorkflow otherRealEstateWorkflow = validWorkflow();
|
||||||
|
otherRealEstateWorkflow.setCustType("企业");
|
||||||
|
otherRealEstateWorkflow.setGuarType("抵押");
|
||||||
|
otherRealEstateWorkflow.setCollType("其他不动产抵押");
|
||||||
|
|
||||||
|
loanPricingWorkflowService.createLoanPricing(otherRealEstateWorkflow);
|
||||||
|
|
||||||
|
LoanPricingWorkflow oldFourthCategoryWorkflow = validWorkflow();
|
||||||
|
oldFourthCategoryWorkflow.setCustType("企业");
|
||||||
|
oldFourthCategoryWorkflow.setGuarType("抵押");
|
||||||
|
oldFourthCategoryWorkflow.setCollType("四类");
|
||||||
|
|
||||||
|
ServiceException fourthCategoryException = assertThrows(ServiceException.class,
|
||||||
|
() -> loanPricingWorkflowService.createLoanPricing(oldFourthCategoryWorkflow));
|
||||||
|
|
||||||
|
LoanPricingWorkflow oldOtherRealEstateWorkflow = validWorkflow();
|
||||||
|
oldOtherRealEstateWorkflow.setCustType("企业");
|
||||||
|
oldOtherRealEstateWorkflow.setGuarType("抵押");
|
||||||
|
oldOtherRealEstateWorkflow.setCollType("设备等其他不动产抵押");
|
||||||
|
|
||||||
|
ServiceException otherRealEstateException = assertThrows(ServiceException.class,
|
||||||
|
() -> loanPricingWorkflowService.createLoanPricing(oldOtherRealEstateWorkflow));
|
||||||
|
|
||||||
|
String expectedMessage = "企业抵押抵质押类型必须是:一类、二类、三类、排污权抵押、其他不动产抵押之一";
|
||||||
|
assertEquals(expectedMessage, fourthCategoryException.getMessage());
|
||||||
|
assertEquals(expectedMessage, otherRealEstateException.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldKeepCorporatePledgeTypesUnchanged()
|
||||||
|
{
|
||||||
LoanPricingWorkflow pledgeWorkflow = validWorkflow();
|
LoanPricingWorkflow pledgeWorkflow = validWorkflow();
|
||||||
pledgeWorkflow.setCustType("企业");
|
pledgeWorkflow.setCustType("企业");
|
||||||
pledgeWorkflow.setGuarType("质押");
|
pledgeWorkflow.setGuarType("质押");
|
||||||
@@ -339,7 +370,7 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldCreatePersonalWorkflowWithCouponRateAndWithoutRemovedFields()
|
void shouldCreatePersonalWorkflowWithCouponRateAndBizProof()
|
||||||
{
|
{
|
||||||
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
||||||
dto.setCustIsn("CUST001");
|
dto.setCustIsn("CUST001");
|
||||||
@@ -349,6 +380,7 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
dto.setLoanTerm("3");
|
dto.setLoanTerm("3");
|
||||||
dto.setCollType("存单质押");
|
dto.setCollType("存单质押");
|
||||||
dto.setCouponRate("2.15");
|
dto.setCouponRate("2.15");
|
||||||
|
dto.setBizProof("1");
|
||||||
|
|
||||||
loanPricingWorkflowService.createPersonalLoanPricing(dto);
|
loanPricingWorkflowService.createPersonalLoanPricing(dto);
|
||||||
|
|
||||||
@@ -356,7 +388,7 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
Objects.equals("个人", entity.getCustType())
|
Objects.equals("个人", entity.getCustType())
|
||||||
&& Objects.equals("2.15", entity.getCouponRate())
|
&& Objects.equals("2.15", entity.getCouponRate())
|
||||||
&& Objects.isNull(entity.getLoanPurpose())
|
&& Objects.isNull(entity.getLoanPurpose())
|
||||||
&& Objects.isNull(entity.getBizProof())));
|
&& Objects.equals("1", entity.getBizProof())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -381,6 +413,48 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
&& Objects.equals("2.35", entity.getCouponRate())));
|
&& Objects.equals("2.35", entity.getCouponRate())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCreatePersonalWorkflowWithMortgageSourceFields()
|
||||||
|
{
|
||||||
|
PersonalLoanPricingCreateDTO dto = new PersonalLoanPricingCreateDTO();
|
||||||
|
dto.setCustIsn("CUST001");
|
||||||
|
dto.setGuarType("抵押");
|
||||||
|
dto.setApplyAmt("100000");
|
||||||
|
dto.setBusinessType("新增");
|
||||||
|
dto.setLoanTerm("3");
|
||||||
|
dto.setCollateralNature("普通住宅、土地、厂房");
|
||||||
|
dto.setIsNineArea("是");
|
||||||
|
dto.setCollType("一类");
|
||||||
|
|
||||||
|
loanPricingWorkflowService.createPersonalLoanPricing(dto);
|
||||||
|
|
||||||
|
verify(loanPricingWorkflowMapper).insert(argThat((LoanPricingWorkflow entity) ->
|
||||||
|
Objects.equals("普通住宅、土地、厂房", entity.getCollateralNature())
|
||||||
|
&& Objects.equals("是", entity.getIsNineArea())
|
||||||
|
&& Objects.equals("一类", entity.getCollType())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldCreateCorporateWorkflowWithMortgageSourceFields()
|
||||||
|
{
|
||||||
|
CorporateLoanPricingCreateDTO dto = new CorporateLoanPricingCreateDTO();
|
||||||
|
dto.setCustIsn("CORP001");
|
||||||
|
dto.setGuarType("抵押");
|
||||||
|
dto.setApplyAmt("1000000");
|
||||||
|
dto.setBusinessType("新增");
|
||||||
|
dto.setLoanTerm("5");
|
||||||
|
dto.setCollateralNature("商业性质不动产");
|
||||||
|
dto.setIsNineArea("否");
|
||||||
|
dto.setCollType("三类");
|
||||||
|
|
||||||
|
loanPricingWorkflowService.createCorporateLoanPricing(dto);
|
||||||
|
|
||||||
|
verify(loanPricingWorkflowMapper).insert(argThat((LoanPricingWorkflow entity) ->
|
||||||
|
Objects.equals("商业性质不动产", entity.getCollateralNature())
|
||||||
|
&& Objects.equals("否", entity.getIsNineArea())
|
||||||
|
&& Objects.equals("三类", entity.getCollType())));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldReturnEditableWorkflowWithPlainSensitiveFieldsForCreator()
|
void shouldReturnEditableWorkflowWithPlainSensitiveFieldsForCreator()
|
||||||
{
|
{
|
||||||
@@ -420,11 +494,16 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
dto.setCustName("张三");
|
dto.setCustName("张三");
|
||||||
dto.setIdType("身份证");
|
dto.setIdType("身份证");
|
||||||
dto.setIdNum("110101199001019999");
|
dto.setIdNum("110101199001019999");
|
||||||
dto.setGuarType("信用");
|
dto.setGuarType("抵押");
|
||||||
dto.setApplyAmt("200000");
|
dto.setApplyAmt("200000");
|
||||||
|
dto.setLoanPurpose("business");
|
||||||
dto.setBusinessType("新增");
|
dto.setBusinessType("新增");
|
||||||
dto.setLoanTerm("3");
|
dto.setLoanTerm("3");
|
||||||
dto.setLoanLoop("1");
|
dto.setLoanLoop("1");
|
||||||
|
dto.setBizProof("1");
|
||||||
|
dto.setCollateralNature("普通住宅、土地、厂房");
|
||||||
|
dto.setIsNineArea("是");
|
||||||
|
dto.setCollType("一类");
|
||||||
|
|
||||||
loanPricingWorkflowService.updatePersonalLoanPricing("P20260525001", dto);
|
loanPricingWorkflowService.updatePersonalLoanPricing("P20260525001", dto);
|
||||||
|
|
||||||
@@ -432,10 +511,18 @@ class LoanPricingWorkflowServiceImplTest
|
|||||||
verify(loanPricingWorkflowMapper).update(any(), updateWrapperCaptor.capture());
|
verify(loanPricingWorkflowMapper).update(any(), updateWrapperCaptor.capture());
|
||||||
String sqlSet = updateWrapperCaptor.getValue().getSqlSet();
|
String sqlSet = updateWrapperCaptor.getValue().getSqlSet();
|
||||||
assertTrue(sqlSet.contains("apply_amt"));
|
assertTrue(sqlSet.contains("apply_amt"));
|
||||||
|
assertTrue(sqlSet.contains("loan_purpose"));
|
||||||
assertTrue(sqlSet.contains("cust_name"));
|
assertTrue(sqlSet.contains("cust_name"));
|
||||||
assertTrue(sqlSet.contains("id_num"));
|
assertTrue(sqlSet.contains("id_num"));
|
||||||
|
assertTrue(sqlSet.contains("biz_proof"));
|
||||||
|
assertTrue(sqlSet.contains("collateral_nature"));
|
||||||
|
assertTrue(sqlSet.contains("is_nine_area"));
|
||||||
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("张三"));
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("张三"));
|
||||||
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("110101199001019999"));
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("110101199001019999"));
|
||||||
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("普通住宅、土地、厂房"));
|
||||||
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("business"));
|
||||||
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("是"));
|
||||||
|
assertTrue(updateWrapperCaptor.getValue().getParamNameValuePairs().containsValue("1"));
|
||||||
verify(sensitiveFieldCryptoService, never()).encrypt(any());
|
verify(sensitiveFieldCryptoService, never()).encrypt(any());
|
||||||
verify(loanPricingModelService).reinvokeModelAndOverwrite(101L);
|
verify(loanPricingModelService).reinvokeModelAndOverwrite(101L);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,33 @@
|
|||||||
<!-- 抵质押信息 -->
|
<!-- 抵质押信息 -->
|
||||||
<el-divider v-if="isCollateralGuarantee" content-position="left">抵质押信息</el-divider>
|
<el-divider v-if="isCollateralGuarantee" content-position="left">抵质押信息</el-divider>
|
||||||
<el-row v-if="isCollateralGuarantee">
|
<el-row v-if="isCollateralGuarantee">
|
||||||
<el-col :span="12">
|
<template v-if="isMortgage">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="抵押物性质" prop="collateralNature">
|
||||||
|
<el-select v-model="form.collateralNature" placeholder="请选择抵押物性质" style="width: 100%">
|
||||||
|
<el-option v-for="item in collateralNatureOptions" :key="item" :label="item" :value="item"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否属于九地" prop="isNineArea">
|
||||||
|
<div class="nine-area-control">
|
||||||
|
<el-select
|
||||||
|
v-model="form.isNineArea"
|
||||||
|
:disabled="!requiresNineArea"
|
||||||
|
:placeholder="requiresNineArea ? '请选择是否属于九地' : '无需选择'"
|
||||||
|
>
|
||||||
|
<el-option label="是" value="是"/>
|
||||||
|
<el-option label="否" value="否"/>
|
||||||
|
</el-select>
|
||||||
|
<el-tooltip content="九地是指绍兴、杭州、宁波、上海、北京、广州、深圳、南京、苏州" placement="top">
|
||||||
|
<i class="el-icon-question nine-area-help" tabindex="0" aria-label="查看九地说明"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
<el-col :span="12" v-if="isPledge">
|
||||||
<el-form-item label="抵质押类型" prop="collType">
|
<el-form-item label="抵质押类型" prop="collType">
|
||||||
<el-select v-model="form.collType" placeholder="请选择抵质押类型" style="width: 100%">
|
<el-select v-model="form.collType" placeholder="请选择抵质押类型" style="width: 100%">
|
||||||
<el-option v-for="item in collateralTypeOptions" :key="item" :label="item" :value="item"/>
|
<el-option v-for="item in collateralTypeOptions" :key="item" :label="item" :value="item"/>
|
||||||
@@ -181,6 +207,30 @@ export default {
|
|||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateCollateralType = (rule, value, callback) => {
|
||||||
|
if (this.isPledge && !value) {
|
||||||
|
callback(new Error('请选择抵质押类型'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateCollateralNature = (rule, value, callback) => {
|
||||||
|
if (this.isMortgage && !value) {
|
||||||
|
callback(new Error('请选择抵押物性质'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateNineArea = (rule, value, callback) => {
|
||||||
|
if (this.requiresNineArea && !value) {
|
||||||
|
callback(new Error('请选择是否属于九地'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
// 贷款期限验证
|
// 贷款期限验证
|
||||||
const validateLoanTerm = (rule, value, callback) => {
|
const validateLoanTerm = (rule, value, callback) => {
|
||||||
if (!value && value !== 0) {
|
if (!value && value !== 0) {
|
||||||
@@ -221,6 +271,8 @@ export default {
|
|||||||
isGreenLoan: false,
|
isGreenLoan: false,
|
||||||
isTradeBuildEnt: false,
|
isTradeBuildEnt: false,
|
||||||
collType: undefined,
|
collType: undefined,
|
||||||
|
collateralNature: undefined,
|
||||||
|
isNineArea: undefined,
|
||||||
collThirdParty: false,
|
collThirdParty: false,
|
||||||
couponRate: undefined
|
couponRate: undefined
|
||||||
},
|
},
|
||||||
@@ -255,7 +307,13 @@ export default {
|
|||||||
{required: true, message: "请选择历史贷款合同", trigger: "change"}
|
{required: true, message: "请选择历史贷款合同", trigger: "change"}
|
||||||
],
|
],
|
||||||
collType: [
|
collType: [
|
||||||
{required: true, message: "请选择抵质押类型", trigger: "change"}
|
{validator: validateCollateralType, trigger: "change"}
|
||||||
|
],
|
||||||
|
collateralNature: [
|
||||||
|
{validator: validateCollateralNature, trigger: "change"}
|
||||||
|
],
|
||||||
|
isNineArea: [
|
||||||
|
{validator: validateNineArea, trigger: "change"}
|
||||||
],
|
],
|
||||||
couponRate: [
|
couponRate: [
|
||||||
{validator: validateCouponRate, trigger: "blur"}
|
{validator: validateCouponRate, trigger: "blur"}
|
||||||
@@ -275,6 +333,15 @@ export default {
|
|||||||
isCollateralGuarantee() {
|
isCollateralGuarantee() {
|
||||||
return this.form.guarType === '抵押' || this.form.guarType === '质押'
|
return this.form.guarType === '抵押' || this.form.guarType === '质押'
|
||||||
},
|
},
|
||||||
|
isMortgage() {
|
||||||
|
return this.form.guarType === '抵押'
|
||||||
|
},
|
||||||
|
isPledge() {
|
||||||
|
return this.form.guarType === '质押'
|
||||||
|
},
|
||||||
|
requiresNineArea() {
|
||||||
|
return this.isMortgage && ['普通住宅、土地、厂房', '商业性质不动产'].includes(this.form.collateralNature)
|
||||||
|
},
|
||||||
isStockTransfer() {
|
isStockTransfer() {
|
||||||
return this.form.businessType === '存量转贷'
|
return this.form.businessType === '存量转贷'
|
||||||
},
|
},
|
||||||
@@ -288,13 +355,13 @@ export default {
|
|||||||
return this.isEdit ? '编辑企业利率定价流程' : '新增企业利率定价流程'
|
return this.isEdit ? '编辑企业利率定价流程' : '新增企业利率定价流程'
|
||||||
},
|
},
|
||||||
collateralTypeOptions() {
|
collateralTypeOptions() {
|
||||||
if (this.form.guarType === '抵押') {
|
if (this.isPledge) {
|
||||||
return ['一类', '二类', '三类', '四类', '排污权抵押', '设备等其他不动产抵押']
|
|
||||||
}
|
|
||||||
if (this.form.guarType === '质押') {
|
|
||||||
return ['存单质押', '股权质押', '其他质押']
|
return ['存单质押', '股权质押', '其他质押']
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
|
},
|
||||||
|
collateralNatureOptions() {
|
||||||
|
return ['普通住宅、土地、厂房', '商业性质不动产', '排污权', '其他不动产']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -316,6 +383,12 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.resetCouponRateIfNotCertificatePledge()
|
this.resetCouponRateIfNotCertificatePledge()
|
||||||
|
},
|
||||||
|
'form.collateralNature'(val, oldVal) {
|
||||||
|
if (this.resettingForm || val === oldVal) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.handleCollateralNatureChange()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -353,7 +426,9 @@ export default {
|
|||||||
resCover: this.isOne(this.editData.resCover),
|
resCover: this.isOne(this.editData.resCover),
|
||||||
isGreenLoan: this.isOne(this.editData.isGreenLoan),
|
isGreenLoan: this.isOne(this.editData.isGreenLoan),
|
||||||
isTradeBuildEnt: this.isOne(this.editData.isTradeBuildEnt),
|
isTradeBuildEnt: this.isOne(this.editData.isTradeBuildEnt),
|
||||||
collType: this.editData.collType,
|
collType: this.editData.guarType === '质押' ? this.editData.collType : undefined,
|
||||||
|
collateralNature: this.editData.collateralNature,
|
||||||
|
isNineArea: this.editData.isNineArea,
|
||||||
collThirdParty: this.isOne(this.editData.collThirdParty),
|
collThirdParty: this.isOne(this.editData.collThirdParty),
|
||||||
couponRate: this.editData.couponRate
|
couponRate: this.editData.couponRate
|
||||||
}
|
}
|
||||||
@@ -374,6 +449,8 @@ export default {
|
|||||||
isGreenLoan: false,
|
isGreenLoan: false,
|
||||||
isTradeBuildEnt: false,
|
isTradeBuildEnt: false,
|
||||||
collType: undefined,
|
collType: undefined,
|
||||||
|
collateralNature: undefined,
|
||||||
|
isNineArea: undefined,
|
||||||
collThirdParty: false,
|
collThirdParty: false,
|
||||||
couponRate: undefined
|
couponRate: undefined
|
||||||
}
|
}
|
||||||
@@ -393,14 +470,38 @@ export default {
|
|||||||
/** 清空抵质押字段 */
|
/** 清空抵质押字段 */
|
||||||
resetCollateralFields() {
|
resetCollateralFields() {
|
||||||
this.form.collType = undefined
|
this.form.collType = undefined
|
||||||
|
this.form.collateralNature = undefined
|
||||||
|
this.form.isNineArea = undefined
|
||||||
this.form.collThirdParty = false
|
this.form.collThirdParty = false
|
||||||
this.resetCouponRateIfNotCertificatePledge()
|
this.resetCouponRateIfNotCertificatePledge()
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.form) {
|
if (this.$refs.form) {
|
||||||
this.$refs.form.clearValidate(['collType', 'collThirdParty', 'couponRate'])
|
this.$refs.form.clearValidate(['collType', 'collateralNature', 'isNineArea', 'collThirdParty', 'couponRate'])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleCollateralNatureChange() {
|
||||||
|
this.form.isNineArea = undefined
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.form) {
|
||||||
|
this.$refs.form.clearValidate(['isNineArea'])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
resolveMortgageCollateralType() {
|
||||||
|
if (this.form.collateralNature === '普通住宅、土地、厂房') {
|
||||||
|
return this.form.isNineArea === '是' ? '一类' : '二类'
|
||||||
|
}
|
||||||
|
if (this.form.collateralNature === '商业性质不动产') {
|
||||||
|
return this.form.isNineArea === '是' ? '二类' : '三类'
|
||||||
|
}
|
||||||
|
if (this.form.collateralNature === '排污权') {
|
||||||
|
return '排污权抵押'
|
||||||
|
}
|
||||||
|
if (this.form.collateralNature === '其他不动产') {
|
||||||
|
return '其他不动产抵押'
|
||||||
|
}
|
||||||
|
},
|
||||||
resetCouponRateIfNotCertificatePledge() {
|
resetCouponRateIfNotCertificatePledge() {
|
||||||
if (!this.isCertificatePledge) {
|
if (!this.isCertificatePledge) {
|
||||||
this.form.couponRate = undefined
|
this.form.couponRate = undefined
|
||||||
@@ -472,6 +573,12 @@ export default {
|
|||||||
isGreenLoan: this.form.isGreenLoan ? '1' : '0',
|
isGreenLoan: this.form.isGreenLoan ? '1' : '0',
|
||||||
isTradeBuildEnt: this.form.isTradeBuildEnt ? '1' : '0'
|
isTradeBuildEnt: this.form.isTradeBuildEnt ? '1' : '0'
|
||||||
}
|
}
|
||||||
|
if (this.isMortgage) {
|
||||||
|
data.collType = this.resolveMortgageCollateralType()
|
||||||
|
} else {
|
||||||
|
delete data.collateralNature
|
||||||
|
delete data.isNineArea
|
||||||
|
}
|
||||||
if (this.isCollateralGuarantee) {
|
if (this.isCollateralGuarantee) {
|
||||||
data.collThirdParty = this.form.collThirdParty ? '1' : '0'
|
data.collThirdParty = this.form.collThirdParty ? '1' : '0'
|
||||||
} else {
|
} else {
|
||||||
@@ -512,6 +619,24 @@ export default {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nine-area-control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nine-area-control .el-select {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nine-area-help {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: #909399;
|
||||||
|
cursor: help;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.workflow-create-form .el-col {
|
.workflow-create-form .el-col {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
|
|||||||
@@ -13,14 +13,10 @@
|
|||||||
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="客户类型">{{ detailData.custType }}</el-descriptions-item>
|
<el-descriptions-item label="客户类型">{{ detailData.custType }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
||||||
<el-descriptions-item label="基准利率">
|
<el-descriptions-item label="期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
||||||
<span class="rate-value">{{ getBaseLoanRate() }}</span> %
|
<el-descriptions-item label="担保方式">{{ detailData.guarType || '-' }}</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="产品最低利率下限">
|
||||||
<el-descriptions-item label="浮动BP">
|
<span class="rate-value">{{ formatRate(corpOutput && corpOutput.minRateProduct) }}</span> %
|
||||||
<span class="total-bp-value">{{ getTotalBp() }}</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="最终测算利率">
|
|
||||||
<span class="calculate-rate">{{ getCalculateRate() }}</span> %
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="执行利率">
|
<el-descriptions-item label="执行利率">
|
||||||
<div class="execute-rate-input-wrapper">
|
<div class="execute-rate-input-wrapper">
|
||||||
@@ -46,13 +42,6 @@
|
|||||||
|
|
||||||
<!-- 右侧面板 -->
|
<!-- 右侧面板 -->
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<!-- 模型输出卡片 -->
|
|
||||||
<ModelOutputDisplay
|
|
||||||
:cust-type="detailData.custType"
|
|
||||||
:retail-output="null"
|
|
||||||
:corp-output="corpOutput"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 流程详情卡片 -->
|
<!-- 流程详情卡片 -->
|
||||||
<el-card class="detail-card">
|
<el-card class="detail-card">
|
||||||
<div slot="header" class="card-header">
|
<div slot="header" class="card-header">
|
||||||
@@ -64,11 +53,10 @@
|
|||||||
<h4 class="section-title">基本信息</h4>
|
<h4 class="section-title">基本信息</h4>
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="机构编码">{{ detailData.orgCode }}</el-descriptions-item>
|
<el-descriptions-item label="机构编码">{{ detailData.orgCode }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="运行模式">{{ detailData.runType }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户内码">{{ detailData.custIsn }}</el-descriptions-item>
|
<el-descriptions-item label="客户内码">{{ detailData.custIsn }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="证件类型">{{ detailData.idType }}</el-descriptions-item>
|
<el-descriptions-item label="证件类型">{{ detailData.idType }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="证件号码">{{ detailData.idNum }}</el-descriptions-item>
|
<el-descriptions-item label="证件号码">{{ detailData.idNum }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="贷款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="创建时间">{{ detailData.createTime }}</el-descriptions-item>
|
<el-descriptions-item label="创建时间">{{ detailData.createTime }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="创建者">{{ detailData.createBy }}</el-descriptions-item>
|
<el-descriptions-item label="创建者">{{ detailData.createBy }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
@@ -81,10 +69,17 @@
|
|||||||
<el-descriptions-item label="担保方式">{{ detailData.guarType }}</el-descriptions-item>
|
<el-descriptions-item label="担保方式">{{ detailData.guarType }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
||||||
<el-descriptions-item label="业务种类">{{ detailData.businessType || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="业务种类">{{ detailData.businessType || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="贷款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="历史贷款利率">{{ formatRate(detailData.loanRateHistory) }}</el-descriptions-item>
|
<el-descriptions-item label="历史贷款利率">{{ formatRate(detailData.loanRateHistory) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="余值覆盖">{{ formatBoolean(detailData.resCover) }}</el-descriptions-item>
|
<el-descriptions-item label="余值覆盖">{{ formatBoolean(detailData.resCover) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="绿色贷款">{{ formatBoolean(detailData.isGreenLoan) }}</el-descriptions-item>
|
<el-descriptions-item label="绿色贷款">{{ formatBoolean(detailData.isGreenLoan) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="贸易和建筑业企业">{{ formatBoolean(detailData.isTradeBuildEnt) }}</el-descriptions-item>
|
<el-descriptions-item label="贸易和建筑业企业">{{ formatBoolean(detailData.isTradeBuildEnt) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="detailData.guarType === '抵押'" label="抵押物性质">
|
||||||
|
{{ detailData.collateralNature || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="detailData.guarType === '抵押'" label="是否属于九地">
|
||||||
|
{{ detailData.isNineArea || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="抵质押类型">{{ detailData.collType || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="抵质押类型">{{ detailData.collType || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="抵质押物是否三方所有">{{
|
<el-descriptions-item label="抵质押物是否三方所有">{{
|
||||||
formatBoolean(detailData.collThirdParty)
|
formatBoolean(detailData.collThirdParty)
|
||||||
@@ -94,6 +89,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 模型输出卡片 -->
|
||||||
|
<ModelOutputDisplay
|
||||||
|
:cust-type="detailData.custType"
|
||||||
|
:guar-type="detailData.guarType"
|
||||||
|
:retail-output="null"
|
||||||
|
:corp-output="corpOutput"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 议价池卡片 -->
|
<!-- 议价池卡片 -->
|
||||||
<BargainingPoolDisplay
|
<BargainingPoolDisplay
|
||||||
v-if="bargainingPool"
|
v-if="bargainingPool"
|
||||||
@@ -155,18 +158,6 @@ export default {
|
|||||||
if (value === 'false' || value === false || value === '0' || value === 0) return '否'
|
if (value === 'false' || value === false || value === '0' || value === 0) return '否'
|
||||||
return value || '-'
|
return value || '-'
|
||||||
},
|
},
|
||||||
/** 获取基准利率 */
|
|
||||||
getBaseLoanRate() {
|
|
||||||
return this.formatRate(this.corpOutput?.baseLoanRate)
|
|
||||||
},
|
|
||||||
/** 获取浮动BP */
|
|
||||||
getTotalBp() {
|
|
||||||
return this.corpOutput?.totalBp || '-'
|
|
||||||
},
|
|
||||||
/** 获取最终测算利率 */
|
|
||||||
getCalculateRate() {
|
|
||||||
return this.formatRate(this.corpOutput?.finalCalculateRate)
|
|
||||||
},
|
|
||||||
/** 设定执行利率 */
|
/** 设定执行利率 */
|
||||||
handleSetExecuteRate() {
|
handleSetExecuteRate() {
|
||||||
const value = this.executeRateInput
|
const value = this.executeRateInput
|
||||||
@@ -248,16 +239,6 @@ export default {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-bp-value {
|
|
||||||
color: #e6a23c;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calculate-rate {
|
|
||||||
color: #f56c6c;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
:close-on-click-modal="false" @close="handleClose">
|
:close-on-click-modal="false" @close="handleClose">
|
||||||
<el-form :model="queryForm" inline size="small">
|
<el-form :model="queryForm" inline size="small">
|
||||||
<el-form-item label="客户号">
|
<el-form-item label="客户号">
|
||||||
<el-input v-model="queryForm.custId" placeholder="请输入客户号" clearable @keyup.enter.native="handleQuery"/>
|
<el-input v-model="queryForm.custId" placeholder="请输入客户号" clearable
|
||||||
|
@keydown.enter.native.prevent="handleQuery"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" :loading="loading" @click="handleQuery">查询</el-button>
|
<el-button type="primary" icon="el-icon-search" :loading="loading" @click="handleQuery">查询</el-button>
|
||||||
|
|||||||
@@ -6,203 +6,176 @@
|
|||||||
<div class="output-sections">
|
<div class="output-sections">
|
||||||
<!-- 个人客户模型输出 -->
|
<!-- 个人客户模型输出 -->
|
||||||
<template v-if="custType === '个人' && retailOutput">
|
<template v-if="custType === '个人' && retailOutput">
|
||||||
<div class="output-section">
|
|
||||||
<h4 class="section-title">基本信息</h4>
|
|
||||||
<el-descriptions :column="2" border size="small">
|
|
||||||
<el-descriptions-item label="客户内码">{{ retailOutput.custIsn || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户名称">{{ retailOutput.custName || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="证件类型">{{ retailOutput.idType || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="证件号码">{{ retailOutput.idNum || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="基准利率"><span class="rate-value">{{ formatRate(retailOutput.baseLoanRate) }}</span> %</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="灰黑名单客户">{{ formatOutputValue(retailOutput.greyBlackCust) }}</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">测算结果</h4>
|
<h4 class="section-title">测算结果</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<el-descriptions :column="3" border size="small">
|
||||||
|
<el-descriptions-item label="基准利率"><span class="rate-value">{{ formatRate(retailOutput.baseLoanRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="浮动BP"><span class="total-bp-value">{{ retailOutput.totalBp || '-' }}</span></el-descriptions-item>
|
<el-descriptions-item label="浮动BP"><span class="total-bp-value">{{ retailOutput.totalBp || '-' }}</span></el-descriptions-item>
|
||||||
<el-descriptions-item label="测算利率"><span class="calculate-rate">{{ formatRate(retailOutput.calculateRate) }}</span> %</el-descriptions-item>
|
<el-descriptions-item label="模型测算利率"><span class="calculate-rate">{{ formatRate(retailOutput.calculateRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="历史利率">{{ formatRate(retailOutput.loanRateHistory) }}</el-descriptions-item>
|
<el-descriptions-item label="历史利率">{{ formatRate(retailOutput.loanRateHistory) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="产品最低利率下限">{{ formatRate(retailOutput.minRateProduct) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="平滑幅度">{{ formatRate(retailOutput.smoothRange) }}</el-descriptions-item>
|
<el-descriptions-item label="平滑幅度">{{ formatRate(retailOutput.smoothRange) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="平滑利率"><span class="calculate-rate">{{ formatRate(retailOutput.finalCalculateRate) }}</span> %</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="行社下调BP">{{ formatOutputValue(retailOutput.branchBp) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="参考利率"><span class="calculate-rate">{{ formatRate(retailOutput.referenceRate) }}</span> %</el-descriptions-item>
|
<el-descriptions-item label="参考利率"><span class="calculate-rate">{{ formatRate(retailOutput.referenceRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="最终测算利率"><span class="calculate-rate">{{ formatRate(retailOutput.finalCalculateRate) }}</span> %</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">忠诚度分析</h4>
|
<h4 class="section-title">忠诚度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="我行首贷客户">{{ formatBoolean(retailOutput.isFirstLoan) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="用信天数">{{ retailOutput.faithDay || '-' }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="客户年龄">{{ retailOutput.custAge || '-' }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="BP_首贷"><span class="bp-value">{{ retailOutput.bpFirstLoan || '-' }}</span></el-descriptions-item>
|
<tr v-for="(row, index) in retailLoyaltyRows" :key="`retail-loyalty-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="BP_贷龄"><span class="bp-value">{{ retailOutput.bpAgeLoan || '-' }}</span></el-descriptions-item>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
<el-descriptions-item label="BP_年龄"><span class="bp-value">{{ retailOutput.bpAge || '-' }}</span></el-descriptions-item>
|
<td><span :class="row.total ? 'total-bp-value' : 'bp-value'">{{ row.bpLabel }}:{{ row.bpValue }}</span></td>
|
||||||
<el-descriptions-item label="TOTAL_BP_忠诚度" :span="2"><span class="total-bp-value">{{ retailOutput.totalBpLoyalty || '-' }}</span></el-descriptions-item>
|
</tr>
|
||||||
</el-descriptions>
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">贡献度分析</h4>
|
<h4 class="section-title">贡献度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="存款年日均">{{ retailOutput.balanceAvg || '-' }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="贷款年日均">{{ retailOutput.loanAvg || '-' }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="派生率">{{ formatRate(retailOutput.derivationRate) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="TOTAL_BP_贡献度"><span class="total-bp-value">{{ retailOutput.totalBpContribution || '-' }}</span></el-descriptions-item>
|
<tr v-for="(row, index) in retailContributionRows" :key="`retail-contribution-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
</el-descriptions>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
|
<td>
|
||||||
|
<span v-if="row.bpLabel" :class="row.total ? 'total-bp-value' : 'bp-value'">
|
||||||
|
{{ row.bpLabel }}:{{ row.bpValue }}
|
||||||
|
<el-tooltip v-if="row.bpTooltip" :content="row.bpTooltip" placement="top">
|
||||||
|
<i class="el-icon-question analysis-help" tabindex="0" :aria-label="row.bpTooltipAriaLabel"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">关联度分析</h4>
|
<h4 class="section-title">关联度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="中间业务_个人_信用卡">{{ formatBoolean(retailOutput.midPerCard) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="中间业务_个人_一码通">{{ formatBoolean(retailOutput.midPerPass) }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="中间业务_个人_丰收互联">{{ formatBoolean(retailOutput.midPerHarvest) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="中间业务_个人_有效客户">{{ formatBoolean(retailOutput.midPerEffect) }}</el-descriptions-item>
|
<tr v-for="(row, index) in retailRelevanceRows" :key="`retail-relevance-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="中间业务_个人_快捷支付">{{ formatBoolean(retailOutput.midPerQuickPay) }}</el-descriptions-item>
|
<td>
|
||||||
<el-descriptions-item label="中间业务_个人_电费代扣">{{ formatBoolean(retailOutput.midPerEleDdc) }}</el-descriptions-item>
|
<span v-if="row.summary">汇总</span>
|
||||||
<el-descriptions-item label="中间业务_个人_水费代扣">{{ formatBoolean(retailOutput.midPerWaterDdc) }}</el-descriptions-item>
|
<div v-else v-for="item in row.results" :key="item.label" class="result-item">
|
||||||
<el-descriptions-item label="中间业务_个人_华数费代扣">{{ formatBoolean(retailOutput.midPerHuashuDdc) }}</el-descriptions-item>
|
<span class="result-label">{{ item.label }}</span>
|
||||||
<el-descriptions-item label="中间业务_个人_煤气费代扣">{{ formatBoolean(retailOutput.MidPerGasDdc) }}</el-descriptions-item>
|
<span v-if="item.showValue !== false" class="result-value">{{ item.value }}</span>
|
||||||
<el-descriptions-item label="中间业务_个人_市民卡">{{ formatBoolean(retailOutput.midPerCitizencard) }}</el-descriptions-item>
|
</div>
|
||||||
<el-descriptions-item label="中间业务_个人_理财业务">{{ formatBoolean(retailOutput.midPerFinMan) }}</el-descriptions-item>
|
</td>
|
||||||
<el-descriptions-item label="中间业务_个人_etc">{{ formatBoolean(retailOutput.midPerEtc) }}</el-descriptions-item>
|
<td>
|
||||||
<el-descriptions-item label="BP_中间业务"><span class="bp-value">{{ retailOutput.bpMid || '-' }}</span></el-descriptions-item>
|
<span :class="row.total ? 'total-bp-value' : 'bp-value'">
|
||||||
<el-descriptions-item label="TOTAL_BP_关联度"><span class="total-bp-value">{{ retailOutput.totalBpRelevance || '-' }}</span></el-descriptions-item>
|
<template v-if="row.bpLabel">
|
||||||
</el-descriptions>
|
{{ row.bpLabel }}:
|
||||||
</div>
|
</template>{{ row.bpValue }}
|
||||||
|
<el-tooltip v-if="row.bpTooltip" :content="row.bpTooltip" placement="top">
|
||||||
<div class="output-section">
|
<i class="el-icon-question analysis-help" tabindex="0" :aria-label="row.bpTooltipAriaLabel"></i>
|
||||||
<h4 class="section-title">贷款特征</h4>
|
</el-tooltip>
|
||||||
<el-descriptions :column="2" border size="small">
|
</span>
|
||||||
<el-descriptions-item label="申请金额">{{ retailOutput.applyAmt || '-' }}</el-descriptions-item>
|
</td>
|
||||||
<el-descriptions-item label="BP_贷款额度"><span class="bp-value">{{ retailOutput.bpLoanAmount || '-' }}</span></el-descriptions-item>
|
</tr>
|
||||||
<el-descriptions-item label="贷款用途">{{ formatLoanPurpose(retailOutput.loanPurpose) }}</el-descriptions-item>
|
</tbody>
|
||||||
<el-descriptions-item label="是否有经营佐证">{{ formatBoolean(retailOutput.bizProof) }}</el-descriptions-item>
|
</table>
|
||||||
<el-descriptions-item label="BP_贷款用途"><span class="bp-value">{{ retailOutput.bpLoanUse || '-' }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="循环功能">{{ formatBoolean(retailOutput.loanLoop) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_循环功能"><span class="bp-value">{{ retailOutput.bpLoanLoop || '-' }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="抵质押类型">{{ retailOutput.collType || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="抵质押物三方所有">{{ formatBoolean(retailOutput.collThirdParty) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_抵押物"><span class="bp-value">{{ retailOutput.bpCollateral || '-' }}</span></el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">风险度分析</h4>
|
<h4 class="section-title">风险度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="灰名单客户">{{ formatBoolean(retailOutput.greyCust) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="本金逾期">{{ formatBoolean(retailOutput.prinOverdue) }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="利息逾期">{{ formatBoolean(retailOutput.interestOverdue) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="信用卡逾期">{{ formatBoolean(retailOutput.cardOverdue) }}</el-descriptions-item>
|
<tr v-for="(row, index) in retailRiskRows" :key="`retail-risk-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="BP_灰名单与逾期"><span class="bp-value">{{ retailOutput.bpGreyOverdue || '-' }}</span></el-descriptions-item>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
<el-descriptions-item label="TOTAL_BP_风险度"><span class="total-bp-value">{{ retailOutput.totalBpRisk || '-' }}</span></el-descriptions-item>
|
<td><span :class="row.total ? 'total-bp-value' : 'bp-value'">{{ row.bpLabel }}:{{ row.bpValue }}</span></td>
|
||||||
</el-descriptions>
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 企业客户模型输出 -->
|
<!-- 企业客户模型输出 -->
|
||||||
<template v-else-if="custType === '企业' && corpOutput">
|
<template v-else-if="custType === '企业' && corpOutput">
|
||||||
<div class="output-section">
|
|
||||||
<h4 class="section-title">基本信息</h4>
|
|
||||||
<el-descriptions :column="2" border size="small">
|
|
||||||
<el-descriptions-item label="客户内码">{{ corpOutput.custIsn || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户名称">{{ corpOutput.custName || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="证件类型">{{ corpOutput.idType || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="证件号码">{{ corpOutput.idNum || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="基准利率"><span class="rate-value">{{ formatRate(corpOutput.baseLoanRate) }}</span> %</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">测算结果</h4>
|
<h4 class="section-title">测算结果</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<el-descriptions :column="3" border size="small">
|
||||||
|
<el-descriptions-item label="基准利率"><span class="rate-value">{{ formatRate(corpOutput.baseLoanRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="浮动BP"><span class="total-bp-value">{{ corpOutput.totalBp || '-' }}</span></el-descriptions-item>
|
<el-descriptions-item label="浮动BP"><span class="total-bp-value">{{ corpOutput.totalBp || '-' }}</span></el-descriptions-item>
|
||||||
<el-descriptions-item label="测算利率"><span class="calculate-rate">{{ formatRate(corpOutput.calculateRate) }}</span> %</el-descriptions-item>
|
<el-descriptions-item label="模型测算利率"><span class="calculate-rate">{{ formatRate(corpOutput.calculateRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="历史利率">{{ formatRate(corpOutput.loanRateHistory) }}</el-descriptions-item>
|
<el-descriptions-item label="历史利率">{{ formatRate(corpOutput.loanRateHistory) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="产品最低利率下限">{{ formatRate(corpOutput.minRateProduct) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="平滑幅度">{{ formatRate(corpOutput.smoothRange) }}</el-descriptions-item>
|
<el-descriptions-item label="平滑幅度">{{ formatRate(corpOutput.smoothRange) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="平滑利率"><span class="calculate-rate">{{ formatRate(corpOutput.finalCalculateRate) }}</span> %</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="行社下调BP">{{ formatOutputValue(corpOutput.branchBp) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="参考利率"><span class="calculate-rate">{{ formatRate(corpOutput.referenceRate) }}</span> %</el-descriptions-item>
|
<el-descriptions-item label="参考利率"><span class="calculate-rate">{{ formatRate(corpOutput.referenceRate) }}</span> %</el-descriptions-item>
|
||||||
<el-descriptions-item label="最终测算利率"><span class="calculate-rate">{{ formatRate(corpOutput.finalCalculateRate) }}</span> %</el-descriptions-item>
|
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">忠诚度分析</h4>
|
<h4 class="section-title">忠诚度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="我行首贷客户">{{ formatBoolean(corpOutput.isFirstLoan) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="用信天数">{{ corpOutput.faithDay || '-' }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="BP_首贷"><span class="bp-value">{{ corpOutput.bpFirstLoan || '-' }}</span></el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="BP_贷龄"><span class="bp-value">{{ corpOutput.bpAgeLoan || '-' }}</span></el-descriptions-item>
|
<tr v-for="(row, index) in corporateLoyaltyRows" :key="`corporate-loyalty-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="TOTAL_BP_忠诚度" :span="2"><span class="total-bp-value">{{ corpOutput.totalBpLoyalty || '-' }}</span></el-descriptions-item>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
</el-descriptions>
|
<td><span :class="row.total ? 'total-bp-value' : 'bp-value'">{{ row.bpLabel }}:{{ row.bpValue }}</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">贡献度分析</h4>
|
<h4 class="section-title">贡献度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="存款年日均">{{ corpOutput.balanceAvg || '-' }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="贷款年日均">{{ corpOutput.loanAvg || '-' }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="派生率">{{ formatRate(corpOutput.derivationRate) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="TOTAL_BP_贡献度"><span class="total-bp-value">{{ corpOutput.totalBpContribution || '-' }}</span></el-descriptions-item>
|
<tr v-for="(row, index) in corporateContributionRows" :key="`corporate-contribution-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
</el-descriptions>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
|
<td><span v-if="row.bpLabel" :class="row.total ? 'total-bp-value' : 'bp-value'">{{ row.bpLabel }}:{{ row.bpValue }}</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">关联度分析</h4>
|
<h4 class="section-title">关联度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="中间业务_企业_企业互联">{{ formatBoolean(corpOutput.midEntConnect) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="中间业务_企业_有效价值客户">{{ formatBoolean(corpOutput.midEntEffect) }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="中间业务_企业_国际业务">{{ formatBoolean(corpOutput.midEntInter) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="中间业务_企业_承兑">{{ formatBoolean(corpOutput.midEntAccept) }}</el-descriptions-item>
|
<tr v-for="(row, index) in corporateRelevanceRows" :key="`corporate-relevance-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="中间业务_企业_贴现">{{ formatBoolean(corpOutput.midEntDiscount) }}</el-descriptions-item>
|
<td><span v-if="row.summary">汇总</span><template v-else><div v-if="row.category" class="result-category">{{ row.category }}</div><div v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span v-if="item.showValue !== false" class="result-value">{{ item.value }}</span></div></template></td>
|
||||||
<el-descriptions-item label="中间业务_企业_电费代扣">{{ formatBoolean(corpOutput.midEntEleDdc) }}</el-descriptions-item>
|
<td>
|
||||||
<el-descriptions-item label="中间业务_企业_水费代扣">{{ formatBoolean(corpOutput.midEntWaterDdc) }}</el-descriptions-item>
|
<span :class="row.total ? 'total-bp-value' : 'bp-value'">
|
||||||
<el-descriptions-item label="BP_中间业务"><span class="bp-value">{{ corpOutput.bpMid || '-' }}</span></el-descriptions-item>
|
<template v-if="row.bpLabel">{{ row.bpLabel }}:</template>{{ row.bpValue }}
|
||||||
<el-descriptions-item label="代发工资户数">{{ corpOutput.payroll || '-' }}</el-descriptions-item>
|
</span>
|
||||||
<el-descriptions-item label="存量贷款余额">{{ corpOutput.invLoanAmount || '-' }}</el-descriptions-item>
|
</td>
|
||||||
<el-descriptions-item label="BP_代发工资"><span class="bp-value">{{ corpOutput.bpPayroll || '-' }}</span></el-descriptions-item>
|
</tr>
|
||||||
<el-descriptions-item label="TOTAL_BP_关联度"><span class="total-bp-value">{{ corpOutput.totalBpRelevance || '-' }}</span></el-descriptions-item>
|
</tbody>
|
||||||
</el-descriptions>
|
</table>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="output-section">
|
|
||||||
<h4 class="section-title">企业类别</h4>
|
|
||||||
<el-descriptions :column="2" border size="small">
|
|
||||||
<el-descriptions-item label="净身企业">{{ formatBoolean(corpOutput.isCleanEnt) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="开立基本结算账户">{{ formatBoolean(corpOutput.hasSettleAcct) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="绿色贷款">{{ formatBoolean(corpOutput.isGreenLoan) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="科技型企业">{{ formatBoolean(corpOutput.isTechEnt) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="贸易和建筑业企业">{{ formatBoolean(corpOutput.isTradeBuildEnt) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_企业客户类别"><span class="bp-value">{{ corpOutput.bpEntType || '-' }}</span></el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="output-section">
|
|
||||||
<h4 class="section-title">贷款特征</h4>
|
|
||||||
<el-descriptions :column="2" border size="small">
|
|
||||||
<el-descriptions-item label="借款期限">{{ corpOutput.loanTerm || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_贷款期限"><span class="bp-value">{{ corpOutput.bpLoanTerm || '-' }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="申请金额">{{ corpOutput.applyAmt || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_贷款额度"><span class="bp-value">{{ corpOutput.bpLoanAmount || '-' }}</span></el-descriptions-item>
|
|
||||||
<el-descriptions-item label="抵质押类型">{{ corpOutput.collType || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="抵质押物三方所有">{{ formatBoolean(corpOutput.collThirdParty) }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="BP_抵押物"><span class="bp-value">{{ corpOutput.bpCollateral || '-' }}</span></el-descriptions-item>
|
|
||||||
</el-descriptions>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="output-section">
|
<div class="output-section">
|
||||||
<h4 class="section-title">风险度分析</h4>
|
<h4 class="section-title">风险度分析</h4>
|
||||||
<el-descriptions :column="2" border size="small">
|
<table class="output-analysis-table">
|
||||||
<el-descriptions-item label="灰名单客户">{{ formatBoolean(corpOutput.greyCust) }}</el-descriptions-item>
|
<colgroup><col class="result-column"><col class="bp-column"></colgroup>
|
||||||
<el-descriptions-item label="本金逾期">{{ formatBoolean(corpOutput.prinOverdue) }}</el-descriptions-item>
|
<thead><tr><th>模型输出结果</th><th>影响BP</th></tr></thead>
|
||||||
<el-descriptions-item label="利息逾期">{{ formatBoolean(corpOutput.interestOverdue) }}</el-descriptions-item>
|
<tbody>
|
||||||
<el-descriptions-item label="BP_灰名单与逾期"><span class="bp-value">{{ corpOutput.bpGreyOverdue || '-' }}</span></el-descriptions-item>
|
<tr v-for="(row, index) in corporateRiskRows" :key="`corporate-risk-${index}`" :class="{ 'is-total-row': row.total }">
|
||||||
<el-descriptions-item label="TOTAL_BP_风险度"><span class="total-bp-value">{{ corpOutput.totalBpRisk || '-' }}</span></el-descriptions-item>
|
<td><span v-if="row.summary">汇总</span><div v-else v-for="item in row.results" :key="item.label" class="result-item"><span class="result-label">{{ item.label }}</span><span class="result-value">{{ item.value }}</span></div></td>
|
||||||
</el-descriptions>
|
<td><span :class="row.total ? 'total-bp-value' : 'bp-value'">{{ row.bpLabel }}:{{ row.bpValue }}</span></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
@@ -225,10 +198,156 @@ export default {
|
|||||||
corpOutput: {
|
corpOutput: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
guarType: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
retailLoyaltyRows() {
|
||||||
|
return [
|
||||||
|
this.analysisRow('我行首贷客户', this.formatBoolean(this.retailOutput.isFirstLoan), 'BP_首贷', this.retailOutput.bpFirstLoan),
|
||||||
|
this.analysisRow('用信天数', this.retailOutput.faithDay, 'BP_贷龄', this.retailOutput.bpAgeLoan),
|
||||||
|
this.analysisRow('客户年龄', this.retailOutput.custAge, 'BP_年龄', this.retailOutput.bpAge),
|
||||||
|
this.totalRow('TOTAL_BP_忠诚度', this.retailOutput.totalBpLoyalty)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
retailContributionRows() {
|
||||||
|
return [
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('存款年日均', this.retailOutput.balanceAvg),
|
||||||
|
this.resultItem('贷款年日均', this.retailOutput.loanAvg),
|
||||||
|
this.resultItem('派生率', this.formatRate(this.retailOutput.derivationRate))
|
||||||
|
]),
|
||||||
|
this.totalRow('TOTAL_BP_贡献度', this.retailOutput.totalBpContribution, '最高上限100BP', '查看贡献度汇总上限')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
retailRelevanceRows() {
|
||||||
|
return [
|
||||||
|
this.middleBusinessRow('中间业务_个人_信用卡', this.retailOutput.midPerCard, '办理减5个BP,信用卡额度1万元及以上的再减10个BP'),
|
||||||
|
this.middleBusinessRow('中间业务_个人_一码通', this.retailOutput.midPerPass),
|
||||||
|
this.middleBusinessRow('中间业务_个人_丰收互联', this.retailOutput.midPerHarvest),
|
||||||
|
this.middleBusinessRow('中间业务_个人_有效客户', this.retailOutput.midPerEffect),
|
||||||
|
this.middleBusinessRow('中间业务_个人_快捷支付', this.retailOutput.midPerQuickPay),
|
||||||
|
this.middleBusinessRow('中间业务_个人_电费代扣', this.retailOutput.midPerEleDdc),
|
||||||
|
this.middleBusinessRow('中间业务_个人_水费代扣', this.retailOutput.midPerWaterDdc),
|
||||||
|
this.middleBusinessRow('中间业务_个人_华数费代扣', this.retailOutput.midPerHuashuDdc),
|
||||||
|
this.middleBusinessRow('中间业务_个人_煤气费代扣', this.retailOutput.midPerGasDdc),
|
||||||
|
this.middleBusinessRow('中间业务_个人_市民卡', this.retailOutput.midPerCitizencard),
|
||||||
|
this.middleBusinessRow('中间业务_个人_理财业务', this.retailOutput.midPerFinMan),
|
||||||
|
this.middleBusinessRow('中间业务_个人_etc', this.retailOutput.midPerEtc),
|
||||||
|
this.totalRow('TOTAL_BP_关联度', this.retailOutput.totalBpRelevance, '最高上限-30BP', '查看中间业务BP上限')
|
||||||
|
]
|
||||||
|
},
|
||||||
|
retailRiskRows() {
|
||||||
|
const rows = [
|
||||||
|
this.analysisRow('申请金额', this.retailOutput.applyAmt, 'BP_贷款额度', this.retailOutput.bpLoanAmount),
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('贷款用途', this.formatLoanPurpose(this.retailOutput.loanPurpose)),
|
||||||
|
this.resultItem('营业执照', this.formatBoolean(this.retailOutput.bizProof))
|
||||||
|
], 'BP_贷款用途', this.retailOutput.bpLoanUse),
|
||||||
|
this.analysisRow('循环功能', this.formatBoolean(this.retailOutput.loanLoop), 'BP_循环功能', this.retailOutput.bpLoanLoop)
|
||||||
|
]
|
||||||
|
if (this.guarType === '抵押' || this.guarType === '质押') {
|
||||||
|
rows.push(this.analysisRow('抵押物第三方所有', this.formatBoolean(this.retailOutput.collThirdParty), 'BP_抵押物', this.retailOutput.bpCollateral))
|
||||||
|
}
|
||||||
|
rows.push(
|
||||||
|
this.analysisRow('本金逾期', this.formatBoolean(this.retailOutput.prinOverdue), 'BP_本金逾期', this.retailOutput.bpPrinOverdue),
|
||||||
|
this.analysisRow('利息逾期', this.formatBoolean(this.retailOutput.interestOverdue), 'BP_利息逾期', this.retailOutput.bpIinterestOverdue),
|
||||||
|
this.analysisRow('信用卡逾期', this.formatBoolean(this.retailOutput.cardOverdue), 'BP_信用卡逾期', this.retailOutput.bpCardOverdue),
|
||||||
|
this.totalRow('TOTAL_BP_风险度', this.retailOutput.totalBpRisk)
|
||||||
|
)
|
||||||
|
return rows
|
||||||
|
},
|
||||||
|
corporateLoyaltyRows() {
|
||||||
|
return [
|
||||||
|
this.analysisRow('我行首贷客户', this.formatBoolean(this.corpOutput.isFirstLoan), 'BP_首贷', this.corpOutput.bpFirstLoan),
|
||||||
|
this.analysisRow('用信天数', this.corpOutput.faithDay, 'BP_贷龄', this.corpOutput.bpAgeLoan),
|
||||||
|
this.totalRow('TOTAL_BP_忠诚度', this.corpOutput.totalBpLoyalty)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
corporateContributionRows() {
|
||||||
|
return [
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('存款年日均', this.corpOutput.balanceAvg),
|
||||||
|
this.resultItem('贷款年日均', this.corpOutput.loanAvg),
|
||||||
|
this.resultItem('派生率', this.formatRate(this.corpOutput.derivationRate))
|
||||||
|
]),
|
||||||
|
this.totalRow('TOTAL_BP_贡献度', this.corpOutput.totalBpContribution)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
corporateRelevanceRows() {
|
||||||
|
return [
|
||||||
|
this.middleBusinessRow('中间业务_企业_企业互联', this.corpOutput.midEntConnect),
|
||||||
|
this.middleBusinessRow('中间业务_企业_有效价值客户', this.corpOutput.midEntEffect),
|
||||||
|
this.middleBusinessRow('中间业务_企业_国际业务', this.corpOutput.midEntInter),
|
||||||
|
this.middleBusinessRow('中间业务_企业_承兑', this.corpOutput.midEntAccept),
|
||||||
|
this.middleBusinessRow('中间业务_企业_贴现', this.corpOutput.midEntDiscount),
|
||||||
|
this.middleBusinessRow('中间业务_企业_电费代扣', this.corpOutput.midEntEleDdc),
|
||||||
|
this.middleBusinessRow('中间业务_企业_水费代扣', this.corpOutput.midEntWaterDdc),
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('代发工资户数', this.corpOutput.payroll),
|
||||||
|
this.resultItem('存量贷款余额', this.corpOutput.invLoanAmount)
|
||||||
|
], 'BP_代发工资', this.corpOutput.bpPayroll, false, '代发工资'),
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('净身企业', this.formatBoolean(this.corpOutput.isCleanEnt)),
|
||||||
|
this.resultItem('开立基本结算账户', this.formatBoolean(this.corpOutput.hasSettleAcct)),
|
||||||
|
this.resultItem('绿色贷款', this.formatBoolean(this.corpOutput.isGreenLoan)),
|
||||||
|
this.resultItem('科技型企业', this.formatBoolean(this.corpOutput.isTechEnt)),
|
||||||
|
this.resultItem('贸易和建筑业企业', this.formatBoolean(this.corpOutput.isTradeBuildEnt))
|
||||||
|
], 'BP_企业客户类别', this.corpOutput.bpEntType, false, '客户类型'),
|
||||||
|
this.totalRow('TOTAL_BP_关联度', this.corpOutput.totalBpRelevance)
|
||||||
|
]
|
||||||
|
},
|
||||||
|
corporateRiskRows() {
|
||||||
|
const rows = [
|
||||||
|
this.analysisRow('借款期限', this.corpOutput.loanTerm, 'BP_贷款期限', this.corpOutput.bpLoanTerm),
|
||||||
|
this.analysisRow('申请金额', this.corpOutput.applyAmt, 'BP_贷款额度', this.corpOutput.bpLoanAmount)
|
||||||
|
]
|
||||||
|
if (this.guarType === '抵押' || this.guarType === '质押') {
|
||||||
|
rows.push(this.groupedAnalysisRow([
|
||||||
|
this.resultItem('抵质押类型', this.corpOutput.collType),
|
||||||
|
this.resultItem('抵质押物三方所有', this.formatBoolean(this.corpOutput.collThirdParty))
|
||||||
|
], 'BP_抵押物', this.corpOutput.bpCollateral))
|
||||||
|
}
|
||||||
|
rows.push(
|
||||||
|
this.groupedAnalysisRow([
|
||||||
|
this.resultItem('灰名单客户', this.formatBoolean(this.corpOutput.greyCust)),
|
||||||
|
this.resultItem('黑名单客户', this.formatBoolean(this.corpOutput.blackCust))
|
||||||
|
], 'BP_灰名单与逾期', this.corpOutput.bpGreyOverdue),
|
||||||
|
this.analysisRow('本金逾期', this.formatBoolean(this.corpOutput.prinOverdue), 'BP_本金逾期', this.corpOutput.bpPrinOverdue),
|
||||||
|
this.analysisRow('利息逾期', this.corpOutput.interestOverdue, 'BP_利息逾期', this.corpOutput.bpIinterestOverdue),
|
||||||
|
this.analysisRow('信用卡逾期', this.formatBoolean(this.corpOutput.cardOverdue), 'BP_信用卡逾期', this.corpOutput.bpCardOverdue),
|
||||||
|
this.totalRow('TOTAL_BP_风险度', this.corpOutput.totalBpRisk)
|
||||||
|
)
|
||||||
|
return rows
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatRate,
|
formatRate,
|
||||||
|
resultItem(label, value, showValue = true) {
|
||||||
|
return {label, value: this.formatOutputValue(value), showValue}
|
||||||
|
},
|
||||||
|
groupedAnalysisRow(results, bpLabel, bpValue, total = false, category = null) {
|
||||||
|
return {results, bpLabel, bpValue: this.formatOutputValue(bpValue), total, category}
|
||||||
|
},
|
||||||
|
analysisRow(resultLabel, resultValue, bpLabel, bpValue) {
|
||||||
|
return this.groupedAnalysisRow([this.resultItem(resultLabel, resultValue)], bpLabel, bpValue)
|
||||||
|
},
|
||||||
|
middleBusinessRow(resultLabel, bpValue, tooltip = null) {
|
||||||
|
return {
|
||||||
|
results: [this.resultItem(resultLabel, null, false)],
|
||||||
|
bpLabel: null,
|
||||||
|
bpValue: this.formatOutputValue(bpValue),
|
||||||
|
total: false,
|
||||||
|
bpTooltip: tooltip,
|
||||||
|
bpTooltipAriaLabel: tooltip ? `${resultLabel}提示` : null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
totalRow(bpLabel, bpValue, bpTooltip = null, bpTooltipAriaLabel = null) {
|
||||||
|
return {summary: true, bpLabel, bpValue: this.formatOutputValue(bpValue), total: true, bpTooltip, bpTooltipAriaLabel}
|
||||||
|
},
|
||||||
/** 格式化布尔值为中文 */
|
/** 格式化布尔值为中文 */
|
||||||
formatBoolean(value) {
|
formatBoolean(value) {
|
||||||
if (value === 'true' || value === true || value === '1' || value === 1) return '是'
|
if (value === 'true' || value === true || value === '1' || value === 1) return '是'
|
||||||
@@ -283,6 +402,98 @@ export default {
|
|||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.analysis-help {
|
||||||
|
margin-left: 4px;
|
||||||
|
color: #909399;
|
||||||
|
cursor: help;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-analysis-table {
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
color: #606266;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
.result-column {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp-column {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-right: 1px solid #ebeef5;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
th:last-child,
|
||||||
|
td:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:last-child td {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #909399;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 4px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-item + .result-item {
|
||||||
|
margin-top: 6px;
|
||||||
|
padding-top: 6px;
|
||||||
|
border-top: 1px dashed #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-category {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-label {
|
||||||
|
min-width: 0;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-value {
|
||||||
|
margin-left: auto;
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-total-row {
|
||||||
|
background: #fffaf0;
|
||||||
|
|
||||||
|
td:first-child {
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BP 值样式
|
// BP 值样式
|
||||||
.bp-value {
|
.bp-value {
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
@@ -308,4 +519,44 @@ export default {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.model-output-card {
|
||||||
|
::v-deep .el-card__body {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-analysis-table {
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.model-output-card {
|
||||||
|
break-inside: auto !important;
|
||||||
|
page-break-inside: auto !important;
|
||||||
|
|
||||||
|
.output-section {
|
||||||
|
break-inside: auto;
|
||||||
|
page-break-inside: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output-analysis-table {
|
||||||
|
color: #000;
|
||||||
|
|
||||||
|
thead {
|
||||||
|
display: table-header-group;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
break-inside: avoid !important;
|
||||||
|
page-break-inside: avoid !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -52,6 +52,14 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="贷款用途" prop="loanPurpose">
|
||||||
|
<el-select v-model="form.loanPurpose" placeholder="请选择贷款用途" style="width: 100%">
|
||||||
|
<el-option label="经营" value="business"/>
|
||||||
|
<el-option label="消费" value="consumer"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="借款期限(年)" prop="loanTerm">
|
<el-form-item label="借款期限(年)" prop="loanTerm">
|
||||||
<el-select v-model="form.loanTerm" placeholder="请选择借款期限" style="width: 100%">
|
<el-select v-model="form.loanTerm" placeholder="请选择借款期限" style="width: 100%">
|
||||||
@@ -77,6 +85,11 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row>
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否有营业执照" prop="bizProof">
|
||||||
|
<el-switch v-model="form.bizProof"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="循环功能" prop="loanLoop">
|
<el-form-item label="循环功能" prop="loanLoop">
|
||||||
<el-switch v-model="form.loanLoop"/>
|
<el-switch v-model="form.loanLoop"/>
|
||||||
@@ -87,7 +100,33 @@
|
|||||||
<!-- 抵质押信息 -->
|
<!-- 抵质押信息 -->
|
||||||
<el-divider v-if="isCollateralGuarantee" content-position="left">抵质押信息</el-divider>
|
<el-divider v-if="isCollateralGuarantee" content-position="left">抵质押信息</el-divider>
|
||||||
<el-row v-if="isCollateralGuarantee">
|
<el-row v-if="isCollateralGuarantee">
|
||||||
<el-col :span="12">
|
<template v-if="isMortgage">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="抵押物性质" prop="collateralNature">
|
||||||
|
<el-select v-model="form.collateralNature" placeholder="请选择抵押物性质" style="width: 100%">
|
||||||
|
<el-option v-for="item in collateralNatureOptions" :key="item" :label="item" :value="item"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="是否属于九地" prop="isNineArea">
|
||||||
|
<div class="nine-area-control">
|
||||||
|
<el-select
|
||||||
|
v-model="form.isNineArea"
|
||||||
|
:disabled="!requiresNineArea"
|
||||||
|
:placeholder="requiresNineArea ? '请选择是否属于九地' : '无需选择'"
|
||||||
|
>
|
||||||
|
<el-option label="是" value="是"/>
|
||||||
|
<el-option label="否" value="否"/>
|
||||||
|
</el-select>
|
||||||
|
<el-tooltip content="九地是指绍兴、杭州、宁波、上海、北京、广州、深圳、南京、苏州" placement="top">
|
||||||
|
<i class="el-icon-question nine-area-help" tabindex="0" aria-label="查看九地说明"></i>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</template>
|
||||||
|
<el-col :span="12" v-if="isPledge">
|
||||||
<el-form-item label="抵质押类型" prop="collType">
|
<el-form-item label="抵质押类型" prop="collType">
|
||||||
<el-select v-model="form.collType" placeholder="请选择抵质押类型" style="width: 100%">
|
<el-select v-model="form.collType" placeholder="请选择抵质押类型" style="width: 100%">
|
||||||
<el-option v-for="item in collateralTypeOptions" :key="item" :label="item" :value="item"/>
|
<el-option v-for="item in collateralTypeOptions" :key="item" :label="item" :value="item"/>
|
||||||
@@ -168,6 +207,30 @@ export default {
|
|||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const validateCollateralType = (rule, value, callback) => {
|
||||||
|
if (this.isPledge && !value) {
|
||||||
|
callback(new Error('请选择抵质押类型'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateCollateralNature = (rule, value, callback) => {
|
||||||
|
if (this.isMortgage && !value) {
|
||||||
|
callback(new Error('请选择抵押物性质'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateNineArea = (rule, value, callback) => {
|
||||||
|
if (this.requiresNineArea && !value) {
|
||||||
|
callback(new Error('请选择是否属于九地'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loanTermOptions: [
|
loanTermOptions: [
|
||||||
'1', '2', '3', '4', '5', '6'
|
'1', '2', '3', '4', '5', '6'
|
||||||
@@ -187,11 +250,15 @@ export default {
|
|||||||
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
|
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
|
||||||
guarType: undefined,
|
guarType: undefined,
|
||||||
applyAmt: undefined,
|
applyAmt: undefined,
|
||||||
|
loanPurpose: undefined,
|
||||||
loanTerm: undefined,
|
loanTerm: undefined,
|
||||||
businessType: undefined,
|
businessType: undefined,
|
||||||
loanRateHistory: undefined,
|
loanRateHistory: undefined,
|
||||||
|
bizProof: false,
|
||||||
loanLoop: false,
|
loanLoop: false,
|
||||||
collType: undefined,
|
collType: undefined,
|
||||||
|
collateralNature: undefined,
|
||||||
|
isNineArea: undefined,
|
||||||
collThirdParty: false,
|
collThirdParty: false,
|
||||||
couponRate: undefined
|
couponRate: undefined
|
||||||
},
|
},
|
||||||
@@ -216,6 +283,9 @@ export default {
|
|||||||
applyAmt: [
|
applyAmt: [
|
||||||
{required: true, validator: validateApplyAmt, trigger: "blur"}
|
{required: true, validator: validateApplyAmt, trigger: "blur"}
|
||||||
],
|
],
|
||||||
|
loanPurpose: [
|
||||||
|
{required: true, message: "请选择贷款用途", trigger: "change"}
|
||||||
|
],
|
||||||
loanTerm: [
|
loanTerm: [
|
||||||
{required: true, message: "请选择借款期限", trigger: "change"}
|
{required: true, message: "请选择借款期限", trigger: "change"}
|
||||||
],
|
],
|
||||||
@@ -226,7 +296,13 @@ export default {
|
|||||||
{required: true, message: "请选择历史贷款合同", trigger: "change"}
|
{required: true, message: "请选择历史贷款合同", trigger: "change"}
|
||||||
],
|
],
|
||||||
collType: [
|
collType: [
|
||||||
{required: true, message: "请选择抵质押类型", trigger: "change"}
|
{validator: validateCollateralType, trigger: "change"}
|
||||||
|
],
|
||||||
|
collateralNature: [
|
||||||
|
{validator: validateCollateralNature, trigger: "change"}
|
||||||
|
],
|
||||||
|
isNineArea: [
|
||||||
|
{validator: validateNineArea, trigger: "change"}
|
||||||
],
|
],
|
||||||
couponRate: [
|
couponRate: [
|
||||||
{validator: validateCouponRate, trigger: "blur"}
|
{validator: validateCouponRate, trigger: "blur"}
|
||||||
@@ -246,6 +322,15 @@ export default {
|
|||||||
isCollateralGuarantee() {
|
isCollateralGuarantee() {
|
||||||
return this.form.guarType === '抵押' || this.form.guarType === '质押'
|
return this.form.guarType === '抵押' || this.form.guarType === '质押'
|
||||||
},
|
},
|
||||||
|
isMortgage() {
|
||||||
|
return this.form.guarType === '抵押'
|
||||||
|
},
|
||||||
|
isPledge() {
|
||||||
|
return this.form.guarType === '质押'
|
||||||
|
},
|
||||||
|
requiresNineArea() {
|
||||||
|
return this.isMortgage && ['普通住宅、土地、厂房', '商业性质不动产'].includes(this.form.collateralNature)
|
||||||
|
},
|
||||||
isStockTransfer() {
|
isStockTransfer() {
|
||||||
return this.form.businessType === '存量转贷'
|
return this.form.businessType === '存量转贷'
|
||||||
},
|
},
|
||||||
@@ -259,13 +344,13 @@ export default {
|
|||||||
return this.isEdit ? '编辑个人利率定价流程' : '新增个人利率定价流程'
|
return this.isEdit ? '编辑个人利率定价流程' : '新增个人利率定价流程'
|
||||||
},
|
},
|
||||||
collateralTypeOptions() {
|
collateralTypeOptions() {
|
||||||
if (this.form.guarType === '抵押') {
|
if (this.isPledge) {
|
||||||
return ['一线', '一类', '二类', '三类']
|
|
||||||
}
|
|
||||||
if (this.form.guarType === '质押') {
|
|
||||||
return ['存单质押', '其他质押']
|
return ['存单质押', '其他质押']
|
||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
|
},
|
||||||
|
collateralNatureOptions() {
|
||||||
|
return ['普通住宅、土地、厂房', '商业性质不动产', '其他抵押财产']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@@ -287,6 +372,12 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.resetCouponRateIfNotCertificatePledge()
|
this.resetCouponRateIfNotCertificatePledge()
|
||||||
|
},
|
||||||
|
'form.collateralNature'(val, oldVal) {
|
||||||
|
if (this.resettingForm || val === oldVal) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.handleCollateralNatureChange()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -318,11 +409,15 @@ export default {
|
|||||||
idNum: this.editData.idNum,
|
idNum: this.editData.idNum,
|
||||||
guarType: this.editData.guarType,
|
guarType: this.editData.guarType,
|
||||||
applyAmt: this.editData.applyAmt,
|
applyAmt: this.editData.applyAmt,
|
||||||
|
loanPurpose: this.editData.loanPurpose,
|
||||||
loanTerm: this.editData.loanTerm,
|
loanTerm: this.editData.loanTerm,
|
||||||
businessType: this.editData.businessType,
|
businessType: this.editData.businessType,
|
||||||
loanRateHistory: this.editData.loanRateHistory,
|
loanRateHistory: this.editData.loanRateHistory,
|
||||||
|
bizProof: this.isOne(this.editData.bizProof),
|
||||||
loanLoop: this.isOne(this.editData.loanLoop),
|
loanLoop: this.isOne(this.editData.loanLoop),
|
||||||
collType: this.editData.collType,
|
collType: this.editData.guarType === '质押' ? this.editData.collType : undefined,
|
||||||
|
collateralNature: this.editData.collateralNature,
|
||||||
|
isNineArea: this.editData.isNineArea,
|
||||||
collThirdParty: this.isOne(this.editData.collThirdParty),
|
collThirdParty: this.isOne(this.editData.collThirdParty),
|
||||||
couponRate: this.editData.couponRate
|
couponRate: this.editData.couponRate
|
||||||
}
|
}
|
||||||
@@ -336,11 +431,15 @@ export default {
|
|||||||
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
|
idNum: this.customerMap ? (this.customerMap.cust_id || '').substring(3) : undefined,
|
||||||
guarType: undefined,
|
guarType: undefined,
|
||||||
applyAmt: undefined,
|
applyAmt: undefined,
|
||||||
|
loanPurpose: undefined,
|
||||||
loanTerm: undefined,
|
loanTerm: undefined,
|
||||||
businessType: undefined,
|
businessType: undefined,
|
||||||
loanRateHistory: undefined,
|
loanRateHistory: undefined,
|
||||||
|
bizProof: false,
|
||||||
loanLoop: false,
|
loanLoop: false,
|
||||||
collType: undefined,
|
collType: undefined,
|
||||||
|
collateralNature: undefined,
|
||||||
|
isNineArea: undefined,
|
||||||
collThirdParty: false,
|
collThirdParty: false,
|
||||||
couponRate: undefined
|
couponRate: undefined
|
||||||
}
|
}
|
||||||
@@ -360,14 +459,35 @@ export default {
|
|||||||
/** 清空抵质押字段 */
|
/** 清空抵质押字段 */
|
||||||
resetCollateralFields() {
|
resetCollateralFields() {
|
||||||
this.form.collType = undefined
|
this.form.collType = undefined
|
||||||
|
this.form.collateralNature = undefined
|
||||||
|
this.form.isNineArea = undefined
|
||||||
this.form.collThirdParty = false
|
this.form.collThirdParty = false
|
||||||
this.resetCouponRateIfNotCertificatePledge()
|
this.resetCouponRateIfNotCertificatePledge()
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.$refs.form) {
|
if (this.$refs.form) {
|
||||||
this.$refs.form.clearValidate(['collType', 'collThirdParty', 'couponRate'])
|
this.$refs.form.clearValidate(['collType', 'collateralNature', 'isNineArea', 'collThirdParty', 'couponRate'])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
handleCollateralNatureChange() {
|
||||||
|
this.form.isNineArea = undefined
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.$refs.form) {
|
||||||
|
this.$refs.form.clearValidate(['isNineArea'])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
resolveMortgageCollateralType() {
|
||||||
|
if (this.form.collateralNature === '普通住宅、土地、厂房') {
|
||||||
|
return this.form.isNineArea === '是' ? '一类' : '二类'
|
||||||
|
}
|
||||||
|
if (this.form.collateralNature === '商业性质不动产') {
|
||||||
|
return this.form.isNineArea === '是' ? '二类' : '三类'
|
||||||
|
}
|
||||||
|
if (this.form.collateralNature === '其他抵押财产') {
|
||||||
|
return '四类'
|
||||||
|
}
|
||||||
|
},
|
||||||
resetCouponRateIfNotCertificatePledge() {
|
resetCouponRateIfNotCertificatePledge() {
|
||||||
if (!this.isCertificatePledge) {
|
if (!this.isCertificatePledge) {
|
||||||
this.form.couponRate = undefined
|
this.form.couponRate = undefined
|
||||||
@@ -435,8 +555,15 @@ export default {
|
|||||||
// 转换开关值为字符串
|
// 转换开关值为字符串
|
||||||
const data = {
|
const data = {
|
||||||
...this.form,
|
...this.form,
|
||||||
|
bizProof: this.form.bizProof ? '1' : '0',
|
||||||
loanLoop: this.form.loanLoop ? '1' : '0'
|
loanLoop: this.form.loanLoop ? '1' : '0'
|
||||||
}
|
}
|
||||||
|
if (this.isMortgage) {
|
||||||
|
data.collType = this.resolveMortgageCollateralType()
|
||||||
|
} else {
|
||||||
|
delete data.collateralNature
|
||||||
|
delete data.isNineArea
|
||||||
|
}
|
||||||
if (this.isCollateralGuarantee) {
|
if (this.isCollateralGuarantee) {
|
||||||
data.collThirdParty = this.form.collThirdParty ? '1' : '0'
|
data.collThirdParty = this.form.collThirdParty ? '1' : '0'
|
||||||
} else {
|
} else {
|
||||||
@@ -477,6 +604,24 @@ export default {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nine-area-control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nine-area-control .el-select {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nine-area-help {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
color: #909399;
|
||||||
|
cursor: help;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.workflow-create-form .el-col {
|
.workflow-create-form .el-col {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
|
|||||||
@@ -13,14 +13,10 @@
|
|||||||
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="客户类型">{{ detailData.custType }}</el-descriptions-item>
|
<el-descriptions-item label="客户类型">{{ detailData.custType }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
<el-descriptions-item label="申请金额">{{ detailData.applyAmt }} 元</el-descriptions-item>
|
||||||
<el-descriptions-item label="基准利率">
|
<el-descriptions-item label="期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
||||||
<span class="rate-value">{{ getBaseLoanRate() }}</span> %
|
<el-descriptions-item label="担保方式">{{ detailData.guarType || '-' }}</el-descriptions-item>
|
||||||
</el-descriptions-item>
|
<el-descriptions-item label="产品最低利率下限">
|
||||||
<el-descriptions-item label="浮动BP">
|
<span class="rate-value">{{ formatRate(retailOutput && retailOutput.minRateProduct) }}</span> %
|
||||||
<span class="total-bp-value">{{ getTotalBp() }}</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="最终测算利率">
|
|
||||||
<span class="calculate-rate">{{ getCalculateRate() }}</span> %
|
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="执行利率">
|
<el-descriptions-item label="执行利率">
|
||||||
<div class="execute-rate-input-wrapper">
|
<div class="execute-rate-input-wrapper">
|
||||||
@@ -46,13 +42,6 @@
|
|||||||
|
|
||||||
<!-- 右侧面板 -->
|
<!-- 右侧面板 -->
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<!-- 模型输出卡片 -->
|
|
||||||
<ModelOutputDisplay
|
|
||||||
:cust-type="detailData.custType"
|
|
||||||
:retail-output="retailOutput"
|
|
||||||
:corp-output="null"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 流程详情卡片 -->
|
<!-- 流程详情卡片 -->
|
||||||
<el-card class="detail-card">
|
<el-card class="detail-card">
|
||||||
<div slot="header" class="card-header">
|
<div slot="header" class="card-header">
|
||||||
@@ -64,10 +53,18 @@
|
|||||||
<h4 class="section-title">基本信息</h4>
|
<h4 class="section-title">基本信息</h4>
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<el-descriptions-item label="机构编码">{{ detailData.orgCode }}</el-descriptions-item>
|
<el-descriptions-item label="机构编码">{{ detailData.orgCode }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="运行模式">{{ detailData.runType }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="客户内码">{{ detailData.custIsn }}</el-descriptions-item>
|
<el-descriptions-item label="客户内码">{{ detailData.custIsn }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="客户名称">{{ detailData.custName }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="证件类型">{{ detailData.idType }}</el-descriptions-item>
|
<el-descriptions-item label="证件类型">{{ detailData.idType }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="证件号码">{{ detailData.idNum }}</el-descriptions-item>
|
<el-descriptions-item label="证件号码">{{ detailData.idNum }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="灰名单客户">{{
|
||||||
|
formatBoolean(retailOutput && retailOutput.greyCust)
|
||||||
|
}}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="黑名单客户">{{
|
||||||
|
formatBoolean(retailOutput && retailOutput.blackCust)
|
||||||
|
}}
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="创建时间">{{ detailData.createTime }}</el-descriptions-item>
|
<el-descriptions-item label="创建时间">{{ detailData.createTime }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="创建者">{{ detailData.createBy }}</el-descriptions-item>
|
<el-descriptions-item label="创建者">{{ detailData.createBy }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
@@ -83,11 +80,17 @@
|
|||||||
<el-descriptions-item label="业务种类">{{ detailData.businessType || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="业务种类">{{ detailData.businessType || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="历史贷款利率">{{ formatRate(detailData.loanRateHistory) }}</el-descriptions-item>
|
<el-descriptions-item label="历史贷款利率">{{ formatRate(detailData.loanRateHistory) }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="借款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="借款期限">{{ detailData.loanTerm || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="是否有经营佐证">{{
|
<el-descriptions-item label="是否有营业执照">{{
|
||||||
formatBoolean(detailData.bizProof)
|
formatBoolean(detailData.bizProof)
|
||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="循环功能">{{ formatBoolean(detailData.loanLoop) }}</el-descriptions-item>
|
<el-descriptions-item label="循环功能">{{ formatBoolean(detailData.loanLoop) }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="detailData.guarType === '抵押'" label="抵押物性质">
|
||||||
|
{{ detailData.collateralNature || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item v-if="detailData.guarType === '抵押'" label="是否属于九地">
|
||||||
|
{{ detailData.isNineArea || '-' }}
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="抵质押类型">{{ detailData.collType || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="抵质押类型">{{ detailData.collType || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="抵质押物是否三方所有">{{
|
<el-descriptions-item label="抵质押物是否三方所有">{{
|
||||||
formatBoolean(detailData.collThirdParty)
|
formatBoolean(detailData.collThirdParty)
|
||||||
@@ -97,6 +100,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 模型输出卡片 -->
|
||||||
|
<ModelOutputDisplay
|
||||||
|
:cust-type="detailData.custType"
|
||||||
|
:guar-type="detailData.guarType"
|
||||||
|
:retail-output="retailOutput"
|
||||||
|
:corp-output="null"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 议价池卡片 -->
|
<!-- 议价池卡片 -->
|
||||||
<BargainingPoolDisplay
|
<BargainingPoolDisplay
|
||||||
v-if="bargainingPool"
|
v-if="bargainingPool"
|
||||||
@@ -164,18 +175,6 @@ export default {
|
|||||||
if (value === 'business') return '经营'
|
if (value === 'business') return '经营'
|
||||||
return value || '-'
|
return value || '-'
|
||||||
},
|
},
|
||||||
/** 获取基准利率 */
|
|
||||||
getBaseLoanRate() {
|
|
||||||
return this.formatRate(this.retailOutput?.baseLoanRate)
|
|
||||||
},
|
|
||||||
/** 获取浮动BP */
|
|
||||||
getTotalBp() {
|
|
||||||
return this.retailOutput?.totalBp || '-'
|
|
||||||
},
|
|
||||||
/** 获取最终测算利率 */
|
|
||||||
getCalculateRate() {
|
|
||||||
return this.formatRate(this.retailOutput?.finalCalculateRate)
|
|
||||||
},
|
|
||||||
/** 设定执行利率 */
|
/** 设定执行利率 */
|
||||||
handleSetExecuteRate() {
|
handleSetExecuteRate() {
|
||||||
const value = this.executeRateInput
|
const value = this.executeRateInput
|
||||||
@@ -257,16 +256,6 @@ export default {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.total-bp-value {
|
|
||||||
color: #e6a23c;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calculate-rate {
|
|
||||||
color: #f56c6c;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
<el-form
|
||||||
|
:model="queryParams"
|
||||||
|
ref="queryForm"
|
||||||
|
size="small"
|
||||||
|
:inline="true"
|
||||||
|
v-show="showSearch"
|
||||||
|
label-width="68px"
|
||||||
|
@submit.native.prevent="handleQuery"
|
||||||
|
>
|
||||||
<el-form-item label="客户信息" prop="custIsn">
|
<el-form-item label="客户信息" prop="custIsn">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.custIsn"
|
v-model="queryParams.custIsn"
|
||||||
placeholder="请输入客户内码/证件号/客户名"
|
placeholder="请输入客户内码/证件号/客户名"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter.native="handleQuery"
|
@keydown.enter.native.prevent="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建者" prop="createBy">
|
<el-form-item v-if="showAllSearchItems" label="客户类型" prop="custType">
|
||||||
|
<el-select v-model="queryParams.custType" placeholder="请选择客户类型" clearable style="width: 160px">
|
||||||
|
<el-option label="个人" value="个人" />
|
||||||
|
<el-option label="企业" value="企业" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="showAllSearchItems" label="担保方式" prop="guarType">
|
||||||
|
<el-select v-model="queryParams.guarType" placeholder="请选择担保方式" clearable style="width: 160px">
|
||||||
|
<el-option label="信用" value="信用" />
|
||||||
|
<el-option label="保证" value="保证" />
|
||||||
|
<el-option label="抵押" value="抵押" />
|
||||||
|
<el-option label="质押" value="质押" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item v-if="showAllSearchItems" label="创建者" prop="createBy">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.createBy"
|
v-model="queryParams.createBy"
|
||||||
placeholder="请输入创建者"
|
placeholder="请输入创建者"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter.native="handleQuery"
|
@keydown.enter.native.prevent="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="机构号" prop="deptId">
|
<el-form-item v-if="showAllSearchItems" label="机构号" prop="deptId">
|
||||||
<treeselect
|
<treeselect
|
||||||
v-model="queryParams.deptId"
|
v-model="queryParams.deptId"
|
||||||
:options="deptOptions"
|
:options="deptOptions"
|
||||||
@@ -27,8 +49,19 @@
|
|||||||
style="width: 220px"
|
style="width: 220px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item v-if="showAllSearchItems" label="创建时间">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
type="daterange"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
range-separator="-"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
style="width: 240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
<el-button type="primary" icon="el-icon-search" size="mini" native-type="submit">搜索</el-button>
|
||||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -69,6 +102,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建者" align="center" prop="createBy" min-width="220" class-name="workflow-important-column" />
|
<el-table-column label="创建者" align="center" prop="createBy" min-width="220" class-name="workflow-important-column" />
|
||||||
|
<el-table-column label="机构号" align="center" prop="deptId" min-width="110" />
|
||||||
<el-table-column label="操作" align="center" fixed="right" min-width="150" class-name="small-padding fixed-width">
|
<el-table-column label="操作" align="center" fixed="right" min-width="150" class-name="small-padding fixed-width">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button
|
<el-button
|
||||||
@@ -157,6 +191,8 @@ export default {
|
|||||||
workflowList: [],
|
workflowList: [],
|
||||||
// 机构树选项
|
// 机构树选项
|
||||||
deptOptions: [],
|
deptOptions: [],
|
||||||
|
// 创建时间范围
|
||||||
|
dateRange: [],
|
||||||
// 是否显示客户类型选择弹出层
|
// 是否显示客户类型选择弹出层
|
||||||
showTypeSelector: false,
|
showTypeSelector: false,
|
||||||
// 是否显示客户号查询选择弹出层
|
// 是否显示客户号查询选择弹出层
|
||||||
@@ -176,6 +212,8 @@ export default {
|
|||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
custIsn: undefined,
|
custIsn: undefined,
|
||||||
|
custType: undefined,
|
||||||
|
guarType: undefined,
|
||||||
createBy: undefined,
|
createBy: undefined,
|
||||||
deptId: undefined
|
deptId: undefined
|
||||||
}
|
}
|
||||||
@@ -188,8 +226,12 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'name',
|
'name',
|
||||||
'nickName'
|
'nickName',
|
||||||
|
'roles'
|
||||||
]),
|
]),
|
||||||
|
showAllSearchItems() {
|
||||||
|
return !this.roles.includes('common')
|
||||||
|
},
|
||||||
currentCreateBy() {
|
currentCreateBy() {
|
||||||
return `${this.nickName}-${this.name}`
|
return `${this.nickName}-${this.name}`
|
||||||
}
|
}
|
||||||
@@ -220,7 +262,13 @@ export default {
|
|||||||
/** 查询利率定价流程列表 */
|
/** 查询利率定价流程列表 */
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
listWorkflow(this.queryParams).then(response => {
|
const hasDateRange = Array.isArray(this.dateRange) && this.dateRange.length === 2
|
||||||
|
const query = {
|
||||||
|
...this.queryParams,
|
||||||
|
beginCreateTime: hasDateRange ? `${this.dateRange[0]} 00:00:00` : undefined,
|
||||||
|
endCreateTime: hasDateRange ? `${this.dateRange[1]} 23:59:59` : undefined
|
||||||
|
}
|
||||||
|
listWorkflow(query).then(response => {
|
||||||
this.workflowList = response.rows
|
this.workflowList = response.rows
|
||||||
this.total = response.total
|
this.total = response.total
|
||||||
this.loading = false
|
this.loading = false
|
||||||
@@ -233,6 +281,7 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 重置按钮操作 */
|
/** 重置按钮操作 */
|
||||||
resetQuery() {
|
resetQuery() {
|
||||||
|
this.dateRange = []
|
||||||
this.resetForm("queryForm")
|
this.resetForm("queryForm")
|
||||||
this.handleQuery()
|
this.handleQuery()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ assert(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
!personalCreateDialog.includes('label="贷款用途"') &&
|
personalCreateDialog.includes('label="贷款用途"') &&
|
||||||
!personalCreateDialog.includes('prop="loanPurpose"') &&
|
personalCreateDialog.includes('prop="loanPurpose"') &&
|
||||||
!personalCreateDialog.includes('loanPurpose:'),
|
personalCreateDialog.includes('loanPurpose: undefined') &&
|
||||||
'个人新增弹窗不应继续保留贷款用途字段'
|
personalCreateDialog.includes('loanPurpose: this.editData.loanPurpose') &&
|
||||||
|
personalCreateDialog.includes('请选择贷款用途'),
|
||||||
|
'个人新增弹窗缺少贷款用途、必填校验或编辑回显'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@@ -31,8 +33,9 @@ assert(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
!personalCreateDialog.includes("value=\"consumer\"") && !personalCreateDialog.includes("value=\"business\""),
|
personalCreateDialog.includes('label="经营" value="business"') &&
|
||||||
'个人新增弹窗不应继续保留贷款用途选项'
|
personalCreateDialog.includes('label="消费" value="consumer"'),
|
||||||
|
'个人新增弹窗贷款用途选项或协议值不正确'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@@ -52,25 +55,49 @@ assert(
|
|||||||
|
|
||||||
assert(
|
assert(
|
||||||
personalCreateDialog.includes('collateralTypeOptions') &&
|
personalCreateDialog.includes('collateralTypeOptions') &&
|
||||||
personalCreateDialog.includes("return ['一线', '一类', '二类', '三类']") &&
|
|
||||||
personalCreateDialog.includes("return ['存单质押', '其他质押']"),
|
personalCreateDialog.includes("return ['存单质押', '其他质押']"),
|
||||||
'个人新增弹窗抵质押类型选项未按担保方式动态切换'
|
'个人新增弹窗应保留质押类型选项'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
personalCreateDialog.includes('{required: true, message: "请选择抵质押类型", trigger: "change"}'),
|
personalCreateDialog.includes('label="抵押物性质"') &&
|
||||||
'个人新增弹窗抵质押类型应为必填'
|
personalCreateDialog.includes('prop="collateralNature"') &&
|
||||||
|
personalCreateDialog.includes("return ['普通住宅、土地、厂房', '商业性质不动产', '其他抵押财产']") &&
|
||||||
|
personalCreateDialog.includes('label="是否属于九地"') &&
|
||||||
|
personalCreateDialog.includes('九地是指绍兴、杭州、宁波、上海、北京、广州、深圳、南京、苏州') &&
|
||||||
|
personalCreateDialog.includes(':disabled="!requiresNineArea"') &&
|
||||||
|
personalCreateDialog.includes("'无需选择'"),
|
||||||
|
'个人新增弹窗缺少抵押物性质、九地选择或九地说明'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
!personalCreateDialog.includes('label="是否有经营佐证"') &&
|
personalCreateDialog.includes("return this.form.isNineArea === '是' ? '一类' : '二类'") &&
|
||||||
!personalCreateDialog.includes('prop="bizProof"') &&
|
personalCreateDialog.includes("return this.form.isNineArea === '是' ? '二类' : '三类'") &&
|
||||||
!personalCreateDialog.includes('bizProof:') &&
|
personalCreateDialog.includes("return '四类'"),
|
||||||
|
'个人新增弹窗抵押物类型映射不完整'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalCreateDialog.includes("if (this.isPledge && !value)") &&
|
||||||
|
personalCreateDialog.includes("if (this.isMortgage && !value)") &&
|
||||||
|
personalCreateDialog.includes("if (this.requiresNineArea && !value)"),
|
||||||
|
'个人新增弹窗缺少抵押和质押的条件校验'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalCreateDialog.includes('label="是否有营业执照"') &&
|
||||||
|
personalCreateDialog.includes('prop="bizProof"') &&
|
||||||
|
personalCreateDialog.includes('bizProof: false') &&
|
||||||
|
personalCreateDialog.includes('bizProof: this.isOne(this.editData.bizProof)') &&
|
||||||
|
personalCreateDialog.includes("bizProof: this.form.bizProof ? '1' : '0'") &&
|
||||||
personalCreateDialog.includes("loanLoop: this.form.loanLoop ? '1' : '0'") &&
|
personalCreateDialog.includes("loanLoop: this.form.loanLoop ? '1' : '0'") &&
|
||||||
personalCreateDialog.includes("data.collThirdParty = this.form.collThirdParty ? '1' : '0'") &&
|
personalCreateDialog.includes("data.collThirdParty = this.form.collThirdParty ? '1' : '0'") &&
|
||||||
|
personalCreateDialog.includes('data.collType = this.resolveMortgageCollateralType()') &&
|
||||||
|
personalCreateDialog.includes('collateralNature: this.editData.collateralNature') &&
|
||||||
|
personalCreateDialog.includes('isNineArea: this.editData.isNineArea') &&
|
||||||
personalCreateDialog.includes('delete data.collType') &&
|
personalCreateDialog.includes('delete data.collType') &&
|
||||||
personalCreateDialog.includes('delete data.collThirdParty'),
|
personalCreateDialog.includes('delete data.collThirdParty'),
|
||||||
'个人新增弹窗开关字段或非抵质押提交字段处理不正确'
|
'个人新增弹窗营业执照、抵押来源字段、开关字段或非抵质押提交字段处理不正确'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
@@ -78,6 +105,19 @@ assert(
|
|||||||
'个人详情页缺少贷款用途展示'
|
'个人详情页缺少贷款用途展示'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalDetail.includes('label="是否有营业执照"') && personalDetail.includes('detailData.bizProof'),
|
||||||
|
'个人详情页缺少营业执照展示'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalDetail.includes('label="抵押物性质"') &&
|
||||||
|
personalDetail.includes('detailData.collateralNature') &&
|
||||||
|
personalDetail.includes('label="是否属于九地"') &&
|
||||||
|
personalDetail.includes('detailData.isNineArea'),
|
||||||
|
'个人详情页缺少抵押物性质或九地展示'
|
||||||
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
personalDetail.includes("value === '1'") && personalDetail.includes("value === '0'"),
|
personalDetail.includes("value === '1'") && personalDetail.includes("value === '0'"),
|
||||||
'个人详情页布尔格式化未兼容 1/0'
|
'个人详情页布尔格式化未兼容 1/0'
|
||||||
|
|||||||
@@ -7,15 +7,22 @@ function read(relativePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
||||||
|
const summaryStart = personalDetail.indexOf('<el-card class="summary-card">')
|
||||||
|
const summaryEnd = personalDetail.indexOf('</el-card>', summaryStart)
|
||||||
|
const summaryCard = personalDetail.slice(summaryStart, summaryEnd)
|
||||||
|
|
||||||
|
assert(summaryStart !== -1 && summaryEnd !== -1, '个人流程详情缺少关键信息卡片')
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
/label="最终测算利率"/.test(personalDetail),
|
!/label="(?:基准利率|浮动BP|最终测算利率)"/.test(summaryCard),
|
||||||
'个人流程详情左侧缺少“最终测算利率”标签'
|
'个人流程详情关键信息不应展示基准利率、浮动BP或最终测算利率'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
/return this\.retailOutput\?\.finalCalculateRate \|\| '-'/.test(personalDetail),
|
/label="期限"/.test(summaryCard)
|
||||||
'个人流程详情没有使用 finalCalculateRate 展示最终测算利率'
|
&& /label="担保方式"/.test(summaryCard)
|
||||||
|
&& /label="产品最低利率下限"/.test(summaryCard),
|
||||||
|
'个人流程详情关键信息缺少期限、担保方式或产品最低利率下限'
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log('personal final calculate rate display assertions passed')
|
console.log('personal key information display assertions passed')
|
||||||
|
|||||||
@@ -9,18 +9,55 @@ function read(relativePath) {
|
|||||||
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
||||||
const modelOutput = read('src/views/loanPricing/workflow/components/ModelOutputDisplay.vue')
|
const modelOutput = read('src/views/loanPricing/workflow/components/ModelOutputDisplay.vue')
|
||||||
|
|
||||||
|
function extractCard(source, className) {
|
||||||
|
const start = source.indexOf(`<el-card class="${className}">`)
|
||||||
|
const end = source.indexOf('</el-card>', start)
|
||||||
|
assert(start !== -1 && end !== -1, `缺少卡片: ${className}`)
|
||||||
|
return source.slice(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
|
const summaryCard = extractCard(personalDetail, 'summary-card')
|
||||||
|
const detailCard = extractCard(personalDetail, 'detail-card')
|
||||||
|
const businessInfoStart = detailCard.indexOf('<h4 class="section-title">业务信息</h4>')
|
||||||
|
const basicInfo = detailCard.slice(0, businessInfoStart)
|
||||||
|
const businessInfo = detailCard.slice(businessInfoStart)
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
personalDetail.includes('label="借款期限"') && personalDetail.includes('detailData.loanTerm'),
|
!basicInfo.includes('label="借款期限"')
|
||||||
'个人详情页缺少借款期限展示'
|
&& businessInfo.includes('label="借款期限"')
|
||||||
|
&& businessInfo.includes('detailData.loanTerm'),
|
||||||
|
'个人详情页借款期限未展示在业务信息中'
|
||||||
|
)
|
||||||
|
|
||||||
|
;['期限', '担保方式', '产品最低利率下限'].forEach((label) => {
|
||||||
|
assert(summaryCard.includes(`label="${label}"`), `个人流程详情关键信息缺少字段: ${label}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
;['基准利率', '浮动BP', '最终测算利率'].forEach((label) => {
|
||||||
|
assert(!summaryCard.includes(`label="${label}"`), `个人流程详情关键信息不应展示字段: ${label}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalDetail.includes('formatRate(retailOutput && retailOutput.minRateProduct)'),
|
||||||
|
'个人流程详情关键信息未展示产品最低利率下限'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
personalDetail.includes(':guar-type="detailData.guarType"'),
|
||||||
|
'个人模型输出未使用流程担保方式控制抵押物行'
|
||||||
)
|
)
|
||||||
|
|
||||||
const requiredRetailFields = [
|
const requiredRetailFields = [
|
||||||
'retailOutput.greyBlackCust',
|
|
||||||
'retailOutput.loanRateHistory',
|
'retailOutput.loanRateHistory',
|
||||||
'retailOutput.minRateProduct',
|
|
||||||
'retailOutput.smoothRange',
|
'retailOutput.smoothRange',
|
||||||
'retailOutput.finalCalculateRate',
|
'retailOutput.finalCalculateRate',
|
||||||
'retailOutput.referenceRate'
|
'retailOutput.referenceRate',
|
||||||
|
'retailOutput.branchBp',
|
||||||
|
'retailOutput.bpLoanUse',
|
||||||
|
'retailOutput.midPerGasDdc',
|
||||||
|
'retailOutput.bpPrinOverdue',
|
||||||
|
'retailOutput.bpIinterestOverdue',
|
||||||
|
'retailOutput.bpCardOverdue'
|
||||||
]
|
]
|
||||||
|
|
||||||
requiredRetailFields.forEach((field) => {
|
requiredRetailFields.forEach((field) => {
|
||||||
@@ -28,9 +65,34 @@ requiredRetailFields.forEach((field) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
modelOutput.indexOf('label="灰黑名单客户"') > modelOutput.indexOf('<h4 class="section-title">基本信息</h4>')
|
modelOutput.includes("this.resultItem('营业执照', this.formatBoolean(this.retailOutput.bizProof))"),
|
||||||
&& modelOutput.indexOf('label="灰黑名单客户"') < modelOutput.indexOf('<h4 class="section-title">测算结果</h4>'),
|
'个人风险度缺少营业执照或 BP_贷款用途关联展示'
|
||||||
'灰黑名单客户未展示在个人模型输出基础信息中'
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
basicInfo.includes('label="灰名单客户"')
|
||||||
|
&& basicInfo.includes('retailOutput && retailOutput.greyCust')
|
||||||
|
&& basicInfo.includes('label="黑名单客户"')
|
||||||
|
&& basicInfo.includes('retailOutput && retailOutput.blackCust'),
|
||||||
|
'个人流程详情基本信息缺少灰名单客户或黑名单客户'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!modelOutput.includes("this.resultItem('灰名单客户', this.formatBoolean(this.retailOutput.greyCust))")
|
||||||
|
&& !modelOutput.includes("this.resultItem('黑名单客户', this.formatBoolean(this.retailOutput.blackCust))")
|
||||||
|
&& !modelOutput.includes("'BP_灰名单与逾期', this.retailOutput.bpGreyOverdue"),
|
||||||
|
'个人风险度不应继续展示灰黑客户或旧聚合BP'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!basicInfo.includes('label="基准利率"')
|
||||||
|
&& !basicInfo.includes('retailOutput && retailOutput.baseLoanRate'),
|
||||||
|
'个人流程详情基本信息不应展示基准利率'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert(
|
||||||
|
!detailCard.includes('label="运行模式"') && !modelOutput.includes('<h4 class="section-title">基本信息</h4>'),
|
||||||
|
'个人详情仍展示运行模式或模型输出基本信息'
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log('retail display fields assertions passed')
|
console.log('retail display fields assertions passed')
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ function read(relativePath) {
|
|||||||
return fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8')
|
return fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertModelOutputBeforeDetailCard(source, label) {
|
function assertDetailCardBeforeModelOutput(source, label) {
|
||||||
const modelOutputIndex = source.indexOf('<ModelOutputDisplay')
|
const modelOutputIndex = source.indexOf('<ModelOutputDisplay')
|
||||||
const detailCardIndex = source.indexOf('<el-card class="detail-card">')
|
const detailCardIndex = source.indexOf('<el-card class="detail-card">')
|
||||||
|
|
||||||
assert(modelOutputIndex !== -1, `${label} 缺少模型输出卡片`)
|
assert(modelOutputIndex !== -1, `${label} 缺少模型输出卡片`)
|
||||||
assert(detailCardIndex !== -1, `${label} 缺少流程详情卡片`)
|
assert(detailCardIndex !== -1, `${label} 缺少流程详情卡片`)
|
||||||
assert(
|
assert(
|
||||||
modelOutputIndex < detailCardIndex,
|
detailCardIndex < modelOutputIndex,
|
||||||
`${label} 的模型输出卡片应位于流程详情卡片上方`
|
`${label} 的流程详情卡片应位于模型输出卡片上方`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
const personalDetail = read('src/views/loanPricing/workflow/components/PersonalWorkflowDetail.vue')
|
||||||
const corporateDetail = read('src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue')
|
const corporateDetail = read('src/views/loanPricing/workflow/components/CorporateWorkflowDetail.vue')
|
||||||
|
|
||||||
assertModelOutputBeforeDetailCard(personalDetail, '个人流程详情')
|
assertDetailCardBeforeModelOutput(personalDetail, '个人流程详情')
|
||||||
assertModelOutputBeforeDetailCard(corporateDetail, '企业流程详情')
|
assertDetailCardBeforeModelOutput(corporateDetail, '企业流程详情')
|
||||||
|
|
||||||
console.log('workflow detail card order assertions passed')
|
console.log('workflow detail card order assertions passed')
|
||||||
|
|||||||
@@ -55,6 +55,23 @@ assert(source.includes('icon="el-icon-edit"') && source.includes('>编辑</el-bu
|
|||||||
assert(source.includes('v-if="canEdit(scope.row)"'), '流程列表编辑按钮应只对可编辑行显示')
|
assert(source.includes('v-if="canEdit(scope.row)"'), '流程列表编辑按钮应只对可编辑行显示')
|
||||||
assert(source.includes('row.createBy === this.currentCreateBy'), '流程列表应按创建者判断编辑按钮权限')
|
assert(source.includes('row.createBy === this.currentCreateBy'), '流程列表应按创建者判断编辑按钮权限')
|
||||||
assert(source.includes('getWorkflowEdit(row.serialNum)'), '编辑操作应先查询编辑数据')
|
assert(source.includes('getWorkflowEdit(row.serialNum)'), '编辑操作应先查询编辑数据')
|
||||||
|
assert(source.includes('v-model="queryParams.custType"'), '流程列表应包含客户类型筛选')
|
||||||
|
assert(source.includes('v-model="queryParams.guarType"'), '流程列表应包含担保方式筛选')
|
||||||
|
assert(source.includes('v-model="dateRange"'), '流程列表应包含创建时间范围筛选')
|
||||||
|
assert(source.includes('value-format="yyyy-MM-dd"'), '流程列表创建时间筛选应使用日期值')
|
||||||
|
assert(source.includes('beginCreateTime: hasDateRange ? `${this.dateRange[0]} 00:00:00` : undefined'), '流程列表应传递当天零点的顶层创建时间起始参数')
|
||||||
|
assert(source.includes('endCreateTime: hasDateRange ? `${this.dateRange[1]} 23:59:59` : undefined'), '流程列表应传递当天末秒的顶层创建时间结束参数')
|
||||||
|
assert(source.includes('label="机构号"') && source.includes('prop="deptId"'), '流程列表应展示机构号')
|
||||||
|
assert(source.indexOf('label="机构号"') > source.indexOf('label="创建者"'), '机构号列应位于创建者列之后')
|
||||||
|
assert.strictEqual((source.match(/v-if="showAllSearchItems"/g) || []).length, 5, '五个高级搜索项均应根据角色显示')
|
||||||
|
|
||||||
|
assert.strictEqual(component.computed.showAllSearchItems.call({
|
||||||
|
roles: ['common']
|
||||||
|
}), false, '客户经理只应展示客户信息搜索项')
|
||||||
|
|
||||||
|
assert.strictEqual(component.computed.showAllSearchItems.call({
|
||||||
|
roles: ['headAdmin']
|
||||||
|
}), true, '其他角色应展示全部搜索项')
|
||||||
|
|
||||||
let refreshCount = 0
|
let refreshCount = 0
|
||||||
component.activated.call({
|
component.activated.call({
|
||||||
|
|||||||
16
sql/20260814-production.sql
Normal file
16
sql/20260814-production.sql
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
-- 2026-08-14 production database changes
|
||||||
|
|
||||||
|
-- Personal model output fields
|
||||||
|
ALTER TABLE `model_retail_output_fields`
|
||||||
|
ADD COLUMN `black_cust` varchar(100) DEFAULT NULL COMMENT '黑名单客户' AFTER `grey_cust`,
|
||||||
|
ADD COLUMN `branch_bp` varchar(100) DEFAULT NULL COMMENT '行社下调BP' AFTER `reference_rate`;
|
||||||
|
|
||||||
|
-- Corporate model output fields
|
||||||
|
ALTER TABLE `model_corp_output_fields`
|
||||||
|
ADD COLUMN `black_cust` varchar(100) DEFAULT NULL COMMENT '黑名单客户' AFTER `grey_cust`,
|
||||||
|
ADD COLUMN `branch_bp` varchar(100) DEFAULT NULL COMMENT '行社下调BP' AFTER `reference_rate`;
|
||||||
|
|
||||||
|
-- Workflow collateral source fields
|
||||||
|
ALTER TABLE `loan_pricing_workflow`
|
||||||
|
ADD COLUMN `collateral_nature` varchar(50) DEFAULT NULL COMMENT '抵押物性质' AFTER `loan_loop`,
|
||||||
|
ADD COLUMN `is_nine_area` varchar(10) DEFAULT NULL COMMENT '是否属于九地: 是/否' AFTER `collateral_nature`;
|
||||||
5
sql/20260824-corporate-workflow-optimization.sql
Normal file
5
sql/20260824-corporate-workflow-optimization.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
-- 2026-08-24 corporate model output overdue BP fields
|
||||||
|
ALTER TABLE `model_corp_output_fields`
|
||||||
|
ADD COLUMN `bp_prin_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_本金逾期' AFTER `prin_overdue`,
|
||||||
|
ADD COLUMN `bp_iinterest_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_利息逾期' AFTER `interest_overdue`,
|
||||||
|
ADD COLUMN `bp_card_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_信用卡逾期' AFTER `card_overdue`;
|
||||||
5
sql/20260824-personal-workflow-optimization.sql
Normal file
5
sql/20260824-personal-workflow-optimization.sql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
-- 2026-08-24 personal model output overdue BP fields
|
||||||
|
ALTER TABLE `model_retail_output_fields`
|
||||||
|
ADD COLUMN `bp_prin_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_本金逾期' AFTER `prin_overdue`,
|
||||||
|
ADD COLUMN `bp_iinterest_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_利息逾期' AFTER `interest_overdue`,
|
||||||
|
ADD COLUMN `bp_card_overdue` varchar(100) DEFAULT NULL COMMENT 'BP_信用卡逾期' AFTER `card_overdue`;
|
||||||
Reference in New Issue
Block a user