Ver código fonte

feat:账款评级/评级动态

zhangwei 3 anos atrás
pai
commit
361fb13bc8

+ 35 - 0
src/main/java/com/winhc/repal/enums/Dict.java

@@ -82,4 +82,39 @@ public class Dict {
             return code;
         }
     }
+
+    /**
+     * 被告类型
+     */
+    public enum LitigantTypeEnum {
+        /**
+         * 报告类型
+         */
+        自然人("0"),企业("1"),自然人无关联("2");
+        private final String code;
+
+        LitigantTypeEnum(String code) {
+            this.code = code;
+        }
+
+        public String getCode() {
+            return code;
+        }
+    }
+
+    public enum RankStatusEnum {
+        /**
+         * 评分结果
+         */
+        待评分(0), 评分完成(1), 评分失败(3);
+        private final Integer code;
+
+        RankStatusEnum(Integer code) {
+            this.code = code;
+        }
+
+        public Integer getCode() {
+            return code;
+        }
+    }
 }

+ 24 - 0
src/main/java/com/winhc/repal/mq/MQConfig.java

@@ -0,0 +1,24 @@
+package com.winhc.repal.mq;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * mq配置
+ */
+@Data
+@Configuration
+@ConfigurationProperties(prefix = "ons")
+public class MQConfig {
+    // mq url
+    private String url;
+    private String accessKey;
+    private String secretKey;
+
+    private String messageTopic;
+
+    private String repalTopic;
+
+    private String repalConsumerId;
+}

+ 17 - 0
src/main/java/com/winhc/repal/mq/MQTag.java

@@ -0,0 +1,17 @@
+package com.winhc.repal.mq;
+
+/**
+ *
+ */
+public class MQTag {
+    public enum EnterpriseTag {
+        /**
+         * 企业查询服务
+         */
+        tag_enterprise,tag_receivables_notice
+    }
+
+    public enum BizTag {
+        tag_msg, tag_credit_score,tag_repal
+    }
+}

+ 52 - 0
src/main/java/com/winhc/repal/mq/bean/RiskScoreDataTransfer.java

@@ -0,0 +1,52 @@
+package com.winhc.repal.mq.bean;
+
+import com.winhc.repal.cloud.dto.DiagnosisDebtorDTO;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * @description: 智能风控请求数据的传输
+ * @author: yujie
+ * @date 2020.3.18 11:04
+ */
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class RiskScoreDataTransfer {
+
+    // 业务ID
+    private Long bizId;
+    // 报告类型:0资信的调查报告;1案件动态报告;2债权穿透报告;3债权监测报告;4律师匹配报告;5简易资信报告
+    private Integer reportType;
+    // 优先级 越低优先级越高
+    private int priority;
+
+    // 案件标的
+    private Double biaodiAmt;
+
+    // 结果数据主键ID
+    private String mId;
+
+
+    // 待评分的列表
+    private List<DiagnosisDebtorDTO> diagnosisDebtorDTOS;
+    /**
+     * 时候需要回调
+     */
+    private boolean requireCallback;
+
+    @ApiModelProperty(value = "ABCD")
+    private String grade;
+
+    @ApiModelProperty("诊断评分")
+    private Double score;
+
+    // 待评分(0), 评分完成(1), 评分失败(3)
+    private Integer status;
+}

+ 54 - 0
src/main/java/com/winhc/repal/mq/consumer/GradeConsumer.java

@@ -0,0 +1,54 @@
+package com.winhc.repal.mq.consumer;
+
+import com.aliyun.openservices.ons.api.Consumer;
+import com.aliyun.openservices.ons.api.ONSFactory;
+import com.aliyun.openservices.ons.api.PropertyKeyConst;
+import com.winhc.repal.mq.MQConfig;
+import com.winhc.repal.mq.MQTag;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Properties;
+
+/**
+ * @author Aaron
+ * @date 2020/12/14 11:41
+ * @description
+ */
+@Slf4j
+@Component
+public class GradeConsumer {
+    @Autowired
+    private MQConfig mqConfig;
+    @Autowired
+    private GradeListener gradeListener;
+
+    @PostConstruct
+    public void init() {
+        log.info("初始化队列bean begin");
+        new Thread(this::initConsumer).start();
+        log.info("初始化队列bean end");
+    }
+
+    private void initConsumer() {
+        log.info("开始初始化队列消费");
+        System.setProperty("rocketmq.client.log.loadconfig","false");
+        Properties consumerProperties = new Properties();
+        consumerProperties.setProperty(PropertyKeyConst.GROUP_ID, mqConfig.getRepalConsumerId());
+        consumerProperties.setProperty(PropertyKeyConst.AccessKey, mqConfig.getAccessKey());
+        consumerProperties.setProperty(PropertyKeyConst.SecretKey, mqConfig.getSecretKey());
+        consumerProperties.setProperty(PropertyKeyConst.ONSAddr, mqConfig.getUrl());
+        consumerProperties.setProperty(PropertyKeyConst.ConsumeThreadNums,"2");
+        consumerProperties.setProperty(PropertyKeyConst.ConsumeTimeout,"15");
+        try {
+            Consumer consumer = ONSFactory.createConsumer(consumerProperties);
+            consumer.subscribe(mqConfig.getRepalTopic(), MQTag.BizTag.tag_repal.name(), gradeListener);
+            consumer.start();
+            log.info("初始化队列消费完成");
+        } catch (Exception e) {
+            log.error("初始化失败", e);
+        }
+    }
+}

+ 39 - 0
src/main/java/com/winhc/repal/mq/consumer/GradeListener.java

@@ -0,0 +1,39 @@
+package com.winhc.repal.mq.consumer;
+
+import com.aliyun.openservices.ons.api.Action;
+import com.aliyun.openservices.ons.api.ConsumeContext;
+import com.aliyun.openservices.ons.api.Message;
+import com.aliyun.openservices.ons.api.MessageListener;
+import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
+import com.winhc.repal.mq.bean.RiskScoreDataTransfer;
+import com.winhc.repal.service.RepalBillDiagnosisService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+/**
+ * @author Aaron
+ * @date 2020/12/14 11:48
+ * @description
+ */
+@Slf4j
+@Service
+public class GradeListener implements MessageListener {
+    @Autowired
+    private RepalBillDiagnosisService repalBillDiagnosisService;
+
+    @Override
+    public Action consume(Message message, ConsumeContext consumeContext) {
+        try{
+            log.info(new Date() + "收到评分结果消息, Topic is:" + message.getTopic() + ", MsgId is:" + message.getMsgID());
+            RiskScoreDataTransfer transfer = JSON.parseObject(new String(message.getBody(), StandardCharsets.UTF_8), RiskScoreDataTransfer.class);
+            repalBillDiagnosisService.updateGrade(transfer);
+        }catch (Throwable e){
+            log.error("消费评分结果出错",e);
+        }
+        return Action.CommitMessage;
+    }
+}

+ 15 - 1
src/main/java/com/winhc/repal/service/RepalBillDiagnosisService.java

@@ -2,6 +2,10 @@ package com.winhc.repal.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.winhc.repal.entity.RepalBillDiagnosis;
+import com.winhc.repal.mq.bean.RiskScoreDataTransfer;
+
+import java.math.BigDecimal;
+import java.util.List;
 
 
 /**
@@ -10,5 +14,15 @@ import com.winhc.repal.entity.RepalBillDiagnosis;
  * @date 2022-04-14
  */
 public interface RepalBillDiagnosisService extends IService<RepalBillDiagnosis> {
-
+    /**
+     * 新生成评估记录并提交评估
+     * @param repalBillId
+     */
+    RepalBillDiagnosis addRepalBillDiagnosis(Long userId, Long repalBillId, BigDecimal amt, List<String> companys);
+    /**
+     * 更新评估结果
+     * 1、评分表   2、账款表 本次以及历史 3、账本表 刷新状态
+     * @param transfer
+     */
+    void updateGrade(RiskScoreDataTransfer transfer);
 }

+ 8 - 0
src/main/java/com/winhc/repal/service/RepalBillService.java

@@ -88,4 +88,12 @@ public interface RepalBillService extends IService<RepalBill> {
      * @date 2022/4/18 12:12
      */
     Boolean deleteRepalBillByBookId(Long repalBookId);
+
+    /**
+     * 检查是否一个账本下除了自己外所有账款都刷新完成
+     *
+     * @param repalBookId
+     * @return
+     */
+    boolean checkAllBillRefreshStatus(Long repalBookId, Long repalBillId);
 }

+ 10 - 0
src/main/java/com/winhc/repal/service/RepalRemindHistoryService.java

@@ -1,5 +1,7 @@
 package com.winhc.repal.service;
 
+import com.winhc.repal.entity.RepalBill;
+import com.winhc.repal.entity.RepalBillDiagnosis;
 import com.winhc.repal.entity.RepalRemindHistory;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.winhc.repal.model.vo.RepalBillRemindUnReadVO;
@@ -19,4 +21,12 @@ public interface RepalRemindHistoryService extends IService<RepalRemindHistory>
      * @return
      */
     RepalBillRemindUnReadVO getRemindUnReadVO(List<Long> repalBillIds);
+
+    /**
+     * 新增评级提醒
+     * @param accountBill
+     * @param diagnosis
+     * @return
+     */
+    boolean insertRankRemind(RepalBill accountBill, RepalBillDiagnosis diagnosis);
 }

+ 171 - 0
src/main/java/com/winhc/repal/service/impl/RepalBillDiagnosisServiceImpl.java

@@ -1,17 +1,188 @@
 package com.winhc.repal.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.winhc.common.base.ApiDataResult;
+import com.winhc.repal.cloud.InCaseService;
+import com.winhc.repal.cloud.dto.AddDiagnoseRecordDTO;
+import com.winhc.repal.cloud.dto.DiagnosisDebtorDTO;
+import com.winhc.repal.cloud.vo.DiagnosisRecord;
+import com.winhc.repal.entity.RepalBill;
 import com.winhc.repal.entity.RepalBillDiagnosis;
+import com.winhc.repal.entity.RepalBook;
+import com.winhc.repal.enums.DiagnosisStatusEnum;
+import com.winhc.repal.enums.Dict;
+import com.winhc.repal.enums.RefreshStatusEnum;
+import com.winhc.repal.mq.bean.RiskScoreDataTransfer;
 import com.winhc.repal.repository.RepalBillDiagnosisMapper;
 import com.winhc.repal.service.RepalBillDiagnosisService;
+import com.winhc.repal.service.RepalBillService;
+import com.winhc.repal.service.RepalBookService;
+import com.winhc.repal.service.RepalRemindHistoryService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
 /**
  * @description RepalBillDiagnosis 接口实现类
  * @author Generator
  * @date 2022-04-14
  */
 @Service
+@Slf4j
 public class RepalBillDiagnosisServiceImpl extends ServiceImpl<RepalBillDiagnosisMapper, RepalBillDiagnosis> implements RepalBillDiagnosisService {
+    @Autowired
+    private InCaseService inCaseService;
+    @Autowired
+    private RepalBillService repalBillService;
+    @Autowired
+    private RepalBookService repalBookService;
+    @Autowired
+    private RepalRemindHistoryService repalRemindHistoryService;
+
+    private static String DIAGNOSIS_PREFIX = "REPAL_";
+
+    @Override
+    public RepalBillDiagnosis addRepalBillDiagnosis(Long userId, Long repalBillId, BigDecimal amt, List<String> companys) {
+        LocalDateTime now = LocalDateTime.now();
+        RepalBillDiagnosis diagnosis = new RepalBillDiagnosis();
+        diagnosis.setRepalBillId(repalBillId).setTimeCreated(now).setTimeModified(now).setDiagnosisDatetime(now)
+                .setDiagnosisStatus(DiagnosisStatusEnum.DIAGNOSIS_ING.getCode());
+        save(diagnosis);
+
+        List<DiagnosisDebtorDTO> diagnosisDebtorDTOS = companys.stream().map(this::convertDebtor).collect(Collectors.toList());
+        AddDiagnoseRecordDTO addDiagnoseRecordDTO = new AddDiagnoseRecordDTO();
+        addDiagnoseRecordDTO.setCreditorName(DIAGNOSIS_PREFIX+diagnosis.getId());
+        addDiagnoseRecordDTO.setDebtorName(StringUtils.join(companys,"、"));
+        addDiagnoseRecordDTO.setDebtorDTOList(diagnosisDebtorDTOS);
+        addDiagnoseRecordDTO.setCaseAmt(amt.doubleValue());
+        addDiagnoseRecordDTO.setRiskMode(0);
+        addDiagnoseRecordDTO.setUserId(userId);
+        addDiagnoseRecordDTO.setDiagnosisType(1);
+        ApiDataResult<DiagnosisRecord> result =  inCaseService.performanceAssessment(addDiagnoseRecordDTO);
+        if(result.getData() !=null){
+            DiagnosisRecord record = result.getData();
+            diagnosis.setBizId(record.getDiagnosisId());
+            updateById(diagnosis);
+            if(record.getStatus() == 1) {
+                RiskScoreDataTransfer transfer = new RiskScoreDataTransfer();
+                transfer.setBizId(record.getDiagnosisId());
+                transfer.setStatus(record.getStatus());
+                transfer.setGrade(record.getGrade());
+                transfer.setScore(record.getScore().doubleValue());
+                updateGrade(transfer);
+            }
+        }else {
+            RepalBill accountBill = repalBillService.getById(repalBillId);
+            RepalBook accountBook = repalBookService.getById(accountBill.getRepalBookId());
+            diagnosis.setDiagnosisStatus(DiagnosisStatusEnum.DIAGNOSIS_FAIL.getCode()).setTimeModified(now);
+            accountBill.setRefreshStatus(RefreshStatusEnum.REFRESH_FAIL.getCode()).setTimeModified(now);
+            accountBook.setRefreshStatus(RefreshStatusEnum.REFRESH_FAIL.getCode()).setTimeModified(now);
+            repalBillService.updateById(accountBill);
+            repalBookService.updateById(accountBook);
+        }
+        return diagnosis;
+    }
+
+    @Override
+    public void updateGrade(RiskScoreDataTransfer transfer) {
+        LocalDateTime now = LocalDateTime.now();
+        Long id = transfer.getBizId();
+        LambdaQueryWrapper<RepalBillDiagnosis> queryWrapper = Wrappers.lambdaQuery(RepalBillDiagnosis.class);
+        queryWrapper.eq(RepalBillDiagnosis::getBizId,id);
+        queryWrapper.isNull(RepalBillDiagnosis::getDiagnosisGrade);
+        List<RepalBillDiagnosis> results = list(queryWrapper);
+        if(CollUtil.isEmpty(results)){
+            log.error("查询不到评分记录,id={}",id);
+            return;
+        }
+        results.forEach(result->{
+            Long repalBillId = result.getRepalBillId();
+            RepalBill accountBill = repalBillService.getById(repalBillId);
+            if(accountBill == null){
+                log.error("查询不到账款记录,accountBillId={}",repalBillId);
+                return;
+            }
+            Long repalBookId = accountBill.getRepalBookId();
+            RepalBook accountBook = repalBookService.getById(repalBookId);
+            if(accountBook == null){
+                log.error("查询不到账本记录,accountBookId={}",repalBookId);
+                return;
+            }
+            if(Dict.RankStatusEnum.评分失败.getCode().equals(transfer.getStatus())){
+                result.setDiagnosisStatus(DiagnosisStatusEnum.DIAGNOSIS_FAIL.getCode()).setTimeModified(now);
+                accountBill.setRefreshStatus(RefreshStatusEnum.REFRESH_FAIL.getCode()).setTimeModified(now);
+                accountBook.setRefreshStatus(RefreshStatusEnum.REFRESH_FAIL.getCode()).setTimeModified(now);
+            }else {
+                result.setDiagnosisStatus(DiagnosisStatusEnum.DIAGNOSIS_SUCCESS.getCode())
+                        .setTimeModified(now)
+                        .setDiagnosisGrade(transfer.getGrade())
+                        .setDiagnosisScore(BigDecimal.valueOf(transfer.getScore()))
+                        .setDiagnosisDetail(JSON.toJSONString(transfer));
+                //更新账款
+                boolean isChangePre = setGrade(result,accountBill);
+                //更新账本状态
+                if(repalBillService.checkAllBillRefreshStatus(repalBookId,repalBillId)){
+                    accountBook.setRefreshStatus(RefreshStatusEnum.REFRESH_SUCCESS.getCode());
+                }
+                //评级变更智能提醒,如果分数有变化的话
+                if(isChangePre) {
+                    log.info("开始新增分数变更智能提醒");
+                    repalRemindHistoryService.insertRankRemind(accountBill, result);
+                }
+            }
+            updateById(result);
+            repalBillService.updateById(accountBill);
+            repalBookService.updateById(accountBook);
+        });
+        log.info("完成更新账款状态");
+    }
+
+    private boolean setGrade(RepalBillDiagnosis result,RepalBill repalBill){
+        boolean isChangePre = false;
+        LambdaQueryWrapper<RepalBillDiagnosis> qw = Wrappers.lambdaQuery(RepalBillDiagnosis.class);
+        qw.eq(RepalBillDiagnosis::getRepalBillId,repalBill.getId());
+        qw.lt(RepalBillDiagnosis::getTimeCreated,result.getTimeCreated());
+        qw.orderByDesc(RepalBillDiagnosis::getId);
+        RepalBillDiagnosis lastDiagnosis = getOne(qw,false);
+        if(lastDiagnosis !=null && lastDiagnosis.getDiagnosisScore().compareTo(result.getDiagnosisScore()) !=0){
+            repalBill.setPreDiagnosisId(lastDiagnosis.getId());
+            repalBill.setPreDiagnosisGrade(lastDiagnosis.getDiagnosisGrade());
+            repalBill.setPreDiagnosisDatetime(lastDiagnosis.getDiagnosisDatetime());
+            repalBill.setPreDiagnosisScore(lastDiagnosis.getDiagnosisScore());
+            int trend = result.getDiagnosisScore().compareTo(lastDiagnosis.getDiagnosisScore());
+            trend = trend < 0 ? 2: trend;
+            repalBill.setDiagnosisTrend(trend);
+            isChangePre=true;
+        }
+        repalBill.setDiagnosisId(result.getId());
+        repalBill.setDiagnosisGrade(result.getDiagnosisGrade());
+        repalBill.setDiagnosisScore(result.getDiagnosisScore());
+        repalBill.setDiagnosisDatetime(result.getDiagnosisDatetime());
+        repalBill.setRefreshStatus(RefreshStatusEnum.REFRESH_SUCCESS.getCode());
+        repalBill.setTimeModified(LocalDateTime.now());
+        return isChangePre;
+    }
 
+    /**
+     * 生成评估对象
+     * @param companyName
+     * @return
+     */
+    private DiagnosisDebtorDTO convertDebtor(String companyName){
+        DiagnosisDebtorDTO debtorDTO = new DiagnosisDebtorDTO();
+        debtorDTO.setLitigantType(Dict.LitigantTypeEnum.企业.getCode());
+        debtorDTO.setLitigantName(companyName);
+        return debtorDTO;
+    }
 }

+ 17 - 0
src/main/java/com/winhc/repal/service/impl/RepalBillServiceImpl.java

@@ -3,6 +3,8 @@ package com.winhc.repal.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -20,6 +22,7 @@ import com.winhc.repal.cloud.vo.FinanceDynamicNumVO;
 import com.winhc.repal.entity.*;
 import com.winhc.repal.enums.CustPropertyEnum;
 import com.winhc.repal.enums.DeletedStatusEnum;
+import com.winhc.repal.enums.RefreshStatusEnum;
 import com.winhc.repal.enums.RepalBillStatusEnum;
 import com.winhc.repal.model.dto.*;
 import com.winhc.repal.model.vo.RepalBillDetailVO;
@@ -309,4 +312,18 @@ public class RepalBillServiceImpl extends ServiceImpl<RepalBillMapper, RepalBill
         repalResponsiblePersonService.deletePersonByBookId(repalBookId);
         return true;
     }
+
+    @Override
+    public boolean checkAllBillRefreshStatus(Long repalBookId, Long repalBillId) {
+        LambdaQueryWrapper<RepalBill> qw = Wrappers.lambdaQuery(RepalBill.class);
+        qw.eq(RepalBill::getRepalBookId,repalBookId);
+        qw.ne(RepalBill::getId,repalBillId);
+        List<RepalBill> results = list(qw);
+        for(RepalBill accountBill:results){
+            if(!RefreshStatusEnum.REFRESH_SUCCESS.getCode().equals(accountBill.getRefreshStatus())){
+                return false;
+            }
+        }
+        return true;
+    }
 }

+ 114 - 1
src/main/java/com/winhc/repal/service/impl/RepalRemindHistoryServiceImpl.java

@@ -1,11 +1,19 @@
 package com.winhc.repal.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.winhc.repal.entity.RepalBill;
+import com.winhc.repal.entity.RepalBillDiagnosis;
+import com.winhc.repal.entity.RepalRemindDefinition;
 import com.winhc.repal.entity.RepalRemindHistory;
-import com.winhc.repal.enums.Dict;
+import com.winhc.repal.enums.*;
 import com.winhc.repal.model.vo.RemindTypeUnReadCountVO;
 import com.winhc.repal.model.vo.RepalBillRemindUnReadVO;
 import com.winhc.repal.repository.RepalRemindHistoryMapper;
+import com.winhc.repal.service.RepalRemindDefinitionService;
 import com.winhc.repal.service.RepalRemindHistoryService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.ibatis.annotations.Param;
@@ -20,7 +28,13 @@ import com.winhc.repal.model.dto.RepalRemindHistoryDTO;
 import com.winhc.repal.model.cvt.RepalRemindHistoryConvert;
 import com.winhc.repal.model.vo.RepalRemindHistoryVO;
 
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -32,6 +46,8 @@ import java.util.stream.Collectors;
 public class RepalRemindHistoryServiceImpl extends ServiceImpl<RepalRemindHistoryMapper, RepalRemindHistory> implements RepalRemindHistoryService {
     @Autowired
     private RepalRemindHistoryMapper repalRemindHistoryMapper;
+    @Autowired
+    private RepalRemindDefinitionService repalRemindDefinitionService;
 
     @Override
     public RepalBillRemindUnReadVO getRemindUnReadVO(List<Long> repalBillIds) {
@@ -58,4 +74,101 @@ public class RepalRemindHistoryServiceImpl extends ServiceImpl<RepalRemindHistor
         result.setUnreadTotalCount(unReadCounts.stream().mapToInt(RemindTypeUnReadCountVO::getCount).sum());
         return result;
     }
+
+    @Override
+    public boolean insertRankRemind(RepalBill repalBill, RepalBillDiagnosis diagnosis) {
+        if (repalBill.getRepalBillStage() == null) {
+            return true;
+        }
+        LocalDate endDate = repalBill.getEndDate();
+        if (endDate == null) {
+            endDate = LocalDate.now().minusDays(1);
+        }
+        OverdueEnum overdueEnum = getDaysBetween(endDate);
+        LambdaQueryWrapper<RepalRemindDefinition> qw = Wrappers.lambdaQuery(RepalRemindDefinition.class);
+        qw.eq(RepalRemindDefinition::getRemindType, Dict.RemindEnum.账款评级.name());
+        if (RepalBillStatusEnum.PROGRESSING.getCode().equals(repalBill.getRepalBillStatus())
+                || !RepalBillStageEnum.NON_PROSECUTE.getCode().equals(repalBill.getRepalBillStage())) {
+            qw.eq(RepalRemindDefinition::getOpportunity, diagnosis.getDiagnosisGrade());
+        } else {
+            qw.eq(RepalRemindDefinition::getOpportunity, diagnosis.getDiagnosisGrade() + "+" + overdueEnum.getCode());
+        }
+        qw.eq(RepalRemindDefinition::getRepalBillStatus, repalBill.getRepalBillStatus());
+        qw.eq(RepalRemindDefinition::getRepalBillStage, repalBill.getRepalBillStage());
+        RepalRemindDefinition accountRemindDefinition = repalRemindDefinitionService.getOne(qw, false);
+        if (accountRemindDefinition != null) {
+            String changeStr = "下降";
+            String changeStr1 = "下降";
+            if (repalBill.getDiagnosisScore().compareTo(repalBill.getPreDiagnosisScore() == null ? new BigDecimal(0)
+                    : repalBill.getPreDiagnosisScore()) > 0) {
+                changeStr = "上升";
+                changeStr1 = "提高";
+            }
+            RepalRemindHistory accountRemindHistory = new RepalRemindHistory();
+            accountRemindHistory.setUserId(repalBill.getUserId())
+                    .setRepalBookId(repalBill.getRepalBookId())
+                    .setRepalBillId(repalBill.getId())
+                    .setTrendId(diagnosis.getId().toString())
+                    .setTrendContent(repalBill.getPreDiagnosisId() != null ? repalBill.getPreDiagnosisId().toString() : null)
+                    .setRemindTime(LocalDateTime.now())
+                    .setCompanyName(repalBill.getCustomerName())
+                    .setRemindTitle(diagnosis.getDiagnosisGrade() + "(" + diagnosis.getDiagnosisScore().stripTrailingZeros().toPlainString() + "分)")
+                    .setRemindContent(StrUtil.format(accountRemindDefinition.getRemindContent(),
+                            changeStr,
+                            changeStr1,
+                            overdueEnum.name()))
+                    .setFunctionList(accountRemindDefinition.getFunctionList())
+                    .setRemindType(Dict.RemindEnum.账款评级.name())
+                    .setReadStatus(ReadStatusEnum.未读.getCode());
+            save(accountRemindHistory);
+//            //推送
+//            AccountRemindSettingVO accountRemindSetting = accountRemindSettingService.find(accountBill.getUserId());
+//            String redisKey = MESSAGE_PRIFIX + repalBill.getUserId() + "_" + Dict.RemindEnum.账款评级.name();
+//            if (Dict.REMIND_SETTING_ENUM.需要提醒.getCode().equals(accountRemindSetting.getRank()) &&
+//                    redisUtil.get(redisKey) == null && accountBill.getPreDiagnosisId() != null) {
+//                Map<String, String> paraMap = new HashMap<>();
+//                paraMap.put("company", repalBill.getAccountBillTitle());
+//                paraMap.put("pregrade", repalBill.getPreDiagnosisGrade());
+//                paraMap.put("prescore", repalBill.getPreDiagnosisScore().toPlainString());
+//                paraMap.put("change", changeStr);
+//                paraMap.put("grade", repalBill.getDiagnosisGrade());
+//                paraMap.put("score", repalBill.getDiagnosisScore().toPlainString());
+//                paraMap.put("change1", changeStr1);
+//                paraMap.put("wizardId", repalBill.getId().toString());
+//                paraMap.put("accountBookId", repalBill.getAccountBookId().toString());
+//                messageNoticeService.sendPushmsg(repalBill.getUserId(), Dict.MsgNameEnum.评级变动APP提醒, paraMap);
+//                messageNoticeService.sendSms(repalBill.getUserId(), Dict.MsgNameEnum.评级变动短信提醒, paraMap);
+//                redisUtil.setEx(redisKey, "done", calTTL(), TimeUnit.MILLISECONDS);
+//            }
+
+
+            //掐头去尾压进accountbill.remindInfo中
+            String remindContent = accountRemindHistory.getRemindContent();
+            if (remindContent.length() > 100) {
+                remindContent = remindContent.substring(0, 100);
+            }
+            accountRemindHistory.setFunctionList(null).setRemindContent(remindContent);
+            repalBill.setRemindInfo(JSON.toJSONString(accountRemindHistory));
+        }
+        return true;
+    }
+
+    private OverdueEnum getDaysBetween(LocalDate endDate) {
+        long delta = LocalDate.now().toEpochDay() - endDate.toEpochDay();
+        OverdueEnum overdueEnum = OverdueEnum.其他;
+        if (delta <= 0 && delta >= -7) {
+            overdueEnum = OverdueEnum.即将逾期;
+        } else if (delta > 0 && delta < 90) {
+            overdueEnum = OverdueEnum.已逾期;
+        } else if (delta >= 90 && delta < 180) {
+            overdueEnum = OverdueEnum.已逾期三个月;
+        } else if (delta >= 180 && delta < 365) {
+            overdueEnum = OverdueEnum.已逾期半年;
+        } else if (delta >= 365 && delta < 365 * 3) {
+            overdueEnum = OverdueEnum.已逾期一年;
+        } else if (delta >= 365 * 3) {
+            overdueEnum = OverdueEnum.已逾期三年;
+        }
+        return overdueEnum;
+    }
 }