✨ 客商评分提交校验、复评状态与空评分持久化
提交审批前必须完成且仅保留一条自评,审核通过前必须完成复评。 列表返回最新复评状态;删除最后一条评分会落库;评分为 0 时不再被当成空值覆盖。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+4
@@ -98,6 +98,10 @@ public class CustomerArchiveVO extends CustomerArchive {
|
|||||||
@Schema(description = "资金使用率(百分比)")
|
@Schema(description = "资金使用率(百分比)")
|
||||||
private BigDecimal fundUseRate;
|
private BigDecimal fundUseRate;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
@Schema(description = "评分复评状态")
|
||||||
|
private String reviewStatus;
|
||||||
|
|
||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
@Schema(description = "已付金额合计(元)")
|
@Schema(description = "已付金额合计(元)")
|
||||||
private BigDecimal usedFundLimit;
|
private BigDecimal usedFundLimit;
|
||||||
|
|||||||
+10
-1
@@ -46,6 +46,7 @@
|
|||||||
<result column="current_node" property="currentNode"/>
|
<result column="current_node" property="currentNode"/>
|
||||||
<result column="current_processor" property="currentProcessor"/>
|
<result column="current_processor" property="currentProcessor"/>
|
||||||
<result column="approved_time" property="approvedTime"/>
|
<result column="approved_time" property="approvedTime"/>
|
||||||
|
<result column="review_status" property="reviewStatus"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<select id="selectCustomerArchivePage" resultMap="customerArchiveResultMap">
|
<select id="selectCustomerArchivePage" resultMap="customerArchiveResultMap">
|
||||||
@@ -92,7 +93,15 @@
|
|||||||
approval_status,
|
approval_status,
|
||||||
current_node,
|
current_node,
|
||||||
current_processor,
|
current_processor,
|
||||||
approved_time
|
approved_time,
|
||||||
|
(
|
||||||
|
SELECT s.review_status
|
||||||
|
FROM blade_customer_credit_score s
|
||||||
|
WHERE s.customer_id = blade_customer_archive.id
|
||||||
|
AND (s.is_deleted = 0 OR s.is_deleted IS NULL)
|
||||||
|
ORDER BY s.score_date DESC, s.update_time DESC, s.id DESC
|
||||||
|
LIMIT 1
|
||||||
|
) AS review_status
|
||||||
FROM blade_customer_archive
|
FROM blade_customer_archive
|
||||||
WHERE is_deleted = 0
|
WHERE is_deleted = 0
|
||||||
<if test="userId != null">
|
<if test="userId != null">
|
||||||
|
|||||||
+25
-10
@@ -213,6 +213,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
CustomerArchiveVO detail = detail(id);
|
CustomerArchiveVO detail = detail(id);
|
||||||
prepare(detail);
|
prepare(detail);
|
||||||
validateBase(detail);
|
validateBase(detail);
|
||||||
|
validateScoreForApproval(detail);
|
||||||
validateApproval(detail);
|
validateApproval(detail);
|
||||||
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||||
CustomerArchive after = copyCustomer(before);
|
CustomerArchive after = copyCustomer(before);
|
||||||
@@ -323,6 +324,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
log.info("流程结束审核通过跳过,客商已是审核通过 id={}", id);
|
log.info("流程结束审核通过跳过,客商已是审核通过 id={}", id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
validateReviewCompleted(buildDetail(before));
|
||||||
CustomerArchive after = copyCustomer(before);
|
CustomerArchive after = copyCustomer(before);
|
||||||
after.setAccessType(ACCESS_FORMAL);
|
after.setAccessType(ACCESS_FORMAL);
|
||||||
after.setApprovalStatus(APPROVAL_APPROVED);
|
after.setApprovalStatus(APPROVAL_APPROVED);
|
||||||
@@ -383,6 +385,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
CustomerArchiveVO detail = detail(id);
|
CustomerArchiveVO detail = detail(id);
|
||||||
prepare(detail);
|
prepare(detail);
|
||||||
validateBase(detail);
|
validateBase(detail);
|
||||||
|
validateReviewCompleted(detail);
|
||||||
// 临时客商审核通过时由流程转为正式客商,不要求补齐正式客商材料。
|
// 临时客商审核通过时由流程转为正式客商,不要求补齐正式客商材料。
|
||||||
validateApproval(detail, Objects.equals(detail.getAccessType(), ACCESS_TEMPORARY));
|
validateApproval(detail, Objects.equals(detail.getAccessType(), ACCESS_TEMPORARY));
|
||||||
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
CustomerArchive before = Objects.requireNonNull(BeanUtil.copyProperties(detail, CustomerArchive.class));
|
||||||
@@ -556,16 +559,30 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
validateApproval(customer, false);
|
validateApproval(customer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateReviewCompleted(CustomerArchiveVO customer) {
|
||||||
|
List<CustomerCreditScoreVO> scores = customer.getScores() == null ? List.of() : customer.getScores();
|
||||||
|
boolean reviewCompleted = scores.size() == 1 && "已完成".equals(scores.get(0).getReviewStatus());
|
||||||
|
if (!reviewCompleted) {
|
||||||
|
throw new ServiceException("请先完成复评");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateScoreForApproval(CustomerArchiveVO customer) {
|
||||||
|
List<CustomerCreditScoreVO> scores = customer.getScores() == null ? List.of() : customer.getScores();
|
||||||
|
if (scores.size() > 1) {
|
||||||
|
throw new ServiceException("评分记录只能有一条");
|
||||||
|
}
|
||||||
|
boolean selfCompleted = scores.size() == 1 && "已完成".equals(scores.get(0).getSelfStatus());
|
||||||
|
if (!selfCompleted) {
|
||||||
|
throw new ServiceException("提交审批前必须完成自评");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void validateApproval(CustomerArchiveVO customer, boolean temporaryToFormal) {
|
private void validateApproval(CustomerArchiveVO customer, boolean temporaryToFormal) {
|
||||||
if (Objects.equals(customer.getAccessType(), ACCESS_FORMAL) && !temporaryToFormal) {
|
if (Objects.equals(customer.getAccessType(), ACCESS_FORMAL) && !temporaryToFormal) {
|
||||||
if (Func.isEmpty(customer.getQualificationAttachments())) {
|
if (Func.isEmpty(customer.getQualificationAttachments())) {
|
||||||
throw new ServiceException("正式客商提交审核前必须上传客商材料");
|
throw new ServiceException("正式客商提交审核前必须上传客商材料");
|
||||||
}
|
}
|
||||||
boolean hasCompletedScore = customer.getScores().stream()
|
|
||||||
.anyMatch(score -> "已完成".equals(score.getSelfStatus()) || "已完成".equals(score.getReviewStatus()) || Func.isNotEmpty(score.getFinalScore()));
|
|
||||||
if (!hasCompletedScore) {
|
|
||||||
throw new ServiceException("正式客商提交审核前必须完成信用评分");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,10 +614,8 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
insertContacts(customerId, customer.getContacts());
|
insertContacts(customerId, customer.getContacts());
|
||||||
insertReceiptAccounts(customerId, customer.getReceiptAccounts());
|
insertReceiptAccounts(customerId, customer.getReceiptAccounts());
|
||||||
insertInvoices(customerId, customer);
|
insertInvoices(customerId, customer);
|
||||||
if (Func.isNotEmpty(customer.getScores())) {
|
deleteScores(List.of(customerId));
|
||||||
deleteScores(List.of(customerId));
|
insertScores(customerId, customer.getScores());
|
||||||
insertScores(customerId, customer.getScores());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertContacts(Long customerId, List<CustomerContactVO> contacts) {
|
private void insertContacts(Long customerId, List<CustomerContactVO> contacts) {
|
||||||
@@ -774,7 +789,7 @@ public class CustomerArchiveServiceImpl extends BaseServiceImpl<CustomerArchiveM
|
|||||||
}
|
}
|
||||||
for (int detailIndex = 0; detailIndex < details.size(); detailIndex++) {
|
for (int detailIndex = 0; detailIndex < details.size(); detailIndex++) {
|
||||||
CustomerCreditScoreDetailVO detailVO = details.get(detailIndex);
|
CustomerCreditScoreDetailVO detailVO = details.get(detailIndex);
|
||||||
if (Func.isEmpty(detailVO.getScore())) {
|
if (detailVO.getScore() == null) {
|
||||||
detailVO.setScore(resolveFullScore(detailVO.getOptionsJson()));
|
detailVO.setScore(resolveFullScore(detailVO.getOptionsJson()));
|
||||||
}
|
}
|
||||||
CustomerCreditScoreDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(detailVO, CustomerCreditScoreDetail.class));
|
CustomerCreditScoreDetail detail = Objects.requireNonNull(BeanUtil.copyProperties(detailVO, CustomerCreditScoreDetail.class));
|
||||||
|
|||||||
Reference in New Issue
Block a user