Browse Source

2026/1/10 修改出款、合同

25057 3 months ago
parent
commit
99998bfd57
52 changed files with 926 additions and 327 deletions
  1. 5 5
      pom.xml
  2. 18 18
      src/main/java/com/loan/system/controller/admin/DetailsController.java
  3. 0 1
      src/main/java/com/loan/system/controller/wechat/DisbursementController.java
  4. 18 8
      src/main/java/com/loan/system/controller/wechat/RepaymentController.java
  5. 0 33
      src/main/java/com/loan/system/controller/wechat/test.java
  6. 24 0
      src/main/java/com/loan/system/domain/dto/ContractBankInfoDTO.java
  7. 5 3
      src/main/java/com/loan/system/domain/dto/ContractDTO.java
  8. 1 0
      src/main/java/com/loan/system/domain/dto/DisburseBankInfoDTO.java
  9. 1 0
      src/main/java/com/loan/system/domain/dto/DisbursementRecordDTO.java
  10. 1 0
      src/main/java/com/loan/system/domain/dto/RepaymentRecordDTO.java
  11. 12 13
      src/main/java/com/loan/system/domain/entity/Contract.java
  12. 61 0
      src/main/java/com/loan/system/domain/entity/ContractBankInfo.java
  13. 3 0
      src/main/java/com/loan/system/domain/entity/DisburseBankInfo.java
  14. 3 0
      src/main/java/com/loan/system/domain/entity/PawnTicketInfo.java
  15. 3 0
      src/main/java/com/loan/system/domain/entity/RepaymentRecord.java
  16. 3 3
      src/main/java/com/loan/system/domain/enums/StepPropertyEnum.java
  17. 1 0
      src/main/java/com/loan/system/domain/pojo/DateAndAmountPOJO.java
  18. 26 0
      src/main/java/com/loan/system/domain/vo/ContractBankInfoVO.java
  19. 21 0
      src/main/java/com/loan/system/domain/vo/ContractCompleteVO.java
  20. 9 4
      src/main/java/com/loan/system/domain/vo/ContractVO.java
  21. 1 0
      src/main/java/com/loan/system/domain/vo/DisburseBankInfoVO.java
  22. 6 2
      src/main/java/com/loan/system/domain/vo/DisbursementDetailVO.java
  23. 1 1
      src/main/java/com/loan/system/domain/vo/LoanCaseCompleteVO.java
  24. 1 0
      src/main/java/com/loan/system/domain/vo/RepaymentDetailVO.java
  25. 1 0
      src/main/java/com/loan/system/domain/vo/RepaymentRecordVO.java
  26. 41 0
      src/main/java/com/loan/system/repository/ContractBankInfoRepository.java
  27. 5 0
      src/main/java/com/loan/system/repository/ContractRepaymentRepository.java
  28. 14 8
      src/main/java/com/loan/system/repository/ContractRepository.java
  29. 1 0
      src/main/java/com/loan/system/repository/LoanRepository.java
  30. 1 1
      src/main/java/com/loan/system/repository/PawnTicketRepository.java
  31. 1 0
      src/main/java/com/loan/system/repository/RepaymentRecordRepository.java
  32. 4 0
      src/main/java/com/loan/system/repository/StepRepository.java
  33. 25 0
      src/main/java/com/loan/system/service/ContractBankInfoService.java
  34. 1 1
      src/main/java/com/loan/system/service/ContractDisbursementService.java
  35. 2 0
      src/main/java/com/loan/system/service/ContractRepaymentService.java
  36. 5 1
      src/main/java/com/loan/system/service/ContractService.java
  37. 156 0
      src/main/java/com/loan/system/service/Impl/ContractBankInfoServiceImpl.java
  38. 2 1
      src/main/java/com/loan/system/service/Impl/ContractDisbursementServiceImpl.java
  39. 5 0
      src/main/java/com/loan/system/service/Impl/ContractRepaymentServiceImpl.java
  40. 75 15
      src/main/java/com/loan/system/service/Impl/ContractServiceImpl.java
  41. 78 32
      src/main/java/com/loan/system/service/Impl/DisbursementServiceImpl.java
  42. 104 72
      src/main/java/com/loan/system/service/Impl/LoanServiceImpl.java
  43. 2 0
      src/main/java/com/loan/system/service/Impl/LocationDatumServiceImpl.java
  44. 4 3
      src/main/java/com/loan/system/service/Impl/PawnTicketServiceImpl.java
  45. 117 55
      src/main/java/com/loan/system/service/Impl/RepaymentServiceImpl.java
  46. 9 8
      src/main/java/com/loan/system/service/Impl/StepServiceImpl.java
  47. 2 2
      src/main/java/com/loan/system/service/Impl/UserServiceImpl.java
  48. 2 2
      src/main/java/com/loan/system/service/PawnTicketService.java
  49. 1 0
      src/main/java/com/loan/system/service/RepaymentService.java
  50. 2 0
      src/main/java/com/loan/system/service/StepService.java
  51. 14 11
      src/main/java/com/loan/system/utils/EsignSdkUtil.java
  52. 28 24
      src/main/java/com/loan/system/utils/RedisData.java

+ 5 - 5
pom.xml

@@ -320,11 +320,11 @@
 <!--            <artifactId>esign-sdk-java</artifactId>-->
 <!--            <version>3.6.0</version>-->
 <!--        </dependency>-->
-        <dependency>
-            <groupId>esign-cn</groupId>
-            <artifactId>paas-sdk</artifactId>
-            <version>3.1.4</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>esign-cn</groupId>-->
+<!--            <artifactId>paas-sdk</artifactId>-->
+<!--            <version>3.1.4</version>-->
+<!--        </dependency>-->
         <!--
         备用方案:如果Maven仓库无法访问,取消下面注释并注释上面的依赖
         <dependency>

+ 18 - 18
src/main/java/com/loan/system/controller/admin/DetailsController.java

@@ -87,12 +87,12 @@ public class DetailsController {
                     LoanCaseDetails loanCaseDetail = new LoanCaseDetails();
 
                     loanCaseDetail.setContractNo(contract.getContractNo());//1
-                    PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractId);
-                    if(pawnTicketInfo!=null){
-                        loanCaseDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
-                        loanCaseDetail.setRedeemTime(pawnTicketInfo.getEndTime());//16.
-                        loanCaseDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//17.
-                    }
+//                    PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractId);
+//                    if(pawnTicketInfo!=null){
+//                        loanCaseDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
+//                        loanCaseDetail.setRedeemTime(pawnTicketInfo.getEndTime());//16.
+//                        loanCaseDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//17.
+//                    }
                     loanCaseDetail.setLoanTime(disbursementService.getLoanTime(caseId));//3.
                     loanCaseDetail.setCustomerName(customer.getName());//4.
                     loanCaseDetail.setCustomerName2(customersOtherVOS.get(0).getName());//5.
@@ -207,13 +207,13 @@ public class DetailsController {
             DisbursementDetails disbursementDetail = new DisbursementDetails();
 
             disbursementDetail.setContractNo(contractVO.getContractNo());//1.
-            PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractVO.getId());
-            if(pawnTicketInfo!=null){
-                disbursementDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
-                disbursementDetail.setRedeemTime(pawnTicketInfo.getEndTime());//9.
-                disbursementDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//10.
-            }
-            disbursementDetail.setLoanTime(disbursementService.getLoanTime(caseId));//3.
+//            PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractVO.getId());
+//            if(pawnTicketInfo!=null){
+//                disbursementDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
+//                disbursementDetail.setRedeemTime(pawnTicketInfo.getEndTime());//9.
+//                disbursementDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//10.
+//            }
+//            disbursementDetail.setLoanTime(disbursementService.getLoanTime(caseId));//3.
 
             disbursementDetail.setCustomerName(customerService.findByCustomerIdAndIsDelete(loanCase.getCustomerId(), false).getName());//4.
             disbursementDetail.setPawnAmount(contractVO.getContractAmount());//5.
@@ -308,11 +308,11 @@ public class DetailsController {
                     RepaymentDetails repaymentDetail = new RepaymentDetails();
 
                     repaymentDetail.setContractNo(contract.getContractNo());//1
-                    PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractId);
-                    if(pawnTicketInfo!=null){
-                        repaymentDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
-                        repaymentDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//10.
-                    }
+//                    PawnTicketInfo pawnTicketInfo = pawnTicketService.findByContractIdAndIsDelete(contractId);
+//                    if(pawnTicketInfo!=null){
+//                        repaymentDetail.setPawnTicketNo(pawnTicketInfo.getPawnTicketNo());//2.
+//                        repaymentDetail.setRedeemTicketNo(pawnTicketInfo.getRedeemTicketNo());//10.
+//                    }
                     repaymentDetail.setLoanTime(disbursementService.getLoanTime(caseId));//3.
                     repaymentDetail.setCustomerName(customer.getName());//4.
                     repaymentDetail.setPawnAmount(loanCase.getTotalLoanAmount());//5.

+ 0 - 1
src/main/java/com/loan/system/controller/wechat/DisbursementController.java

@@ -226,7 +226,6 @@ public class DisbursementController {
         if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
             throw new DescribeException(STEP_HAS_NOT_PROCESS);
 
-
         disbursementService.financeApproval(approvalRecordDTO,DecisionEnum.PASS.getMsg());
 
         return ResultUtil.success("success");

+ 18 - 8
src/main/java/com/loan/system/controller/wechat/RepaymentController.java

@@ -207,6 +207,24 @@ public class RepaymentController {
         return ResultUtil.success("success");
     }
 
+    @PostMapping("/autoRepay")
+    @ApiOperation(value = "主动回款")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
+    public Result AutoRepay(@RequestParam Long caseId, @RequestBody RepaymentRecordDTO repaymentRecordDTO) {
+        if (ObjectUtils.isEmpty(repaymentRecordDTO) || caseId == null)
+            throw new DescribeException(INPUT_ERROR);
+        if (!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepCodeAndCaseId(StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
+        if (ObjectUtils.isEmpty(stepVO) || !stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        repaymentService.autoRepay(repaymentRecordDTO, caseId);
+
+        return ResultUtil.success("success");
+    }
+
     /*
     客户名称、合同金额、剩余回款金额、本次回款金额、本次回款费息、本次回款本金及费息合计;
      */
@@ -241,14 +259,6 @@ public class RepaymentController {
         if (ObjectUtils.isEmpty(stepVO1) || !stepVO1.getStatus().equals(StepEnum.COMPLETED.getMsg()))
             throw new DescribeException(PRE_STEP_NOT_COMPLETE);
 
-        List<StepVO> steps = stepService.getStepByCaseId(caseId);
-        for (StepVO step : steps) {
-            if (!step.getParentCode().equals(stepVO.getParentCode()) || step.getCode().equals(StepPropertyEnum.CASE_COMPLETE.getCode()) || step.getCode().equals(stepVO.getCode()))
-                continue;
-            if (!step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
-                throw new DescribeException(STEP_EXIST_NOT_COMPLETE);
-        }
-
         repaymentService.repayComplete(caseId);
 
         return ResultUtil.success("success");

+ 0 - 33
src/main/java/com/loan/system/controller/wechat/test.java

@@ -1,33 +0,0 @@
-package com.loan.system.controller.wechat;
-
-import lombok.Data;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class test {
-    @Data
-    private class Record{
-        double total;//出款
-        double amount;//本次还款
-        double currentAmount;//还款
-    }
-    public static void main(String[] args) {
-        double totalAmount = 900;
-
-        List<Record> records = new ArrayList<>();
-        for (Record record : records){
-            double gap = record.total-record.currentAmount;
-
-            if(gap <= totalAmount){
-                record.amount = gap;
-                totalAmount -= gap;
-            }else{
-                record.amount = totalAmount;
-                totalAmount = 0.0;
-            }
-
-            //再小
-        }
-    }
-}

+ 24 - 0
src/main/java/com/loan/system/domain/dto/ContractBankInfoDTO.java

@@ -0,0 +1,24 @@
+package com.loan.system.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ContractBankInfoDTO implements Serializable {
+    private Long id;
+    private Long contractId;
+    private Long customerId;//客户id
+    private Double amount;
+    private String payee;
+    private String mobile;
+    private String disburseAccount;
+    private String disburseBank;
+    private Boolean isEntrust;
+    private Integer disburseCount;
+}

+ 5 - 3
src/main/java/com/loan/system/domain/dto/ContractDTO.java

@@ -8,6 +8,7 @@ import javax.persistence.Column;
 import javax.persistence.Lob;
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 @Data
 @AllArgsConstructor
@@ -17,15 +18,16 @@ public class ContractDTO implements Serializable {
     private String businessAttr;//业务属性
     private Long caseId;//业务id
     private Long customerId;//客户id
+    private String customerIds;
     private String contractNo;// 合同编号
     private String contractName;//合同名称
     private Double contractAmount;//借款金额
     private Double interestRate;//年利率
     private Integer loanPeriod;//借款期限
     private String content;//合同内容
-    private String bankName;
-    private String bankAccount;
-    private Double amountRate;
+    private ContractBankInfoDTO bankInfo;
+    private List<ContractBankInfoDTO> entrustBankInfos;
+    private Double amountRate;//当金利率
     private Double serviceCost;
     private Double loanRate;
 }

+ 1 - 0
src/main/java/com/loan/system/domain/dto/DisburseBankInfoDTO.java

@@ -16,4 +16,5 @@ public class DisburseBankInfoDTO implements Serializable {
     private String mobile;
     private String disburseAccount;
     private String disburseBank;
+    private Boolean isEntrust;
 }

+ 1 - 0
src/main/java/com/loan/system/domain/dto/DisbursementRecordDTO.java

@@ -25,6 +25,7 @@ public class DisbursementRecordDTO implements Serializable {
     private List<DisburseBankInfoDTO> disburseBankInfos;
     private String comment;
     private Map<Long,Double> contractIdAndAmount;//每个合同对应的出款金额
+    private Map<Long,Boolean> contractIdAndIsComplete;
     private String createTime;
     private String approvalIds;
     private String financeApprovalIds;

+ 1 - 0
src/main/java/com/loan/system/domain/dto/RepaymentRecordDTO.java

@@ -22,6 +22,7 @@ public class RepaymentRecordDTO implements Serializable {
     private Double amount;
     private LocationDatumDTO locationDatum;
     private String planTime;
+    private String planComment;
     private Long planUserId;
 
     //回款操作

+ 12 - 13
src/main/java/com/loan/system/domain/entity/Contract.java

@@ -23,21 +23,27 @@ public class Contract extends BaseEntity{
     @Column(name = "customer_id")
     private Long customerId;
 
+    @Column(name = "customer_id1")
+    private Long customerId1;
+
+    @Column(name = "customer_id2")
+    private Long customerId2;
+
     @Column(name = "contract_no", length = 50)
     private String contractNo;
 
     @Column(name = "contract_name", length = 50)
     private String contractName;
 
-    @Column(name = "contract_version")
-    private Integer contractVersion;
-
     @Column(name = "contract_amount", precision = 18, scale = 2)
     private Double contractAmount;
 
     @Column(name = "actual_amount", precision = 18, scale = 2)
     private Double actualAmount;
 
+    @Column(name = "is_disbursement_complete")
+    Boolean isDisbursementComplete;
+
     @Column(name = "interest_rate", precision = 5, scale = 4)
     private Double interestRate;//暂时没用
 
@@ -47,16 +53,15 @@ public class Contract extends BaseEntity{
     @Column(name = "cleared_status",length = 10)
     private String clearedStatus;
 
+    @Column(name = "cleared_time")
+    private String clearedTime;
+
     @Column(name = "loan_period")
     private Integer loanPeriod;
 
     @Column(name = "finance_user_id",length = 20)
     private Long financeUserId;
 
-    @Lob
-    @Column(name = "content")
-    private String content;
-
     @Column(name = "signed_by_customer")
     private Boolean signedByCustomer;
 
@@ -72,12 +77,6 @@ public class Contract extends BaseEntity{
     @Column(name = "is_push")
     private Boolean isPush;
 
-    @Column(name = "bank_name",length = 200)
-    private String bankName;
-
-    @Column(name = "bank_account" , length = 200)
-    private String bankAccount;
-
     @Column(name = "amount_rate")
     private Double amountRate;
 

+ 61 - 0
src/main/java/com/loan/system/domain/entity/ContractBankInfo.java

@@ -0,0 +1,61 @@
+package com.loan.system.domain.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.math.BigDecimal;
+import java.time.Instant;
+
+@Getter
+@Setter
+@Entity
+@Table(name = "contract_bank_info")
+public class ContractBankInfo extends BaseEntity {
+    private static final long serialVersionUID = 43L;
+    @NotNull
+    @Column(name = "contract_id", nullable = false)
+    private Long contractId;
+
+    @Column(name = "customer_id")
+    private Long customerId;
+
+    @Column(name = "amount", precision = 18, scale = 2)
+    private BigDecimal amount;
+
+    @Size(max = 50)
+    @Column(name = "payee", length = 50)
+    private String payee;
+
+    @Size(max = 11)
+    @Column(name = "mobile", length = 11)
+    private String mobile;
+
+    @Size(max = 30)
+    @Column(name = "disburse_account", length = 30)
+    private String disburseAccount;
+
+    @Size(max = 100)
+    @Column(name = "disburse_bank", length = 100)
+    private String disburseBank;
+
+    @Column(name = "is_entrust")
+    private Boolean isEntrust;
+
+    @Column(name = "disburse_count")
+    private Integer disburseCount;
+
+    @Column(name = "create_time")
+    private String createTime;
+
+    @Column(name = "update_time")
+    private String updateTime;
+
+    @Column(name = "is_delete")
+    private Boolean isDelete;
+
+}

+ 3 - 0
src/main/java/com/loan/system/domain/entity/DisburseBankInfo.java

@@ -38,6 +38,9 @@ public class DisburseBankInfo extends BaseEntity {
     @Column(name = "disburse_bank", length = 100)
     private String disburseBank;
 
+    @Column(name = "is_entrust")
+    private Boolean isEntrust;
+
     @Column(name = "create_time")
     private String createTime;
 

+ 3 - 0
src/main/java/com/loan/system/domain/entity/PawnTicketInfo.java

@@ -27,6 +27,9 @@ public class PawnTicketInfo extends BaseEntity{
     @Column(name = "pawn_ticket_no")
     private String pawnTicketNo;
 
+    @Column(name = "pawn_amount" , precision = 18, scale = 2)
+    private Double pawnAmount;
+
     @Column(name = "begin_time")
     private String beginTime;
 

+ 3 - 0
src/main/java/com/loan/system/domain/entity/RepaymentRecord.java

@@ -39,6 +39,9 @@ public class RepaymentRecord extends BaseEntity {
     @Column(name = "repay_location", length = 200)
     private String repayLocation;//计划地点
 
+    @Column(name = "plan_comment")
+    private String planComment;
+
     @Column(name = "plan_time")
     private String planTime;
 

+ 3 - 3
src/main/java/com/loan/system/domain/enums/StepPropertyEnum.java

@@ -37,7 +37,7 @@ public enum StepPropertyEnum {
     PLAN_AUDIT(553, "出帐派单", false),
     DISBURSE_START(554, "出帐操作", false),
     DISBURSE_AUDIT(555, "出帐审批", false),
-    FINANCE_DISBURSE(556, "财务复核", false),
+    FINANCE_DISBURSE(556, "财务出帐", false),
     DISBURSE_CONFIRM(557, "出帐确认", false),
 
     COLLATERAL_DELIVERY(561, "押品送证", true),
@@ -237,14 +237,14 @@ public enum StepPropertyEnum {
                 Arrays.asList(18),
                 Arrays.asList(19),
                 Arrays.asList(20),
-                Arrays.asList(26),
+                Arrays.asList(26, 29),
                 Arrays.asList(),//送证21
                 Arrays.asList(23),
                 Arrays.asList(24),
                 Arrays.asList(),
                 Arrays.asList(),//回款25
                 Arrays.asList(27),
-                Arrays.asList(28,29),
+                Arrays.asList(28),
                 Arrays.asList(30),
                 Arrays.asList(30),
                 Arrays.asList(31),

+ 1 - 0
src/main/java/com/loan/system/domain/pojo/DateAndAmountPOJO.java

@@ -6,4 +6,5 @@ import lombok.Data;
 public class DateAndAmountPOJO {
     private String date;
     private Double amount;
+    private String pawnTicketNo;
 }

+ 26 - 0
src/main/java/com/loan/system/domain/vo/ContractBankInfoVO.java

@@ -0,0 +1,26 @@
+package com.loan.system.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class ContractBankInfoVO implements Serializable {
+    private Long id;
+    private Long contractId;
+    private Long customerId;
+    private BigDecimal amount;
+    private String payee;
+    private String mobile;
+    private String disburseAccount;
+    private String disburseBank;
+    private Boolean isEntrust;
+    private Integer disburseCount;
+}

+ 21 - 0
src/main/java/com/loan/system/domain/vo/ContractCompleteVO.java

@@ -0,0 +1,21 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.PawnTicketInfo;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ContractCompleteVO {
+    private String contractNo;//对应的合同号
+    private List<PawnTicketInfo> pawnTicketNoList;//当票号、当票金额(万)、赎当号
+    private List<String> loanDateList;//借款日期
+    private Double repaymentTotalAmount;//前期总回款
+    private Double repaymentLastAmount;//最后一次回款
+    private Double interestAmount;// 费息金额(元)
+    private String clearedTime;// 结清日期,
+}

+ 9 - 4
src/main/java/com/loan/system/domain/vo/ContractVO.java

@@ -7,6 +7,7 @@ import lombok.NoArgsConstructor;
 import javax.persistence.Column;
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.List;
 
 @Data
 @AllArgsConstructor
@@ -15,24 +16,28 @@ public class ContractVO implements Serializable {
     private Long id;
     private String businessAttr;//业务属性
     private Long caseId;//业务id
-    private String customerName;
+    private CustomerVO customer;
+    private CustomerVO customer1;
+    private CustomerVO customer2;
+    private String customerNames;
     private String contractNo;// 合同编号
     private String contractName;//合同名称
     private Double contractAmount;//借款金额
     private Double actualAmount;//实际金额
+    private Boolean isDisbursementComplete;
     private Double interestRate;//年利率
     private Double interestAmount;
     private String clearedStatus;
+    private String clearedTime;
     private Integer loanPeriod;//借款期限
     private UserVO financeUser;
-    private String content;//合同内容
     private EsignFlowVO esignFlow;
     private Boolean signedByCustomer;//是否签署
     private Long signedId;//电子签名附件id
     private String commitedId;//承诺签名id
     private String signedTime;//签署实际
-    private String bankName;
-    private String bankAccount;
+    private ContractBankInfoVO bankInfo;
+    private List<ContractBankInfoVO> entrustBankInfos;
     private Double amountRate;
     private Double serviceCost;
     private Double loanRate;

+ 1 - 0
src/main/java/com/loan/system/domain/vo/DisburseBankInfoVO.java

@@ -17,4 +17,5 @@ public class DisburseBankInfoVO implements Serializable {
     private String mobile;
     private String disburseAccount;
     private String disburseBank;
+    private Boolean isEntrust;
 }

+ 6 - 2
src/main/java/com/loan/system/domain/vo/DisbursementDetailVO.java

@@ -23,6 +23,7 @@ public class DisbursementDetailVO implements Serializable {
     List<DisbursementVO> disbursementPlans;
 
     //出款启动+出款审批+财务复核
+    private List<ContractBankInfoVO> contractBankInfos;
     private List<DisbursementRecordVO> disbursementRecords;
     private String rejectComment2;
 
@@ -32,7 +33,10 @@ public class DisbursementDetailVO implements Serializable {
     private Map<Long,Double> contractAndCurrentAmount;//目前合同对应的出款金额
 
     private List<String> collateralStatus;//押品状态
-    private Double currentAmount;//目前金额
-    private Double totalAmount;//总金额
+    private Double currentPlanAmount;//已申报的金额
+    private Double currentPlanAmount1;//出账派单的申报金额
+    private Double currentAmount;//出账操作的目前金额
+    private Double currentAmount1;//目前金额
+    private Double totalAmount;//实际总金额
 
 }

+ 1 - 1
src/main/java/com/loan/system/domain/vo/LoanCaseCompleteVO.java

@@ -32,6 +32,6 @@ public class LoanCaseCompleteVO {
     private String caseUser1;// 业务主办、
     private String caseUser2;// 业务辅办
     private String clearedTime;//结清日期
-    private Map<String, PawnTicketInfo> contractAngPawnMap;//合同号:当票实体(pawnTicketNo,redeemTicketNo)
+    List<ContractCompleteVO> contractCompleteVOS;
     List<DocumentVO> documents;
 }

+ 1 - 0
src/main/java/com/loan/system/domain/vo/RepaymentDetailVO.java

@@ -26,6 +26,7 @@ public class RepaymentDetailVO implements Serializable {
     private Map<Long,Double> clearInterest;
     private Map<Long , List<DateAndAmountPOJO>> dateAndAmounts;
     private Double totalAmount;//业务回款总额
+    private Double actualTotalAmount;//实际回款总额
     private Double totalInterestAmount;//利息总额
     private Double currentAmount;//目前本金回款总额
     private Double currentInterestAmount;//目前利息回款总额

+ 1 - 0
src/main/java/com/loan/system/domain/vo/RepaymentRecordVO.java

@@ -28,6 +28,7 @@ public class RepaymentRecordVO implements Serializable {
     private String remitter;
     private String mobile;
     private Double amount;
+    private String planComment;
     private String planTime;
     private LocationDatum locationDatum;
 

+ 41 - 0
src/main/java/com/loan/system/repository/ContractBankInfoRepository.java

@@ -0,0 +1,41 @@
+package com.loan.system.repository;
+
+import com.loan.system.domain.entity.ContractBankInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 合同银行信息 Repository
+ */
+public interface ContractBankInfoRepository extends JpaRepository<ContractBankInfo, Long> {
+
+    List<ContractBankInfo> findByContractIdAndIsDelete(Long contractId, boolean isDelete);
+
+    @Modifying
+    @Transactional
+    @Query("UPDATE ContractBankInfo c SET " +
+           "c.amount = COALESCE(?2, c.amount), " +
+           "c.payee = COALESCE(?3, c.payee), " +
+           "c.mobile = COALESCE(?4, c.mobile), " +
+           "c.disburseAccount = COALESCE(?5, c.disburseAccount), " +
+           "c.disburseBank = COALESCE(?6, c.disburseBank), " +
+           "c.isEntrust = COALESCE(?7, c.isEntrust), " +
+           "c.disburseCount = COALESCE(?8, c.disburseCount), " +
+           "c.updateTime = ?9 " +
+           "WHERE c.id = ?1")
+    void updateById(Long id, java.math.BigDecimal amount, String payee, String mobile, 
+                   String disburseAccount, String disburseBank, Boolean isEntrust, 
+                   Integer disburseCount, String updateTime);
+
+    @Modifying
+    @Transactional
+    @Query("UPDATE ContractBankInfo c SET c.isDelete = true WHERE c.contractId = ?1")
+    void deleteByContractId(Long contractId);
+
+    @Query("SELECT c FROM ContractBankInfo c WHERE c.contractId IN ?1 AND c.isDelete = ?2")
+    List<ContractBankInfo> findByContractIdsAndIsDelete(List<Long> contractIds, boolean b);
+}

+ 5 - 0
src/main/java/com/loan/system/repository/ContractRepaymentRepository.java

@@ -35,4 +35,9 @@ public interface ContractRepaymentRepository extends JpaRepository<ContractRepay
 
     @Query("select c.contractId from ContractRepayment c where c.repaymentRecordId = ?1 and c.isDelete = ?2 order by c.createTime asc")
     List<Long> findContractIdsByRepaymentId(Long recordId, boolean b);
+
+    @Modifying
+    @Transactional
+    @Query("update ContractRepayment c set c.amount = ?1 where c.contractId = ?2 and c.repaymentRecordId = ?3")
+    void updateAmountByRecordIdAndContractId(Double amount, Long contractId, Long recordId);
 }

+ 14 - 8
src/main/java/com/loan/system/repository/ContractRepository.java

@@ -1,5 +1,6 @@
 package com.loan.system.repository;
 
+import com.loan.system.domain.dto.ContractBankInfoDTO;
 import com.loan.system.domain.entity.Contract;
 import com.loan.system.domain.vo.ContractVO;
 import io.swagger.models.Contact;
@@ -29,13 +30,13 @@ public interface ContractRepository extends JpaRepository<Contract,Long> {
             "c.businessAttr = CASE WHEN :#{#contract.businessAttr} IS NOT NULL THEN :#{#contract.businessAttr} ELSE c.businessAttr END, " +
             "c.caseId = CASE WHEN :#{#contract.caseId} IS NOT NULL THEN :#{#contract.caseId} ELSE c.caseId END, " +
             "c.customerId = CASE WHEN :#{#contract.customerId} IS NOT NULL THEN :#{#contract.customerId} ELSE c.customerId END, " +
+            "c.customerId1 = CASE WHEN :#{#contract.customerId1} IS NOT NULL THEN :#{#contract.customerId1} ELSE c.customerId1 END, " +
+            "c.customerId2 = CASE WHEN :#{#contract.customerId2} IS NOT NULL THEN :#{#contract.customerId2} ELSE c.customerId2 END, " +
             "c.contractNo = CASE WHEN :#{#contract.contractNo} IS NOT NULL THEN :#{#contract.contractNo} ELSE c.contractNo END, " +
             "c.contractName = CASE WHEN :#{#contract.contractName} IS NOT NULL THEN :#{#contract.contractName} ELSE c.contractName END, " +
-            "c.contractVersion = CASE WHEN :#{#contract.contractVersion} IS NOT NULL THEN :#{#contract.contractVersion} ELSE c.contractVersion END, " +
             "c.contractAmount = CASE WHEN :#{#contract.contractAmount} IS NOT NULL THEN :#{#contract.contractAmount} ELSE c.contractAmount END, " +
             "c.interestRate = CASE WHEN :#{#contract.interestRate} IS NOT NULL THEN :#{#contract.interestRate} ELSE c.interestRate END, " +
             "c.loanPeriod = CASE WHEN :#{#contract.loanPeriod} IS NOT NULL THEN :#{#contract.loanPeriod} ELSE c.loanPeriod END, " +
-            "c.content = CASE WHEN :#{#contract.content} IS NOT NULL THEN :#{#contract.content} ELSE c.content END, " +
             "c.signedByCustomer = CASE WHEN :#{#contract.signedByCustomer} IS NOT NULL THEN :#{#contract.signedByCustomer} ELSE c.signedByCustomer END, " +
             "c.signedId = CASE WHEN :#{#contract.signedId} IS NOT NULL THEN :#{#contract.signedId} ELSE c.signedId END, " +
             "c.signedTime = CASE WHEN :#{#contract.signedTime} IS NOT NULL THEN :#{#contract.signedTime} ELSE c.signedTime END, " +
@@ -95,19 +96,24 @@ public interface ContractRepository extends JpaRepository<Contract,Long> {
 
     @Transactional
     @Modifying
-    @Query("update Contract c set c.customerId = ?1, c.bankName = ?2, c.bankAccount = ?3 where c.id = ?4")
-    void updateLoanInfoById(Long customerId, String bankName, String bankAccount, Long id);
+    @Query("update Contract c set c.amountRate = ?1 , c.serviceCost = ?2 , c.loanRate = ?3 where c.id = ?4")
+    void updateLoanInfoById(Double amountRate,Double serviceCost,Double loanRate, Long id);
 
     @Transactional
     @Modifying
-    @Query("update Contract c set c.clearedStatus = ?2 where c.id = ?1")
-    void updateClearedStatusById(Long contractId, String msg);
+    @Query("update Contract c set c.clearedStatus = ?2 , c.clearedTime = ?3 where c.id = ?1")
+    void updateClearedStatusById(Long contractId, String msg, String clearedTime);
 
     @Query("select c.id from Contract c where c.caseId = ?1 and c.isDelete = ?2")
     List<Long> findIdsByCaseIdAndIsDelete(Long caseId, boolean b);
 
     @Transactional
     @Modifying
-    @Query("update Contract c set c.actualAmount = ?2 where c.id = ?1")
-    void updateActualAmountById(Long key, Double value);
+    @Query("update Contract c set c.actualAmount = ?2  ,c.isDisbursementComplete = ?3 where c.id = ?1")
+    void updateActualAmountAndIsCompleteById(Long key, Double value,Boolean isComplete);
+
+    @Transactional
+    @Modifying
+    @Query("update Contract c set c.isDisbursementComplete = ?2  where c.id = ?1")
+    void updateISCompleteById(Long contractId, boolean isDisbursement );
 }

+ 1 - 0
src/main/java/com/loan/system/repository/LoanRepository.java

@@ -59,6 +59,7 @@ public interface LoanRepository extends JpaRepository<LoanCase,Long> {
 
     @Query("SELECT l FROM LoanCase l WHERE l.customerId IN :customerIds AND l.isComplete = :isComplete AND l.isDelete = :isDelete")
     Page<LoanCase> findLoanCaseByCustomerIds(List<Long> customerIds, Pageable pageable, String isComplete, boolean isDelete);
+
     @Query("SELECT l FROM LoanCase l WHERE l.customerId IN :customerIds AND l.isDelete = :isDelete")
     Page<LoanCase> findLoanCaseByCustomerIds(List<Long> customerIds, Pageable pageable, boolean isDelete);
 

+ 1 - 1
src/main/java/com/loan/system/repository/PawnTicketRepository.java

@@ -20,7 +20,7 @@ public interface PawnTicketRepository extends JpaRepository<PawnTicketInfo,Long>
     List<PawnTicketInfo> findByCaseIdAndIsDelete(Long caseId, boolean isDelete);
 
     @Query("select p from PawnTicketInfo p where p.contractId = ?1 and p.isDelete = ?2")
-    PawnTicketInfo findByContractIdAndIsDelete(Long contractId, boolean isDelete);
+    List<PawnTicketInfo> findByContractIdAndIsDelete(Long contractId, boolean isDelete);
 
     @Modifying
     @Transactional

+ 1 - 0
src/main/java/com/loan/system/repository/RepaymentRecordRepository.java

@@ -54,6 +54,7 @@ public interface RepaymentRecordRepository extends JpaRepository<RepaymentRecord
     @Modifying
     @Transactional
     @Query("update RepaymentRecord  r set " +
+            "r.amount = :#{#repaymentRecordDTO.amount},"+
             "r.interestAmount = CASE WHEN :#{#repaymentRecordDTO.interestAmount} IS NOT NULL THEN :#{#repaymentRecordDTO.interestAmount} ELSE r.interestAmount END," +
             "r.repayWay = :#{#repaymentRecordDTO.repayWay}," +
             "r.repayComment = :#{#repaymentRecordDTO.repayComment}," +

+ 4 - 0
src/main/java/com/loan/system/repository/StepRepository.java

@@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -76,4 +77,7 @@ public interface StepRepository extends JpaRepository<Step,Long> {
 
     @Query("select s from Step s where s.caseId = ?1 and s.parentCode != 0 and s.beginTime < ?2 order by s.beginTime")
     List<Step> getChildStepByCaseIdBeforeTime(Long id, String time, boolean b);
+
+    @Query("select s from Step s where s.caseId in ?1 and s.code = ?2")
+    List<Step> findByCaseIdsAndCode(List<Long> ids, Integer stepCode);
 }

+ 25 - 0
src/main/java/com/loan/system/service/ContractBankInfoService.java

@@ -0,0 +1,25 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.dto.ContractBankInfoDTO;
+import com.loan.system.domain.vo.ContractBankInfoVO;
+import com.loan.system.domain.vo.LoanCaseSimpleVO;
+
+import java.util.List;
+
+public interface ContractBankInfoService {
+    List<ContractBankInfoVO> listContractBankInfo(Long contractId);
+
+    void addContractBankInfo(List<ContractBankInfoDTO> contractBankInfoList, Long contractId);
+
+    List<ContractBankInfoVO> findByContractIdAndIsDelete(Long contractId, boolean isDelete);
+
+    void deleteByContractId(Long contractId);
+
+    void addInfo(ContractBankInfoDTO bankInfo, Long id);
+
+    void addInfos(List<ContractBankInfoDTO> entrustBankInfos, Long id);
+
+    List<ContractBankInfoVO> findByContractIdsAndIsDelete(List<Long> contractIds);
+
+    List<ContractBankInfoVO> listContractBankInfoByIds(List<Long> contractIds, LoanCaseSimpleVO loanCaseSimpleVO);
+}

+ 1 - 1
src/main/java/com/loan/system/service/ContractDisbursementService.java

@@ -7,7 +7,7 @@ import java.util.Map;
 
 public interface ContractDisbursementService {
 
-    void addContractDisbursement(Map<Long, Double> contractIdAndAmount, Long recordId,Boolean isPlan);
+    void addContractDisbursement(Map<Long, Double> contractIdAndAmount, Long recordId,Long caseId,Boolean isPlan);
 
     List<ContractDisbursement> findByRecordIdAndIsPlan(Long recordId,Boolean isPlan);
 

+ 2 - 0
src/main/java/com/loan/system/service/ContractRepaymentService.java

@@ -18,4 +18,6 @@ public interface ContractRepaymentService {
     List<ContractRepayment> findDataByRepaymentRecordIdAndIsDelete(Long recordId);
 
     List<Long> findContractIdsByRepaymentId(Long recordId);
+
+    void updateAmountByRecordIdAndContractId(Double amount, Long contractId, Long recordId);
 }

+ 5 - 1
src/main/java/com/loan/system/service/ContractService.java

@@ -59,5 +59,9 @@ public interface ContractService {
 
     List<Long> findIdsByCaseId(Long caseId);
 
-    void updateActualAmountByIds(Map<Long, Double> contractIdAndAmount);
+    void updateActualAmountAndIsCompleteByIds(Map<Long, Double> contractIdAndAmount,Boolean isComplete);
+
+    Double getActualTotalAmount(Long caseId);
+
+    void updateIsDisbursementById(Long contractId, boolean isDisbursement);
 }

+ 156 - 0
src/main/java/com/loan/system/service/Impl/ContractBankInfoServiceImpl.java

@@ -0,0 +1,156 @@
+package com.loan.system.service.Impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.domain.dto.ContractBankInfoDTO;
+import com.loan.system.domain.entity.ContractBankInfo;
+import com.loan.system.domain.entity.Customer;
+import com.loan.system.domain.vo.ContractBankInfoVO;
+import com.loan.system.domain.vo.LoanCaseSimpleVO;
+import com.loan.system.repository.ContractBankInfoRepository;
+import com.loan.system.service.ContractBankInfoService;
+import com.loan.system.service.CustomerService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+@Service
+@RequiredArgsConstructor
+public class ContractBankInfoServiceImpl implements ContractBankInfoService {
+    private final ContractBankInfoRepository contractBankInfoRepository;
+    private final CustomerService customerService;
+
+
+    @Override
+    public List<ContractBankInfoVO> listContractBankInfo(Long contractId) {
+        return BeanUtil.copyToList(contractBankInfoRepository.findByContractIdAndIsDelete(contractId, false), ContractBankInfoVO.class);
+    }
+
+    @Override
+    public void addContractBankInfo(List<ContractBankInfoDTO> contractBankInfoList, Long contractId) {
+        // 先将全部的逻辑删除
+        contractBankInfoRepository.deleteByContractId(contractId);
+        List<ContractBankInfo> contractBankInfos = BeanUtil.copyToList(contractBankInfoList, ContractBankInfo.class);
+        for (ContractBankInfo contractBankInfo : contractBankInfos) {
+            contractBankInfo.setContractId(contractId);
+            contractBankInfo.setIsDelete(false);
+            contractBankInfo.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            contractBankInfo.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        }
+        contractBankInfoRepository.saveAll(contractBankInfos);
+    }
+
+    @Override
+    public List<ContractBankInfoVO> findByContractIdAndIsDelete(Long contractId, boolean isDelete) {
+        return BeanUtil.copyToList(contractBankInfoRepository.findByContractIdAndIsDelete(contractId, isDelete), ContractBankInfoVO.class);
+    }
+
+
+    @Override
+    public void deleteByContractId(Long contractId) {
+        contractBankInfoRepository.deleteByContractId(contractId);
+    }
+
+    @Override
+    public void addInfo(ContractBankInfoDTO bankInfo, Long id) {
+        ContractBankInfo contractBankInfo = BeanUtil.copyProperties(bankInfo, ContractBankInfo.class);
+        if (!bankInfo.getIsEntrust()){
+            Customer customer = customerService.findByIdAndIsDelete(bankInfo.getCustomerId());
+            contractBankInfo.setPayee(customer.getName());
+            contractBankInfo.setMobile(customer.getMobile());
+        }
+        contractBankInfo.setContractId(id);
+        contractBankInfo.setIsDelete(false);
+        contractBankInfo.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        contractBankInfo.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+
+        contractBankInfoRepository.save(contractBankInfo);
+    }
+
+    @Override
+    public void addInfos(List<ContractBankInfoDTO> bankInfos, Long id) {
+        List<ContractBankInfo> contractBankInfos = new ArrayList<>();
+        for (ContractBankInfoDTO bankInfo : bankInfos) {
+            ContractBankInfo contractBankInfo = BeanUtil.copyProperties(bankInfo, ContractBankInfo.class);
+            contractBankInfo.setContractId(id);
+            contractBankInfo.setIsDelete(false);
+            contractBankInfo.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            contractBankInfo.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+
+            contractBankInfos.add(contractBankInfo);
+        }
+        contractBankInfoRepository.saveAll(contractBankInfos);
+    }
+
+    @Override
+    public List<ContractBankInfoVO> findByContractIdsAndIsDelete(List<Long> contractIds) {
+        List<ContractBankInfo> contractBankInfos = contractBankInfoRepository.findByContractIdsAndIsDelete(contractIds, false);
+        return BeanUtil.copyToList(contractBankInfos, ContractBankInfoVO.class);
+    }
+
+    @Override
+    public List<ContractBankInfoVO> listContractBankInfoByIds(List<Long> contractIds, LoanCaseSimpleVO loanCaseSimpleVO) {
+        Long customerId = loanCaseSimpleVO.getCustomerId();
+        Long otherId1 = loanCaseSimpleVO.getOtherId1();
+        Long otherId2 = loanCaseSimpleVO.getOtherId2();
+        Map<String,ContractBankInfoVO> contractBankInfoVOMap = new HashMap<>();//保存所有借款人的信息
+        Customer customer = customerService.findByIdAndIsDelete(customerId);
+        contractBankInfoVOMap.put(customer.getBankName(),ContractBankInfoVO.builder().id(1L).mobile(customer.getMobile()).disburseBank(customer.getBankName()).isEntrust( false).disburseAccount(customer.getBankAccount()).payee(customer.getName()).build());
+        if (otherId1 != null){
+            Customer customer1 = customerService.findByIdAndIsDelete(otherId1);
+            contractBankInfoVOMap.put(customer1.getBankName(),ContractBankInfoVO.builder().id(2L).mobile(customer1.getMobile()).disburseBank(customer1.getBankName()).isEntrust( false).disburseAccount(customer1.getBankAccount()).payee(customer1.getName()).build());
+        }
+        if (otherId2 != null){
+            Customer customer2 = customerService.findByIdAndIsDelete(otherId2);
+            contractBankInfoVOMap.put(customer2.getBankName(),ContractBankInfoVO.builder().id(3L).mobile(customer2.getMobile()).disburseBank(customer2.getBankName()).isEntrust( false).disburseAccount(customer2.getBankAccount()).payee(customer2.getName()).build());
+        }
+
+        List<ContractBankInfo> contractBankInfoList = contractBankInfoRepository.findByContractIdsAndIsDelete(contractIds, false);
+        List<ContractBankInfoVO> contractBankInfoVOList = new ArrayList<>();//返回给前端的信息
+        Long index = 4L;
+        for (ContractBankInfo contractBankInfo : contractBankInfoList){
+            ContractBankInfoVO contractBankInfoVO = BeanUtil.copyProperties(contractBankInfo, ContractBankInfoVO.class);
+            if (!contractBankInfo.getIsEntrust()){//先保存借款人信息
+                ContractBankInfoVO mainBankInfo = contractBankInfoVOMap.get(contractBankInfo.getPayee());
+                if (mainBankInfo != null){//map中存在,用新的
+                    contractBankInfoVO.setId( mainBankInfo.getId());
+                    contractBankInfoVOList.add(contractBankInfoVO);
+                }
+            }else {//再保存委托借款人信息
+                boolean flag = true;
+                for (ContractBankInfoVO contractBankInfoVO1 : contractBankInfoVOList){
+                    if (contractBankInfoVO1.getPayee().equals(contractBankInfo.getPayee()) && contractBankInfoVO1.getDisburseBank().equals(contractBankInfo.getDisburseBank())
+                    && contractBankInfoVO1.getDisburseAccount().equals(contractBankInfo.getDisburseAccount())){
+                        flag = false;
+                        break;
+                    }
+
+                }
+                if (flag){//没有重复则添加
+                    contractBankInfoVO.setId(index);
+                    contractBankInfoVOList.add(contractBankInfoVO);
+                    index++;
+                }
+            }
+
+        }
+        for (Map.Entry<String, ContractBankInfoVO> entry : contractBankInfoVOMap.entrySet()){
+            Long id = entry.getValue().getId();
+
+            boolean flag = true;
+            for (ContractBankInfoVO contractBankInfoVO : contractBankInfoVOList)//有借款人的id,则无需添加,
+                if (contractBankInfoVO.getId().equals(id)){
+                    contractBankInfoVO.setId(entry.getValue().getId());
+                    flag = false;
+                    break;
+                }
+            if (flag)//无借款人的id,则添加
+                contractBankInfoVOList.add(entry.getValue());
+        }
+
+        return contractBankInfoVOList;
+    }
+}

+ 2 - 1
src/main/java/com/loan/system/service/Impl/ContractDisbursementServiceImpl.java

@@ -22,7 +22,7 @@ public class ContractDisbursementServiceImpl implements ContractDisbursementServ
     private final ContractDisbursementRepository contractDisbursementRepository;
 
     @Override
-    public void addContractDisbursement(Map<Long, Double> contractIdAndAmount, Long recordId ,Boolean isPlan) {
+    public void addContractDisbursement(Map<Long, Double> contractIdAndAmount, Long recordId , Long caseId ,Boolean isPlan) {
         Iterator<Map.Entry<Long , Double>> iterator = contractIdAndAmount.entrySet().iterator();
         while (iterator.hasNext()) {
             Map.Entry<Long ,  Double> entry = iterator.next();
@@ -33,6 +33,7 @@ public class ContractDisbursementServiceImpl implements ContractDisbursementServ
             contractDisbursement.setContractId(id);
             contractDisbursement.setDisbursementRecordId(recordId);
             contractDisbursement.setAmount(amount);
+            contractDisbursement.setCaseId(caseId);
             contractDisbursement.setIsDelete(false);
             contractDisbursement.setIsPlan(isPlan);
             contractDisbursement.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

+ 5 - 0
src/main/java/com/loan/system/service/Impl/ContractRepaymentServiceImpl.java

@@ -60,4 +60,9 @@ public class ContractRepaymentServiceImpl implements ContractRepaymentService {
     public List<Long> findContractIdsByRepaymentId(Long recordId) {
         return contractRepaymentRepository.findContractIdsByRepaymentId(recordId, false);
     }
+
+    @Override
+    public void updateAmountByRecordIdAndContractId(Double amount, Long contractId, Long recordId) {
+        contractRepaymentRepository.updateAmountByRecordIdAndContractId(amount,contractId,recordId);
+    }
 }

+ 75 - 15
src/main/java/com/loan/system/service/Impl/ContractServiceImpl.java

@@ -10,6 +10,7 @@ import com.loan.system.domain.entity.DictData;
 import com.loan.system.domain.entity.Document;
 import com.loan.system.domain.enums.*;
 import com.loan.system.domain.pojo.ContractInformation;
+import com.loan.system.domain.vo.ContractBankInfoVO;
 import com.loan.system.domain.vo.ContractVO;
 import com.loan.system.domain.vo.CustomerVO;
 import com.loan.system.domain.vo.LoanCaseSimpleVO;
@@ -23,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
 import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
 
 import javax.servlet.http.HttpServletResponse;
@@ -32,10 +34,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 
 import static com.loan.system.domain.enums.ExceptionEnum.FILE_DELETE_ERROR;
 
@@ -53,14 +52,18 @@ public class ContractServiceImpl implements ContractService {
     private final DictionaryService dictionaryService;
     private final StepService stepService;
     private final EsignService esignService;
+    private final ContractBankInfoService  contractBankInfoService;
 
     @Override
     public Contract saveContract(ContractDTO contractDTO) {
         Map<String, String> contractMap = dictionaryService.contractMap();
         Contract contract = BeanUtil.copyProperties(contractDTO, Contract.class);
-        System.err.println( contract.getCustomerId());
-        Long customerId = contractDTO.getCustomerId();
-        contract.setCustomerId(customerId);
+        String[] split = contractDTO.getCustomerIds().split(",");
+
+        contract.setCustomerId(split.length>0?Long.valueOf(split[0]):null);
+        contract.setCustomerId1(split.length>1?Long.valueOf(split[1]):null);
+        contract.setCustomerId2(split.length>2?Long.valueOf(split[2]):null);
+
         contract.setId( null);
         contract.setContractName(contract.getBusinessAttr().equals(BusinessAttrEnum.ESTATE_MORTGAGE.getMsg())?"抵押合同":"质押合同");
         if(contract.getContractNo()==null)
@@ -70,6 +73,8 @@ public class ContractServiceImpl implements ContractService {
         contract.setIsPush( false);
         contract.setClearedStatus(DecisionEnum.CLEAR_NOT.getMsg());
         contract.setInterestAmount(0.0);
+        contract.setActualAmount(0.0);
+        contract.setIsDisbursementComplete(false);
         contract.setAmountRate(Double.valueOf(contractMap.get(ContractEnum.PAWN_INTEREST_RATE.getLabel())));
         contract.setServiceCost(Double.valueOf(contractMap.get(ContractEnum.MONTHLY_COMPREHENSIVE_FEE.getLabel())));
         contract.setLoanRate(Double.valueOf(contractMap.get(ContractEnum.LOAN_INTEREST_RATE.getLabel())));
@@ -88,9 +93,12 @@ public class ContractServiceImpl implements ContractService {
 
     @Override
     public void updateContractById(Long id, ContractDTO contractDTO, boolean isDelete) {
-        Long customerId = contractDTO.getCustomerId();
         Contract contract = BeanUtil.copyProperties(contractDTO, Contract.class);
-        contract.setCustomerId(customerId);
+
+        String[] split = contractDTO.getCustomerIds().split(",");
+        contract.setCustomerId(split.length>0?Long.valueOf(split[0]):null);
+        contract.setCustomerId1(split.length>1?Long.valueOf(split[1]):null);
+        contract.setCustomerId2(split.length>2?Long.valueOf(split[2]):null);
         contract.setUpdateTime( LocalDateTime.now().format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" )));
         contractRepository.updateContractById(id,contract,isDelete);
     }
@@ -102,9 +110,40 @@ public class ContractServiceImpl implements ContractService {
         for (Contract contract : contracts){
             ContractVO contractVO = BeanUtil.copyProperties(contract, ContractVO.class);
             contractVO.setEsignFlow(esignService.findByContractIdAndNormal(contract.getId()));
-            Customer customer = customerService.findByIdAndIsDelete(contract.getCustomerId());
-            contractVO.setCustomerName(customer != null?customer.getName():"");
 
+            Customer customer = customerService.findByIdAndIsDelete(contract.getCustomerId());
+            contractVO.setCustomer(BeanUtil.copyProperties(customer, CustomerVO.class));
+            Customer customer1 = customerService.findByIdAndIsDelete(contract.getCustomerId1());
+            contractVO.setCustomer1(BeanUtil.copyProperties(customer1, CustomerVO.class));
+            Customer customer2 = customerService.findByIdAndIsDelete(contract.getCustomerId2());
+            contractVO.setCustomer2(BeanUtil.copyProperties(customer2, CustomerVO.class));
+            String customerNames = "";
+            if (!ObjectUtils.isEmpty(customer)) customerNames += customer.getName();
+            if (!ObjectUtils.isEmpty(customer1)) customerNames += "," + customer1.getName();
+            if (!ObjectUtils.isEmpty(customer2)) customerNames += "," + customer2.getName();
+            contractVO.setCustomerNames(customerNames);
+
+            List<ContractBankInfoVO> bankInfoVOS = contractBankInfoService.findByContractIdAndIsDelete(contract.getId(), false);
+            ContractBankInfoVO bankInfo = null;
+            List<ContractBankInfoVO> entrustBankInfoVOS = new ArrayList<>();
+            for (ContractBankInfoVO bankInfoVO : bankInfoVOS){
+                if (!bankInfoVO.getIsEntrust())
+                    bankInfo = bankInfoVO;
+                else
+                    entrustBankInfoVOS.add(bankInfoVO);
+            }
+            if (bankInfo == null){//如果还没填,默认是第一位客户的银行信息
+                bankInfo = new ContractBankInfoVO();
+                bankInfo.setPayee(customer.getName());
+                bankInfo.setCustomerId(customer.getId());
+                bankInfo.setMobile(customer.getMobile());
+                bankInfo.setId(-1L);
+                bankInfo.setDisburseBank(customer.getBankName());
+                bankInfo.setDisburseAccount(customer.getBankAccount());
+            }
+            contractVO.setBankInfo(bankInfo);
+            contractVO.setEntrustBankInfos(entrustBankInfoVOS);
+            //contractVO.setCustomerName(customer.getName());
             contractVOS.add(contractVO);
         }
         return contractVOS;
@@ -212,7 +251,9 @@ public class ContractServiceImpl implements ContractService {
 //        }
         List<ContractDTO> contractDTOS = contractWrapper.getContractDTOS();
         for (ContractDTO contractDTO : contractDTOS) {
-            contractRepository.updateLoanInfoById(contractDTO.getCustomerId(),contractDTO.getBankName(),contractDTO.getBankAccount(),contractDTO.getId());
+            contractBankInfoService.addInfo(contractDTO.getBankInfo(),contractDTO.getId());
+            contractBankInfoService.addInfos(contractDTO.getEntrustBankInfos(),contractDTO.getId());
+            contractRepository.updateLoanInfoById(contractDTO.getAmountRate(),contractDTO.getServiceCost(),contractDTO.getLoanRate(),contractDTO.getId());
         }
         //合同签约完成
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.CONTRACT_SIGN.getCode(), BaseContext.getCurrentId(),caseId);
@@ -279,7 +320,7 @@ public class ContractServiceImpl implements ContractService {
 
     @Override
     public void updateClearedStatusById(Long contractId, String msg) {
-        contractRepository.updateClearedStatusById(contractId,msg);
+        contractRepository.updateClearedStatusById(contractId,msg,LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
     }
 
     @Override
@@ -288,11 +329,30 @@ public class ContractServiceImpl implements ContractService {
     }
 
     @Override
-    public void updateActualAmountByIds(Map<Long, Double> contractIdAndAmount) {
+    public void updateActualAmountAndIsCompleteByIds(Map<Long, Double> contractIdAndAmount,Boolean isComplete) {
         for (Map.Entry<Long, Double> entry : contractIdAndAmount.entrySet()){
-            contractRepository.updateActualAmountById(entry.getKey(),entry.getValue());
+            Contract contract = contractRepository.findContractById(entry.getKey());
+            Double amount = contract.getActualAmount() + entry.getValue();
+            isComplete = contract.getIsDisbursementComplete();
+            if(Math.abs(amount - contract.getContractAmount())<Double.MIN_VALUE && isComplete == false)//相同则自动更新
+                isComplete = true;
+
+            contractRepository.updateActualAmountAndIsCompleteById(entry.getKey(),amount,isComplete);
         }
     }
 
+    @Override
+    public Double getActualTotalAmount(Long caseId) {
+        List<ContractVO> contracts = findContractByCaseId(caseId);
+
+        return contracts.stream().reduce(0.0, (sum, contract) -> sum + contract.getActualAmount(), Double::sum);
+
+    }
+
+    @Override
+    public void updateIsDisbursementById(Long contractId, boolean isDisbursement) {
+        contractRepository.updateISCompleteById(contractId,isDisbursement);
+    }
+
 
 }

+ 78 - 32
src/main/java/com/loan/system/service/Impl/DisbursementServiceImpl.java

@@ -15,6 +15,7 @@ import com.loan.system.repository.DisbursementRepository;
 import com.loan.system.service.*;
 import com.loan.system.utils.RedisData;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
@@ -27,10 +28,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static com.loan.system.domain.enums.DecisionEnum.PASS;
 import static com.loan.system.domain.enums.ExceptionEnum.*;
 
 @Service
 @RequiredArgsConstructor
+@Slf4j
 public class DisbursementServiceImpl implements DisbursementService {
     private final DisbursementRepository disbursementRepository;
     private final CustomerService customerService;
@@ -45,6 +48,7 @@ public class DisbursementServiceImpl implements DisbursementService {
     private final ContractDisbursementService contractDisbursementService;
     private final LocationDatumService locationDatumService;
     private final ContractService contractService;
+    private final ContractBankInfoService contractBankInfoService;
 
     @Override
     public DisbursementVO addDisbursement(DisbursementDTO disbursementDTO) {
@@ -135,28 +139,28 @@ public class DisbursementServiceImpl implements DisbursementService {
         if (id > 0) {
             Disbursement disbursement = disbursementRepository.findByIdAndIsDelete(id, false);
             ApprovalRecord approvalRecord = approvalService.findByIdAndIsDelete(disbursement.getApprovalId());
-            if(approvalRecord ==null || approvalRecord.getDecision().equals(DecisionEnum.PASS.getMsg()))
+            if(approvalRecord ==null || approvalRecord.getDecision().equals(PASS.getMsg()))
                 throw new DescribeException(DISBURSEMENT_HAS_COMPLETED);
 
             updateDisbursementByCaseId(disbursementDTO);
             //删除记录
             contractDisbursementService.deleteByRecordId(id, true);
         } else {
-            List<Disbursement> disbursements = disbursementRepository.findDisbursementsByCaseId(disbursementDTO.getCaseId(), false);
-            if(!ObjectUtils.isEmpty(disbursements)){
-                Disbursement disbursement = disbursements.get(disbursements.size()-1);
-
-                ApprovalRecord approvalRecord = approvalService.findByIdAndIsDelete(disbursement.getApprovalId());
-                if (approvalRecord == null || !approvalRecord.getDecision().equals(DecisionEnum.PASS.getMsg()))
-                    throw new DescribeException(DISBURSEMENT_HAS_BEEN_REJECTED);
-            }
+//            List<Disbursement> disbursements = disbursementRepository.findDisbursementsByCaseId(disbursementDTO.getCaseId(), false);
+//            if(!ObjectUtils.isEmpty(disbursements)){
+//                Disbursement disbursement = disbursements.get(disbursements.size()-1);
+//
+//                ApprovalRecord approvalRecord = approvalService.findByIdAndIsDelete(disbursement.getApprovalId());
+//                if (approvalRecord == null || !approvalRecord.getDecision().equals(PASS.getMsg()))
+//                    throw new DescribeException(DISBURSEMENT_HAS_BEEN_REJECTED);
+//            }
             DisbursementVO disbursementVO = addDisbursement(disbursementDTO);
             id = disbursementVO.getId();
         }
 
         //设置计划与合同对应
         Map<Long, Double> contractAndAmount = disbursementDTO.getContractAndAmount();
-        contractDisbursementService.addContractDisbursement(contractAndAmount, id, true);
+        contractDisbursementService.addContractDisbursement(contractAndAmount, id, disbursementDTO.getCaseId(),true);
 
         //修改状态
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.PLAN_REPORT.getCode(), BaseContext.getCurrentId(), disbursementDTO.getCaseId());
@@ -180,7 +184,7 @@ public class DisbursementServiceImpl implements DisbursementService {
         disbursementRepository.updateUserById(chargeId, assistantId, approvalRecordDTO.getRecordId());
 
         //填写审批意见并绑定审批id
-        ApprovalRecord approvalRecord = approvalService.addApprovalRecord(caseId, StepPropertyEnum.PLAN_AUDIT.getCode(), DecisionEnum.PASS.getMsg(), approvalRecordDTO.getComments());
+        ApprovalRecord approvalRecord = approvalService.addApprovalRecord(caseId, StepPropertyEnum.PLAN_AUDIT.getCode(), PASS.getMsg(), approvalRecordDTO.getComments());
         disbursementRepository.updateApprovalUserById(approvalRecord.getId(), approvalRecordDTO.getRecordId());
 
         //修改状态
@@ -255,8 +259,8 @@ public class DisbursementServiceImpl implements DisbursementService {
                     if (split.length > 0)
                         financeApprovalRecord = approvalService.findByIdAndIsDelete(Long.parseLong(split[split.length - 1]));
                 }
-                if ((ObjectUtils.isEmpty(approvalRecord) || approvalRecord.getDecision().equals(DecisionEnum.PASS.getMsg())) &&
-                        (ObjectUtils.isEmpty(financeApprovalRecord) || financeApprovalRecord.getDecision().equals(DecisionEnum.PASS.getMsg())))
+                if ((ObjectUtils.isEmpty(approvalRecord) || approvalRecord.getDecision().equals(PASS.getMsg())) &&
+                        (ObjectUtils.isEmpty(financeApprovalRecord) || financeApprovalRecord.getDecision().equals(PASS.getMsg())))
                     throw new DescribeException(DISBURSEMENT_HAS_COMPLETED);
             }
 
@@ -283,8 +287,8 @@ public class DisbursementServiceImpl implements DisbursementService {
                         if (split.length > 0)
                             financeApprovalRecord = approvalService.findByIdAndIsDelete(Long.parseLong(split[split.length - 1]));
                     }
-                    if ((ObjectUtils.isEmpty(approvalRecord) || !approvalRecord.getDecision().equals(DecisionEnum.PASS.getMsg())) &&
-                            (ObjectUtils.isEmpty(financeApprovalRecord) || !financeApprovalRecord.getDecision().equals(DecisionEnum.PASS.getMsg())))//未审批通过
+                    if ((ObjectUtils.isEmpty(approvalRecord) || !approvalRecord.getDecision().equals(PASS.getMsg())) &&
+                            (ObjectUtils.isEmpty(financeApprovalRecord) || !financeApprovalRecord.getDecision().equals(PASS.getMsg())))//未审批通过
                         throw new DescribeException(DISBURSEMENT_HAS_BEEN_REJECTED);
                 }
             }
@@ -293,17 +297,35 @@ public class DisbursementServiceImpl implements DisbursementService {
             recordId = disbursementRecord.getId();
         }
 
+        //更新合同实际出款金额状态
+        List<ContractVO> contracts = contractService.findContractByCaseId(caseId);
+        Map<Long, Boolean> contractIdAndIsComplete = disbursementRecordDTO.getContractIdAndIsComplete();
+        for (ContractVO contract : contracts){
+            if (contract.getIsDisbursementComplete().equals(contractIdAndIsComplete.get(contract.getId())))
+                continue;
+
+            contractService.updateIsDisbursementById(contract.getId(), contractIdAndIsComplete.get(contract.getId()));
+        }
+
         //设置计划与合同对应
         Map<Long, Double> contractAndAmount = disbursementRecordDTO.getContractIdAndAmount();
-        contractDisbursementService.addContractDisbursement(contractAndAmount, recordId, false);
+        contractDisbursementService.addContractDisbursement(contractAndAmount, recordId,caseId, false);
 
         //添加当票信息
-        pawnTicketService.addPawnTicket(disbursementStartDTO.getContractAndPawn(), recordId, disbursementRecordDTO.getCreateTime(), caseId);
+        pawnTicketService.addPawnTicket(disbursementStartDTO.getContractAndPawn(), recordId,contractAndAmount, disbursementRecordDTO.getCreateTime(), caseId);
         new RedisData(redisTemplate).deleteApprovalByKey(caseId, StepPropertyEnum.DISBURSE_START.getLabel(), StepPropertyEnum.DISBURSE_START.getCode());
 
         //修改状态
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.DISBURSE_START.getCode(), BaseContext.getCurrentId(), caseId);
-        if (isComplete || disburseIsComplete(caseId))
+        Map<Long, Boolean> complete = disbursementRecordDTO.getContractIdAndIsComplete();
+        boolean flag = true;
+        for (Boolean aBoolean : complete.values()) {
+            if (!aBoolean) {
+                flag = false;
+                break;
+            }
+        }
+        if (flag || disburseIsComplete(caseId))
             stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.DISBURSE_START.getCode(), caseId);
         stepService.tryStartStep(StepPropertyEnum.DISBURSE_START.getCode(), caseId);
 
@@ -349,7 +371,7 @@ public class DisbursementServiceImpl implements DisbursementService {
         //修改状态
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.DISBURSE_AUDIT.getCode(), BaseContext.getCurrentId(), caseId);
 
-        if (decision.equals(DecisionEnum.PASS.getMsg())) {
+        if (decision.equals(PASS.getMsg())) {
             StepVO step = stepService.findByStepCodeAndCaseId(StepPropertyEnum.DISBURSE_START.getCode(), caseId);
             if (ApprovalIsCompleted(caseId, StepPropertyEnum.DISBURSE_AUDIT.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
                 stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.DISBURSE_AUDIT.getCode(), caseId);
@@ -381,7 +403,7 @@ public class DisbursementServiceImpl implements DisbursementService {
             DisbursementRecord disbursementRecord = disbursementRecordService.addDisbursementRecord(disbursementRecordDTO);
             //绑定出款记录与合同id
             Map<Long, Double> contractIdAndAmount = disbursementRecordDTO.getContractIdAndAmount();
-            contractDisbursementService.addContractDisbursement(contractIdAndAmount, disbursementRecord.getId(), false);
+            contractDisbursementService.addContractDisbursement(contractIdAndAmount, disbursementRecord.getId(), caseId,false);
         }
 
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.FINANCE_DISBURSE.getCode(), BaseContext.getCurrentId(), caseId);
@@ -431,6 +453,8 @@ public class DisbursementServiceImpl implements DisbursementService {
         Map<Long, UserVO> userVOMap2 = new HashMap<>();
         if (!ObjectUtils.isEmpty(disbursementDetailVO)) {
             //1.List<DisbursementVO> disbursementPlans;
+            Double currentPlanAmount = 0.0;
+            Double currentPlanAmount1 = 0.0;
             List<Disbursement> plans = disbursementRepository.findDisbursementsByCaseId(caseId, false);
             List<DisbursementVO> planVOs = new ArrayList<>();
             for (Disbursement plan : plans) {
@@ -439,6 +463,9 @@ public class DisbursementServiceImpl implements DisbursementService {
                 if (user != null)
                     disbursementVO.setOperatorUser(BeanUtil.copyProperties(user, UserVO.class));
                 disbursementVO.setLocationDatum(locationDatumService.findById(plan.getLocationId()));
+
+                currentPlanAmount += plan.getPlannedAmount();
+
                 ApprovalRecord approvalRecord = approvalService.findByIdAndIsDelete(plan.getApprovalId());
                 if (approvalRecord != null) {
                     ApprovalRecordVO approvalRecordVO = BeanUtil.copyProperties(approvalRecord, ApprovalRecordVO.class);
@@ -446,6 +473,9 @@ public class DisbursementServiceImpl implements DisbursementService {
                     if (approver != null)
                         approvalRecordVO.setApprover(BeanUtil.copyProperties(approver, UserVO.class));
                     disbursementVO.setApprovalRecordVO(approvalRecordVO);
+
+                    if (approvalRecord.getDecision().equals(PASS.getMsg()))
+                        currentPlanAmount1 += plan.getPlannedAmount();
                 }
                 User user1 = userService.findByIdAndIsDelete(plan.getMainUserId());
                 if (user1 != null) {
@@ -470,13 +500,19 @@ public class DisbursementServiceImpl implements DisbursementService {
                 planVOs.add(disbursementVO);
             }
             disbursementDetailVO.setDisbursementPlans(planVOs);
+            disbursementDetailVO.setCurrentPlanAmount(currentPlanAmount);
+            disbursementDetailVO.setCurrentPlanAmount1(currentPlanAmount1);
 
             //2.private List<DisbursementRecordVO> disbursementRecords;
             List<DisbursementRecordVO> records = disbursementRecordService.findRecordVOByCaseId(caseId);
-            double currentAmount = 0;
+            double currentAmount = 0.0;
+            double currentAmount1 = 0.0;
             Map<Long, Double> contractAndCurrentAmount = new HashMap<>();//合同的目前总金额
             for (int i = 0; i < records.size(); i++) {
                 DisbursementRecordVO record = records.get(i);
+                List<ApprovalRecordVO> financeApprovalRecordVOs = record.getFinanceApprovalRecordVOs();
+                if (financeApprovalRecordVOs != null && financeApprovalRecordVOs.get(financeApprovalRecordVOs.size()-1).getDecision().equals(PASS.getMsg()))
+                    currentAmount1 += record.getAmount();//财务通过了才算实际出账
                 currentAmount += record.getAmount();
 
                 Long recordId = record.getId();
@@ -508,9 +544,13 @@ public class DisbursementServiceImpl implements DisbursementService {
             disbursementDetailVO.setContractAndCurrentAmount(contractAndCurrentAmount);
             // 6.private Double currentAmount;//目前金额
             disbursementDetailVO.setCurrentAmount(currentAmount);
+            disbursementDetailVO.setCurrentAmount1(currentAmount1);
             // 7. private Double totalAmount;//总金额
-            disbursementDetailVO.setTotalAmount(disbursementDetailVO.getLoanCase().getTotalLoanAmount());
+            List<ContractVO> contracts = contractService.findContractByCaseId(caseId);
+            disbursementDetailVO.setTotalAmount(contracts.stream().reduce(0.0 , (sum,contract)-> sum+contract.getActualAmount(),Double::sum));
 
+            List<Long> contractIds = contracts.stream().map(ContractVO::getId).collect(Collectors.toList());
+            disbursementDetailVO.setContractBankInfos(contractBankInfoService.listContractBankInfoByIds(contractIds,disbursementDetailVO.getLoanCase()));
             // 5.private List<String> collateralStatus;//押品状态
             List<CollateralVO> collateralVOS = collateralService.findByCaseId(caseId);
             List<String> collateralStatus = new ArrayList<>();
@@ -523,6 +563,7 @@ public class DisbursementServiceImpl implements DisbursementService {
             disbursementDetailVO.setCollateralStatus(collateralStatus);
 
         }
+
         //获取每个合同的出款时间
         disbursementDetailVO.setContractAndDateAndAmount(getDateAndAmount(caseId));
 
@@ -536,13 +577,12 @@ public class DisbursementServiceImpl implements DisbursementService {
         List<DisbursementRecordVO> disbursementRecordVOS = disbursementRecordService.findRecordVOByCaseId(caseId);
         //按合同划分
         for (DisbursementRecordVO disbursementRecordVO : disbursementRecordVOS) {
-            DateAndAmountPOJO dateAndAmountPOJO = new DateAndAmountPOJO();
-            // 将日期时间格式转换为日期格式
-            dateAndAmountPOJO.setDate(disbursementRecordVO.getCreateTime());
-
             //寻找该记录的合同
             List<ContractDisbursement> contractDisbursements = contractDisbursementService.findByRecordIdAndIsPlan(disbursementRecordVO.getId(), false);
             for (ContractDisbursement contractDisbursement : contractDisbursements) {
+                DateAndAmountPOJO dateAndAmountPOJO = new DateAndAmountPOJO();
+                // 将日期时间格式转换为日期格式
+                dateAndAmountPOJO.setDate(disbursementRecordVO.getCreateTime());
                 dateAndAmountPOJO.setAmount(contractDisbursement.getAmount());
                 result.computeIfAbsent(contractDisbursement.getContractId(), k -> new ArrayList<>()).add(dateAndAmountPOJO);
             }
@@ -552,7 +592,7 @@ public class DisbursementServiceImpl implements DisbursementService {
         Map<Long, List<DateAndAmountPOJO>> processedResult = new HashMap<>();
         for (Map.Entry<Long, List<DateAndAmountPOJO>> entry : result.entrySet()) {
             Long contractId = entry.getKey();
-            List<DateAndAmountPOJO> originalList = entry.getValue();
+            List<DateAndAmountPOJO> originalList = entry.getValue();//原始的时间---现在要合并同一天
             Map<String, Double> dateAmountMap = new HashMap<>();
 
             // 按日期累加金额
@@ -579,6 +619,7 @@ public class DisbursementServiceImpl implements DisbursementService {
             processedResult.put(contractId, processedList);
         }
 
+
         //返回每个合同对应的出款时间即金额
         return processedResult;
     }
@@ -621,16 +662,21 @@ public class DisbursementServiceImpl implements DisbursementService {
         //修改状态
         stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.FINANCE_DISBURSE.getCode(), BaseContext.getCurrentId(), caseId);
 
-        if (decision.equals(DecisionEnum.PASS.getMsg())) {
-            //修改当前合同的出款金额
+        if (decision.equals(PASS.getMsg())) {
+            StepVO step = stepService.findByStepCodeAndCaseId(StepPropertyEnum.DISBURSE_START.getCode(), caseId);
+
+            //设置实际的合同出款金额
             List<ContractDisbursement> contractDisbursements = contractDisbursementService.findByCaseIdAndIsPlan(caseId, false);
             Map<Long, Double> contractIdAndAmount = new HashMap<>();
             for (ContractDisbursement contractDisbursement : contractDisbursements) {
                 contractIdAndAmount.merge(contractDisbursement.getContractId(), contractDisbursement.getAmount(), Double::sum);
             }
-            contractService.updateActualAmountByIds(contractIdAndAmount);
+            if(step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
+                contractService.updateActualAmountAndIsCompleteByIds(contractIdAndAmount,true);
+            else
+                contractService.updateActualAmountAndIsCompleteByIds(contractIdAndAmount,false);
+
 
-            StepVO step = stepService.findByStepCodeAndCaseId(StepPropertyEnum.DISBURSE_START.getCode(), caseId);
             if (ApprovalIsCompleted(caseId, StepPropertyEnum.FINANCE_DISBURSE.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
                 stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.FINANCE_DISBURSE.getCode(), caseId);
             stepService.tryStartStep(StepPropertyEnum.FINANCE_DISBURSE.getCode(), caseId);
@@ -690,7 +736,7 @@ public class DisbursementServiceImpl implements DisbursementService {
 
         List<ApprovalRecordVO> approvalRecordVOS = approvalService.findByIdsAndIsDelete(approvals);
         for (ApprovalRecordVO approvalRecordVO : approvalRecordVOS)
-            if (!approvalRecordVO.getDecision().equals(DecisionEnum.PASS.getMsg()))
+            if (!approvalRecordVO.getDecision().equals(PASS.getMsg()))
                 return false;
 
         return true;

+ 104 - 72
src/main/java/com/loan/system/service/Impl/LoanServiceImpl.java

@@ -97,12 +97,23 @@ public class LoanServiceImpl implements LoanService {
         RedisData redisData = new RedisData(stringRedisTemplate);
         List<Contract> contracts = redisData.getContracts(caseId);
         List<ContractVO> contractVOS = new ArrayList<>();
-        if (ObjectUtils.isEmpty(contracts)) contractVOS = contractService.findContractByCaseId(caseId);
+        if (ObjectUtils.isEmpty(contracts))
+            contractVOS = contractService.findContractByCaseId(caseId);
         else {
             for (Contract contract : contracts) {
                 ContractVO contractVO = BeanUtil.copyProperties(contract, ContractVO.class);
+
                 Customer customer = customerService.findByIdAndIsDelete(contract.getCustomerId());
-                contractVO.setCustomerName(customer != null ? customer.getName() : "");
+                contractVO.setCustomer(BeanUtil.copyProperties(customer, CustomerVO.class));
+                Customer customer1 = customerService.findByIdAndIsDelete(contract.getCustomerId1());
+                contractVO.setCustomer1(BeanUtil.copyProperties(customer1, CustomerVO.class));
+                Customer customer2 = customerService.findByIdAndIsDelete(contract.getCustomerId2());
+                contractVO.setCustomer2(BeanUtil.copyProperties(customer2, CustomerVO.class));
+                String customerNames = "";
+                if (!ObjectUtils.isEmpty(customer)) customerNames += customer.getName();
+                if (!ObjectUtils.isEmpty(customer1)) customerNames += "," + customer1.getName();
+                if (!ObjectUtils.isEmpty(customer2)) customerNames += "," + customer2.getName();
+                contractVO.setCustomerNames(customerNames);
 
                 contractVOS.add(contractVO);
             }
@@ -259,112 +270,118 @@ public class LoanServiceImpl implements LoanService {
     @Override
     public List<LoanCaseVO> listLoanCaseByStepCode(Integer stepCode) {
         //根据角色返回业务列表,业务员返回全部未完成、审批员与财务员仅展示未审批或未财务审批的人物
-        List<Long> loanCaseIds = loanRepository.findIdsByIsCompleteAndIsDelete(DecisionEnum.PROCESS.getMsg(), false);
         List<Long> ids = new ArrayList<>();
         List<StepVO> currentSteps = new ArrayList<>();
-        List<LoanCaseVO> loanCaseVOS = new ArrayList<>();
-
-        for (Long caseId : loanCaseIds) {
-            List<StepVO> steps = stepService.getStepByCaseId(caseId);
-
-            StepVO processStep = null;//受理环节
-            StepVO preTrialStep = null;
-            StepVO receiveStep = null;//取证环节
-            StepVO pushStep1 = null;
-            StepVO pushStep2 = null;
-            boolean flag = false;
-            for (StepVO step : steps) {
-                if (step.getParentCode() == 0) continue;
-
-                //同一用户只能以一个角色处理同一单业务:如果当前环节是第二个角色处理过该单业务,则跳过(true)
+        if(stepCode.equals(StepPropertyEnum.CASE_ARCHIVE.getCode())){
+            //归档环节仅显示已完成的业务
+            ids = loanRepository.findIdsByIsCompleteAndIsDelete(DecisionEnum.COMPLETE.getMsg(), false);
+            List<StepVO> stepVOS = stepService.listByStepCodeAndCaseIds(ids, stepCode);
+            currentSteps.addAll(stepVOS);
+
+        }else{
+            List<Long> loanCaseIds = loanRepository.findIdsByIsCompleteAndIsDelete(DecisionEnum.PROCESS.getMsg(), false);
+
+            for (Long caseId : loanCaseIds) {
+                List<StepVO> steps = stepService.getStepByCaseId(caseId);
+
+                StepVO processStep = null;//受理环节
+                StepVO preTrialStep = null;
+                StepVO receiveStep = null;//取证环节
+                StepVO pushStep1 = null;
+                StepVO pushStep2 = null;
+                boolean flag = false;
+                for (StepVO step : steps) {
+                    if (step.getParentCode() == 0) continue;
+
+                    //同一用户只能以一个角色处理同一单业务:如果当前环节是第二个角色处理过该单业务,则跳过(true)
 //                flag=stepService.hasRolesInCase(caseId,BaseContext.getCurrentId(),step.getCode());
 
-                //只保存正在处理的
-                Step parent = stepService.findStepByCodeAndCaseId(step.getParentCode(), caseId);
-                if (step.getStatus().equals(StepEnum.PROCESS.getMsg()) && parent.getCode().equals(stepCode) && !flag) {
-                    if (step.getCode().equals(StepPropertyEnum.CASE_COMPLETE.getCode())) {//仅显示结清(回款完成)的”业务终结“环节
-                        Step step1 = stepService.findStepByCodeAndCaseId(StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
-                        if (step1 != null && step1.getStatus().equals(StepEnum.COMPLETED.getMsg())) {
+                    //只保存正在处理的
+                    Step parent = stepService.findStepByCodeAndCaseId(step.getParentCode(), caseId);
+                    if (step.getStatus().equals(StepEnum.PROCESS.getMsg()) && parent.getCode().equals(stepCode) && !flag) {
+                        if (step.getCode().equals(StepPropertyEnum.CASE_COMPLETE.getCode())) {//仅显示结清(回款完成)的”业务终结“环节
+                            Step step1 = stepService.findStepByCodeAndCaseId(StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
+                            if (step1 != null && step1.getStatus().equals(StepEnum.COMPLETED.getMsg())) {
+                                currentSteps.add(step);
+                                ids.add(step.getCaseId());
+                            }
+                        } else {
                             currentSteps.add(step);
                             ids.add(step.getCaseId());
                         }
-                    } else {
-                        currentSteps.add(step);
-                        ids.add(step.getCaseId());
                     }
-                }
 
-                //业务受理环节显示未审批的业务
-                if (stepCode.equals(StepPropertyEnum.BUSINESS_ACCEPT_PARENT.getCode())) {
-                    if (step.getCode().equals(StepPropertyEnum.BUSINESS_ACCEPT.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
-                        processStep = step;
+                    //业务受理环节显示未审批的业务
+                    if (stepCode.equals(StepPropertyEnum.BUSINESS_ACCEPT_PARENT.getCode())) {
+                        if (step.getCode().equals(StepPropertyEnum.BUSINESS_ACCEPT.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()))
+                            processStep = step;
 //                    if(step.getCode().equals(StepPropertyEnum.PRE_TRIAL.getCode())&&!step.getStatus().equals(StepEnum.UNSTART.getMsg()))
 //                        preTrialStep = step;
-                    if (!step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getCode().equals(StepPropertyEnum.APPROVAL.getCode())) {
-                        if (processStep != null) {
-                            currentSteps.add(processStep);
-                            ids.add(processStep.getCaseId());
-                            processStep = null;
-                        }
+                        if (!step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getCode().equals(StepPropertyEnum.APPROVAL.getCode())) {
+                            if (processStep != null) {
+                                currentSteps.add(processStep);
+                                ids.add(processStep.getCaseId());
+                                processStep = null;
+                            }
 //                       if (preTrialStep!=null){
 //                           currentSteps.add(preTrialStep);
 //                           ids.add(preTrialStep.getCaseId());
 //                           preTrialStep = null;
 //                       }
+                        }
                     }
-                }
 
-                //保留取证至回款前
-                if (stepCode.equals(StepPropertyEnum.COLLATERAL_RECEIVE.getCode())) {
-                    if (step.getCode().equals(StepPropertyEnum.PLAN_SUBMISSION.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getUserId1() != null)
-                        receiveStep = step;
+                    //保留取证至回款前
+                    if (stepCode.equals(StepPropertyEnum.COLLATERAL_RECEIVE.getCode())) {
+                        if (step.getCode().equals(StepPropertyEnum.PLAN_SUBMISSION.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getUserId1() != null)
+                            receiveStep = step;
 
 //                    if(step.getCode().equals(StepPropertyEnum.CHANNEL_PUSH.getCode())&&step.getStatus().equals(StepEnum.COMPLETED.getMsg())&&step.getUserId1()!=null)
 //                        pushStep1 = step;
 
-                    if (step.getCode().equals(StepPropertyEnum.APPROVAL_ASSIGNMENT_2.getCode()) && step.getStatus().equals(StepEnum.UNSTART.getMsg())) {
-                        if (receiveStep != null) {
-                            currentSteps.add(receiveStep);
-                            ids.add(receiveStep.getCaseId());
-                            receiveStep = null;
-                        }
+                        if (step.getCode().equals(StepPropertyEnum.APPROVAL_ASSIGNMENT_2.getCode()) && step.getStatus().equals(StepEnum.UNSTART.getMsg())) {
+                            if (receiveStep != null) {
+                                currentSteps.add(receiveStep);
+                                ids.add(receiveStep.getCaseId());
+                                receiveStep = null;
+                            }
 
 //                        if (pushStep1!=null){
 //                            currentSteps.add(pushStep1);
 //                            ids.add(pushStep1.getCaseId());
 //                            pushStep1 = null;
 //                        }
+                        }
                     }
-                }
 
-                //保留取证
-                if (stepCode.equals(StepPropertyEnum.COLLATERAL_DELIVERY.getCode())) {
-                    if (step.getCode().equals(StepPropertyEnum.PLAN_SUBMISSION_2.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getUserId1() != null)
-                        receiveStep = step;
+                    //保留取证
+                    if (stepCode.equals(StepPropertyEnum.COLLATERAL_DELIVERY.getCode())) {
+                        if (step.getCode().equals(StepPropertyEnum.PLAN_SUBMISSION_2.getCode()) && step.getStatus().equals(StepEnum.COMPLETED.getMsg()) && step.getUserId1() != null)
+                            receiveStep = step;
 
 //                    if(step.getCode().equals(StepPropertyEnum.CHANNEL_PUSH_2.getCode())&&step.getStatus().equals(StepEnum.COMPLETED.getMsg())&&step.getUserId1()!=null)
 //                        pushStep2 = step;
 
-                    if (step.getCode().equals(StepPropertyEnum.REPAY_APPROVAL.getCode())) {
-                        if (receiveStep != null) {
-                            if (step.getStatus().equals(StepEnum.COMPLETED.getMsg())) {
-                                // 解析字符串为LocalDateTime
-                                LocalDateTime competeTime = LocalDateTime.parse(step.getUpdateTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).plusDays(7);
-                                //保留至指派后七天
-                                if (LocalDateTime.now().isBefore(competeTime)) {
-                                    System.out.println(LocalDateTime.now());
+                        if (step.getCode().equals(StepPropertyEnum.REPAY_APPROVAL.getCode())) {
+                            if (receiveStep != null) {
+                                if (step.getStatus().equals(StepEnum.COMPLETED.getMsg())) {
+                                    // 解析字符串为LocalDateTime
+                                    LocalDateTime competeTime = LocalDateTime.parse(step.getUpdateTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).plusDays(7);
+                                    //保留至指派后七天
+                                    if (LocalDateTime.now().isBefore(competeTime)) {
+                                        System.out.println(LocalDateTime.now());
+                                        currentSteps.add(receiveStep);
+                                        ids.add(receiveStep.getCaseId());
+                                        receiveStep = null;
+                                    }
+                                } else {
+                                    //未完成前也需要保存
                                     currentSteps.add(receiveStep);
                                     ids.add(receiveStep.getCaseId());
                                     receiveStep = null;
                                 }
-                            } else {
-                                //未完成前也需要保存
-                                currentSteps.add(receiveStep);
-                                ids.add(receiveStep.getCaseId());
-                                receiveStep = null;
-                            }
 
-                        }
+                            }
 
 //                        if (pushStep2!=null){
 //                            if(step.getStatus().equals(StepEnum.COMPLETED.getMsg())){
@@ -386,12 +403,15 @@ public class LoanServiceImpl implements LoanService {
 //                            }
 //
 //                        }
+                        }
                     }
+
                 }
 
             }
-
         }
+
+        List<LoanCaseVO> loanCaseVOS = new ArrayList<>();
         for (int i = 0; i < ids.size(); i++) {
             LoanCase loanCase = loanRepository.findLoanCaseById(ids.get(i), false);
 
@@ -444,7 +464,7 @@ public class LoanServiceImpl implements LoanService {
         customerIdMap.put(loanCaseDTO.getCustomer().getId(), loanCaseDTO.getCustomer().getId());
         //个数不变或新增
         CustomerDTO customers1 = loanCaseDTO.getCustomers1();
-        Long customerId1 = null;
+        Long customerId1 = null;//更新数据库后的id
         if (customers1 != null && customers1.getId() != null) {//对于其它借款人,有数据则传入后端
             customerId1 = customers1.getId();
             //id<0新增,否则更新
@@ -488,13 +508,25 @@ public class LoanServiceImpl implements LoanService {
         CustomerDTO customerDTO = loanCaseDTO.getCustomer();
         customerService.updateUserById(customerDTO, customerDTO.getId());
 
+        List<ContractDTO> contractDTOS = new ArrayList<>();
         for (ContractDTO contractDTO : loanCaseDTO.getContracts()) {
+            String[] split = contractDTO.getCustomerIds().split(",");
+            String customerIds = "";//更新的customerIds
+            for (String s : split){
+                customerIds = customerIds != "" ? (customerIds + "," + customerIdMap.get(Long.parseLong(s)) ) : String.valueOf(customerIdMap.get(Long.parseLong(s)));
+            }
+            contractDTO.setCustomerIds(customerIds);
+
             Long customerId = contractDTO.getCustomerId();
 
             if (customerIdMap.get(customerId) != null)//由-1变为实际
                 contractDTO.setCustomerId(customerIdMap.get(customerId));
-            else contractDTO.setCustomerId(null);
+            else
+                contractDTO.setCustomerId(null);
+
+            contractDTOS.add(contractDTO);
         }
+        loanCaseDTO.setContracts(contractDTOS);//设置新的contractDTOs
 
         RedisData redisData = new RedisData(stringRedisTemplate);
         redisData.delete(caseId);

+ 2 - 0
src/main/java/com/loan/system/service/Impl/LocationDatumServiceImpl.java

@@ -39,6 +39,8 @@ public class LocationDatumServiceImpl implements LocationDatumService {
 
     @Override
     public Long getNewId(LocationDatumDTO locationDatum) {
+        if (locationDatum == null)
+            return null;
         Long locationId = locationDatum.getId();
         if(locationDatum.getId() < 0) {
             LocationDatum locationDatum1 =save(locationDatum);

+ 4 - 3
src/main/java/com/loan/system/service/Impl/PawnTicketServiceImpl.java

@@ -20,16 +20,17 @@ public class PawnTicketServiceImpl implements PawnTicketService {
     }
 
     @Override
-    public void addPawnTicket(Map<Long, String> contractAndPawn,Long recordId,String createTime, Long caseId) {
+    public void addPawnTicket(Map<Long, String> contractAndPawn,Long recordId,Map<Long, Double> contractAndAmount,String createTime, Long caseId) {
         pawnTicketRepository.deleteByRecordId(recordId);
         Iterator<Map.Entry<Long, String>> iterator = contractAndPawn.entrySet().iterator();
         while (iterator.hasNext()) {
             Map.Entry<Long, String> entry = iterator.next();
             Long contractId = entry.getKey();
             String pawnTicketNo = entry.getValue();
+            Double amount = contractAndAmount.get(contractId) != null ? contractAndAmount.get(contractId) : 0.0;
 
             if (pawnTicketNo != null){
-                PawnTicketInfo pawnTicketInfo = new PawnTicketInfo(caseId, contractId,recordId, pawnTicketNo, createTime, null, null, false);
+                PawnTicketInfo pawnTicketInfo = new PawnTicketInfo(caseId, contractId,recordId, pawnTicketNo, amount,createTime, null, null, false);
                 pawnTicketRepository.save(pawnTicketInfo);
             }
         }
@@ -41,7 +42,7 @@ public class PawnTicketServiceImpl implements PawnTicketService {
     }
 
     @Override
-    public PawnTicketInfo findByContractIdAndIsDelete(Long contractId) {
+    public List<PawnTicketInfo> findByContractIdAndIsDelete(Long contractId) {
         return pawnTicketRepository.findByContractIdAndIsDelete(contractId, false);
     }
 

+ 117 - 55
src/main/java/com/loan/system/service/Impl/RepaymentServiceImpl.java

@@ -151,13 +151,13 @@ public class RepaymentServiceImpl implements RepaymentService {
         repaymentDetailVO.setTotalInterestAmount(totalInterestAmount);
 
         //填充
+        Double currentAmount = 0.0;
+        Double currentInterestAmount = 0.0;
         Repayment repayment = findByCaseIdAndIsDelete(caseId, false);
         if (!ObjectUtils.isEmpty(repayment)) {
             //获取所有回款记录
             List<RepaymentRecord> repaymentRecords = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
             List<RepaymentRecordVO> repaymentRecordVOS = new ArrayList<>();
-            Double currentAmount = 0.0;
-            Double currentInterestAmount = 0.0;
 
             //计算总的回款金额
             for (RepaymentRecord repaymentRecord : repaymentRecords) {
@@ -219,11 +219,11 @@ public class RepaymentServiceImpl implements RepaymentService {
 
             repaymentDetailVO.setDateAndAmounts(disbursementService.getDateAndAmount(caseId));
             repaymentDetailVO.setRepaymentRecords(repaymentRecordVOS);
-            repaymentDetailVO.setCurrentAmount(currentAmount);
-            repaymentDetailVO.setCurrentInterestAmount(currentInterestAmount);
-            repaymentDetailVO.setTotalAmount(repayment.getTotalAmount());
-        }
 
+        }
+        repaymentDetailVO.setCurrentAmount(currentAmount);
+        repaymentDetailVO.setCurrentInterestAmount(currentInterestAmount);
+        repaymentDetailVO.setActualTotalAmount(contractService.getActualTotalAmount(caseId));
 
         //押品状态
         List<CollateralVO> collateralVOS = collateralService.findByCaseId(caseId);
@@ -259,9 +259,9 @@ public class RepaymentServiceImpl implements RepaymentService {
         Customer customer1 = customerService.findByIdAndIsDelete(loanCase.getOtherId1());
         if (customer1 != null)
             customersName += customer1.getName();
-        Customer customer2 = customerService.findByIdAndIsDelete(loanCase.getOtherId1());
+        Customer customer2 = customerService.findByIdAndIsDelete(loanCase.getOtherId2());
         if (customer2 != null)
-            customersName += customer2.getName();
+            customersName = customersName.concat(",").concat(customer2.getName());
         loanCaseCompleteVO.setCustomersName(customersName);
         loanCaseCompleteVO.setBusinessType(loanCase.getBusinessType());
         loanCaseCompleteVO.setBusinessChannel(loanCase.getChannelName());
@@ -283,23 +283,6 @@ public class RepaymentServiceImpl implements RepaymentService {
             Double totalAmount = amounts.stream().reduce(0.0, (sum, amount) -> amount, Double::sum);
             loanCaseCompleteVO.setRepaymentTotalAmount(totalAmount-amounts.get(amounts.size()-1));
             loanCaseCompleteVO.setRepaymentLastAmount(amounts.get(amounts.size()-1));
-//            loanCaseCompleteVO.setRepaymentAmounts(records.stream()
-//                    .filter(record -> !record.getIsInterest())  // 筛选 isInterest 为 false 的记录
-//                    .map(RepaymentRecord::getAmount)
-//                    .collect(Collectors.toList()));
-//            loanCaseCompleteVO.setRepaymentDates(records.stream()
-//                    .filter(record -> !record.getIsInterest())
-//                    .map(RepaymentRecord::getRepayTime)
-//                    .collect(Collectors.toList()));
-//            Double totalAmount = records.stream().
-//                    filter(record -> !record.getIsInterest()).
-//                    reduce(0.0, (sum, record) -> sum + record.getAmount(), Double::sum);
-           // loanCaseCompleteVO.setRemainAmount(loanCase.getTotalLoanAmount() - totalAmount);
-
-//            loanCaseCompleteVO.setInterestAmount(records.stream()
-//                    .filter(RepaymentRecord::getIsInterest)  // 筛选 isInterest 为 false 的记录
-//                    .map(RepaymentRecord::getAmount)
-//                    .collect(Collectors.toList()));
             loanCaseCompleteVO.setInterestTotalAmount(records.stream().
                     reduce(0.0, (sum, record) -> sum + record.getInterestAmount(), Double::sum));
 
@@ -320,19 +303,32 @@ public class RepaymentServiceImpl implements RepaymentService {
         if (stepVO1 != null && stepVO1.getStatus().equals(StepEnum.COMPLETED.getMsg()))
             loanCaseCompleteVO.setClearedTime(stepVO1.getUpdateTime());
 
+        List<ContractCompleteVO> contractCompleteVOS =new ArrayList<>();
         List<ContractVO> contracts = contractService.findContractByCaseId(caseId);
-        List<PawnTicketInfo> byCaseIdAndIsDelete = pawnTicketService.findByCaseIdAndIsDelete(caseId);
-        Map<String, PawnTicketInfo> contractAndPawnList = new HashMap<>();
+        Map<Long, List<DateAndAmountPOJO>> dateAndAmount = disbursementService.getDateAndAmount(caseId);
         for (ContractVO contract : contracts) {
-            contractAndPawnList.put(contract.getContractNo(), null);
-            for (PawnTicketInfo pawnTicketInfo : byCaseIdAndIsDelete) {
-                if (contract.getId().equals(pawnTicketInfo.getContractId())) {
-                    contractAndPawnList.put(contract.getContractNo(), pawnTicketInfo);
-                    break;
-                }
+            ContractCompleteVO contractCompleteVO = new ContractCompleteVO();
+            contractCompleteVO.setContractNo(contract.getContractNo());
+            List<PawnTicketInfo> pawnTicketInfoList = pawnTicketService.findByContractIdAndIsDelete(contract.getId());
+            contractCompleteVO.setPawnTicketNoList(pawnTicketInfoList);
+            List<DateAndAmountPOJO> dateAndAmountPOJOs = dateAndAmount.get(contract.getId());
+            contractCompleteVO.setLoanDateList(dateAndAmountPOJOs.stream().map(DateAndAmountPOJO::getDate).collect(Collectors.toList()));
+            List<ContractRepayment> contractRepayments = contractRepaymentService.findByContractId(contract.getId());
+            if (contractRepayments != null){
+                Double lastAmount = contractRepayments.get(contractRepayments.size()-1).getAmount();
+                Double amount = contractRepayments.stream().reduce(0.0, (sum, contractRepayment) -> sum + contractRepayment.getAmount(), Double::sum);
+                contractCompleteVO.setRepaymentTotalAmount(amount-lastAmount);
+                contractCompleteVO.setRepaymentLastAmount(lastAmount);
+            }else {
+                contractCompleteVO.setRepaymentTotalAmount(0.0);
+                contractCompleteVO.setRepaymentLastAmount(0.0);
             }
+            contractCompleteVO.setInterestAmount(contract.getInterestAmount());
+            contractCompleteVO.setClearedTime(contract.getClearedTime());
+
+            contractCompleteVOS.add(contractCompleteVO);
         }
-        loanCaseCompleteVO.setContractAngPawnMap(contractAndPawnList);
+        loanCaseCompleteVO.setContractCompleteVOS(contractCompleteVOS);
 
         List<String> fileTypes=Arrays.asList("contractAttachment","idCard","customers1IdCard","customers2IdCard","businessLicense",
                 "marriageCertificate","householdRegister","propertyCertificate");
@@ -359,8 +355,6 @@ public class RepaymentServiceImpl implements RepaymentService {
             Repayment rep = new Repayment();
             rep.setCaseId(caseId);
             rep.setStartUserId(BaseContext.getCurrentId());
-            //rep.setTotalAmount(disbursementService.getDisbursementByCaseId(caseId).getPlannedAmount());
-            //TODO:后续更改为实际出款金额
             rep.setTotalAmount(loanService.findLoanCaseSimpleByIdAndIsDelete(caseId,false).getTotalLoanAmount());
 
             repayment = addRepayment(rep);
@@ -517,12 +511,16 @@ public class RepaymentServiceImpl implements RepaymentService {
         Long recordId = repaymentRecordDTO.getRecordId();
         Long repaymentId = findByCaseIdAndIsDelete(caseId, false).getId();
         RepaymentRecord record;
-        if (recordId < 0)
+        Double originalAmount = 0.0;
+        if (recordId < 0){
             record = repaymentRecordService.addRepaymentRecord(repaymentRecordDTO, repaymentId);
+            originalAmount = record.getAmount();
+        }
         else {
             record = repaymentRecordService.findByIdAndIsDelete(recordId);
             if(record.getRepayTime()!=null)
                 throw new DescribeException(ExceptionEnum.REPAYMENT_PLAN_HAS_COMPLETED);
+            originalAmount = record.getAmount();
 
             repaymentRecordService.updateRepaymentRecordById2(repaymentRecordDTO, recordId);
         }
@@ -530,13 +528,8 @@ public class RepaymentServiceImpl implements RepaymentService {
         //TODO:添加结清记录
         clearDetailService.addClearDetailByList(repaymentRecordDTO.getClearDetailList());
         //TODO:更新费息情况
-        if(repaymentRecordDTO.getInterestAmount()>Double.MIN_VALUE){
-            log.info("更新合同费息");
+        if(repaymentRecordDTO.getInterestAmount()>Double.MIN_VALUE)
             clearDetailService.updateInterestsByCaseId(repaymentRecordDTO.getContractIdAndInterestAmount(),caseId);
-        }
-
-        //添加完记录后,查看利息是否结清
-        contractIsCleared(repaymentId, repaymentRecordDTO.getClearInterest());
 
         Map<Long, Double> amountMap = repaymentRecordDTO.getContractIdAndAmount();
         Map<Long, Double> interestMap = repaymentRecordDTO.getContractIdAndInterestAmount();
@@ -546,14 +539,23 @@ public class RepaymentServiceImpl implements RepaymentService {
             Double amount = entry.getValue();
             Double interest = interestMap.getOrDefault(contractId, 0.0);//若没有这个键,则返回0.0
 
+            if (Math.abs(amount - originalAmount) > Double.MIN_VALUE){
+                //若计划发生修改,则修改合同-计划金额
+                contractRepaymentService.updateAmountByRecordIdAndContractId(amount,contractId,recordId);
+            }
             contractRepaymentService.addContractRepayment(record.getId(), contractId, caseId, 0.0, interest, record.getRepayTime());
         }
 
+        //添加完记录后,查看利息是否结清
+        contractIsCleared(repaymentId, repaymentRecordDTO.getClearInterest());
+
         repayBankInfoService.addRepayBankInfo(repaymentRecordDTO.getRepayBankInfoList(), record.getId());
 
-        stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.BALANCE_REPAY.getCode(), BaseContext.getCurrentId(), caseId);
-        if (interestIsCleared(findByCaseIdAndIsDelete(caseId, false).getId(),caseId))//当全部的合同的费息都完成时才结束环节
+        if (interestIsCleared(findByCaseIdAndIsDelete(caseId, false).getId(),caseId)){
+            //当全部的合同的费息都完成时才结束环节
             stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
+            stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.AUTO_REPAY.getCode(), caseId);
+        }
 
         stepService.tryStartStep(StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
 
@@ -610,12 +612,69 @@ public class RepaymentServiceImpl implements RepaymentService {
 //        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
     }
 
+    @Override
+    public void autoRepay(RepaymentRecordDTO repaymentRecordDTO, Long caseId) {
+        Repayment repayment = findByCaseIdAndIsDelete(caseId, false);
+        if (ObjectUtils.isEmpty(repayment)) {
+            Repayment rep = new Repayment();
+            rep.setCaseId(caseId);
+            rep.setStartUserId(BaseContext.getCurrentId());
+            //TODO:后续更改为实际出款金额
+            rep.setTotalAmount(loanService.findLoanCaseSimpleByIdAndIsDelete(caseId,false).getTotalLoanAmount());
+
+            repayment = addRepayment(rep);
+
+        }
+        //TODO:可能只回本金,可能只回利息,可能一起回
+        Long repaymentId = repayment.getId();
+        RepaymentRecord record = repaymentRecordService.addRepaymentRecord(repaymentRecordDTO, repaymentId);
+
+        //TODO:添加结清记录
+        clearDetailService.addClearDetailByList(repaymentRecordDTO.getClearDetailList());
+        //TODO:更新费息情况
+        if(repaymentRecordDTO.getInterestAmount()>Double.MIN_VALUE)
+            clearDetailService.updateInterestsByCaseId(repaymentRecordDTO.getContractIdAndInterestAmount(),caseId);
+
+        Map<Long, Double> amountMap = repaymentRecordDTO.getContractIdAndAmount();
+        Map<Long, Double> interestMap = repaymentRecordDTO.getContractIdAndInterestAmount();
+
+        for (Map.Entry<Long, Double> entry : amountMap.entrySet()) {
+            Long contractId = entry.getKey();
+            Double amount = entry.getValue();
+            Double interest = interestMap.getOrDefault(contractId, 0.0);//若没有这个键,则返回0.0
+
+            contractRepaymentService.addContractRepayment(record.getId(), contractId, caseId, amount, interest, record.getRepayTime());
+        }
+
+        //添加完记录后,查看利息是否结清
+        contractIsCleared(repaymentId, repaymentRecordDTO.getClearInterest());
+
+        repayBankInfoService.addRepayBankInfo(repaymentRecordDTO.getRepayBankInfoList(), record.getId());
+
+        stepService.updateUserId1ByCaseIdAndStepCode(StepPropertyEnum.AUTO_REPAY.getCode(), BaseContext.getCurrentId(), caseId);
+        if (interestIsCleared(repaymentId,caseId)){
+            //当全部的合同的费息都完成时才结束环节
+            stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.BALANCE_REPAY.getCode(), caseId);
+            stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.AUTO_REPAY.getCode(), caseId);
+        }
+
+        stepService.tryStartStep(StepPropertyEnum.AUTO_REPAY.getCode(), caseId);
+
+    }
+
     //TODO:用于判断总的金额是否结清
     private Boolean isCleared(Long caseId, Integer StepCode) {
         Repayment repayment = findByCaseIdAndIsDelete(caseId, false);
         //获取回款记录
         List<RepaymentRecord> repaymentRecords = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
-        Double totalAmount = findByCaseIdAndIsDelete(caseId, false).getTotalAmount();
+        //Double totalAmount = findByCaseIdAndIsDelete(caseId, false).getTotalAmount();
+        Double totalAmount = 0.0;
+        List<ContractVO> contracts = contractService.findContractByCaseId(caseId);
+        for (ContractVO contract : contracts){
+            if(!contract.getIsDisbursementComplete())//true表示合同的实际金额已敲定
+                return false;
+            totalAmount += contract.getActualAmount();
+        }
 
         Double currentAmount = 0.0;
         for (RepaymentRecord repaymentRecord : repaymentRecords)
@@ -655,9 +714,13 @@ public class RepaymentServiceImpl implements RepaymentService {
             }
 
             //3.
-            Double contractAmount = contractService.findContractById(contractId).getContractAmount();
-            if (Math.abs(amount - contractAmount) < Double.MIN_VALUE){
-                contractService.updateRepayById(DecisionEnum.CLEAR_AMOUNT_YES.getMsg(), interest, null, contractId, false);
+            Contract contract = contractService.findContractById(contractId);
+            if(contract.getIsDisbursementComplete()){//表示实际出款完成
+                Double actualAmount = contract.getActualAmount();
+                if (Math.abs(amount - actualAmount) < Double.MIN_VALUE){
+                    //不按合同结清更新利息的话,会出现设置三个利息且把这三个利息都还完,环节就结束了
+                    contractService.updateRepayById(DecisionEnum.CLEAR_AMOUNT_YES.getMsg(), interest, null, contractId, false);
+                }
             }
 
         }
@@ -670,15 +733,14 @@ public class RepaymentServiceImpl implements RepaymentService {
      * */
     private Boolean interestIsCleared(Long repaymentId,Long caseId) {
         //1.
-        List<RepaymentRecord> repaymentRecords = repaymentRecordService.findByRepaymentIdAndIsInterestAndIsDelete(repaymentId, false);
+        List<RepaymentRecord> repaymentRecords = repaymentRecordService.findByRepaymentIdAndIsDelete(repaymentId, false);
         List<Long> recordIds = repaymentRecords.stream().map(RepaymentRecord::getId).collect(Collectors.toList());
         List<ContractRepayment> contractRepayments = contractRepaymentService.findByRepaymentRecordIdsAndIsDelete(recordIds);
-
         //2.
         //List<Long> contractIds = contractRepayments.stream().map(ContractRepayment::getContractId).collect(Collectors.toList());
-        List<Long> contractIds =contractService.findIdsByCaseId(caseId);
-        for (Long contractId : contractIds) {//计算每个合同的结清状态
-            Contract contract = contractService.findContractById(contractId);
+        List<Contract> contractList = contractService.findContractByCaseId2(caseId);
+        for (Contract contract : contractList) {//计算每个合同的结清状态
+            Long contractId = contract.getId();
             if (contract.getClearedStatus().equals(DecisionEnum.CLEAR_NOT.getMsg()))//本金未结清,利息一定也没有
                 return false;
             double interest = 0.0;
@@ -688,7 +750,7 @@ public class RepaymentServiceImpl implements RepaymentService {
             }
 
             //3.
-            double gap = Math.abs(interest - contractService.findContractById(contractId).getInterestAmount());
+            double gap = Math.abs(interest - contract.getInterestAmount());
             if (gap> Double.MIN_VALUE)
                 return false;
 

+ 9 - 8
src/main/java/com/loan/system/service/Impl/StepServiceImpl.java

@@ -171,19 +171,15 @@ public class StepServiceImpl implements StepService {
                 Step s = stepRepository.findByCodeAndCaseId(Integer.parseInt(preCode), caseId);
                 if (!s.getStatus().equals(StepEnum.COMPLETED.getMsg())){
 
-//                    List<StepPropertyEnum> stepPropertyEnums1= Arrays.asList(StepPropertyEnum.REPAY_START,StepPropertyEnum.REPAY_APPROVAL,StepPropertyEnum.PLAN_SUBMISSION,StepPropertyEnum.PLAN_SUBMISSION_2,
-//                            StepPropertyEnum.APPROVAL_ASSIGNMENT,StepPropertyEnum.APPROVAL_ASSIGNMENT_2,StepPropertyEnum.EVIDENCE_CONFIRMATION,StepPropertyEnum.DELIVERY_CONFIRMATION,
-//                            StepPropertyEnum.CHANNEL_PUSH,StepPropertyEnum.CHANNEL_PUSH_2,StepPropertyEnum.FINANCE_CHECK,StepPropertyEnum.BALANCE_REPAY);
-//                    List<StepPropertyEnum> stepPropertyEnums2= Arrays.asList(StepPropertyEnum.REPAY_APPROVAL,StepPropertyEnum.FINANCE_CHECK,StepPropertyEnum.APPROVAL_ASSIGNMENT,StepPropertyEnum.APPROVAL_ASSIGNMENT_2,
-//                            StepPropertyEnum.EVIDENCE_CONFIRMATION,StepPropertyEnum.DELIVERY_CONFIRMATION,StepPropertyEnum.CHANNEL_PUSH,StepPropertyEnum.CHANNEL_PUSH_2,
-//                            StepPropertyEnum.CHANNEL_CONFIRMATION,StepPropertyEnum.CHANNEL_RECEIVE,StepPropertyEnum.BALANCE_REPAY,StepPropertyEnum.FINANCE_CONFIRM);
+                    if (currentStep.getCode().equals(StepPropertyEnum.FINANCE_CONFIRM.getCode()))
+                        break;
 
                     List<StepPropertyEnum> stepPropertyEnums1= Arrays.asList(StepPropertyEnum.PLAN_REPORT,StepPropertyEnum.PLAN_AUDIT,StepPropertyEnum.DISBURSE_START,
-                            StepPropertyEnum.DISBURSE_AUDIT,StepPropertyEnum.FINANCE_DISBURSE,
+                            StepPropertyEnum.DISBURSE_AUDIT,StepPropertyEnum.FINANCE_DISBURSE,StepPropertyEnum.AUTO_REPAY,
                             StepPropertyEnum.REPAY_START,StepPropertyEnum.REPAY_APPROVAL,StepPropertyEnum.BALANCE_REPAY,StepPropertyEnum.PLAN_SUBMISSION,StepPropertyEnum.PLAN_SUBMISSION_2,
                             StepPropertyEnum.APPROVAL_ASSIGNMENT,StepPropertyEnum.APPROVAL_ASSIGNMENT_2);
                     List<StepPropertyEnum> stepPropertyEnums2= Arrays.asList(StepPropertyEnum.PLAN_AUDIT,StepPropertyEnum.DISBURSE_START, StepPropertyEnum.DISBURSE_AUDIT,
-                            StepPropertyEnum.FINANCE_DISBURSE,StepPropertyEnum.DISBURSE_CONFIRM,
+                            StepPropertyEnum.FINANCE_DISBURSE,StepPropertyEnum.DISBURSE_CONFIRM,StepPropertyEnum.FINANCE_CONFIRM,
                             StepPropertyEnum.REPAY_APPROVAL,StepPropertyEnum.BALANCE_REPAY,StepPropertyEnum.FINANCE_CONFIRM,StepPropertyEnum.APPROVAL_ASSIGNMENT,StepPropertyEnum.APPROVAL_ASSIGNMENT_2,
                             StepPropertyEnum.EVIDENCE_CONFIRMATION,StepPropertyEnum.DELIVERY_CONFIRMATION);
                     //回款上报与审核可以多次
@@ -402,4 +398,9 @@ public class StepServiceImpl implements StepService {
         List<Step> steps = stepRepository.getChildStepByCaseIdBeforeTime(id,time,false);
         return BeanUtil.copyToList(steps, StepVO.class);
     }
+
+    @Override
+    public List<StepVO> listByStepCodeAndCaseIds(List<Long> ids, Integer stepCode) {
+        return BeanUtil.copyToList(stepRepository.findByCaseIdsAndCode(ids,stepCode), StepVO.class);
+    }
 }

+ 2 - 2
src/main/java/com/loan/system/service/Impl/UserServiceImpl.java

@@ -265,7 +265,7 @@ public class UserServiceImpl implements UserService {
             Long caseId = loanCaseVO.getId();
 
             StepVO stepVO = stepService.findByStepCodeAndCaseId(stepCode, caseId);
-            if ((stepCode.equals(StepPropertyEnum.DISBURSE_START.getCode()) || stepCode.equals(StepPropertyEnum.BALANCE_REPAY.getCode()))
+            if (stepVO!=null &&(stepCode.equals(StepPropertyEnum.DISBURSE_START.getCode()) || stepCode.equals(StepPropertyEnum.BALANCE_REPAY.getCode()))
                     && stepVO.getStatus().equals(StepEnum.PROCESS.getMsg())) {
                 Long userId = stepVO.getUserId1();
                 if (userId != null) { // 修复:确保userId不为null
@@ -274,7 +274,7 @@ public class UserServiceImpl implements UserService {
                             .add(loanCaseVO);
                 }
 
-            } else if ((stepCode.equals(StepPropertyEnum.EVIDENCE_CONFIRMATION.getCode()) || stepCode.equals(StepPropertyEnum.DELIVERY_CONFIRMATION.getCode()))
+            } else if (stepVO!=null &&(stepCode.equals(StepPropertyEnum.EVIDENCE_CONFIRMATION.getCode()) || stepCode.equals(StepPropertyEnum.DELIVERY_CONFIRMATION.getCode()))
                     && stepVO.getStatus().equals(StepEnum.PROCESS.getMsg())) {
                 //环节未完成且近两天且计划处于待执行
                 List<CollateralPlan> collateralPlans = collateralPlanService.findByCaseIdAndIsDelete(caseId, false);

+ 2 - 2
src/main/java/com/loan/system/service/PawnTicketService.java

@@ -6,11 +6,11 @@ import java.util.List;
 import java.util.Map;
 
 public interface PawnTicketService {
-    void addPawnTicket(Map<Long, String> contractAndPawn, Long recordId, String createTime,Long caseId);
+    void addPawnTicket(Map<Long, String> contractAndPawn, Long recordId,Map<Long, Double> contractAndAmount, String createTime,Long caseId);
 
     List<PawnTicketInfo> findByCaseIdAndIsDelete(Long caseId);
 
-    PawnTicketInfo findByContractIdAndIsDelete(Long contractId);
+    List<PawnTicketInfo> findByContractIdAndIsDelete(Long contractId);
 
     void updateRedeemTicketNoByPawnTicketNo(String redeemTicketNo, String pawnTicketNo);
 

+ 1 - 0
src/main/java/com/loan/system/service/RepaymentService.java

@@ -44,4 +44,5 @@ public interface RepaymentService {
 
     void financeConfirm(List<Long> recordIds, Long caseId, String comment);
 
+    void autoRepay(RepaymentRecordDTO repaymentRecordDTO, Long caseId);
 }

+ 2 - 0
src/main/java/com/loan/system/service/StepService.java

@@ -52,4 +52,6 @@ public interface StepService {
     void updateStatusByCaseIdAndParentCode(String msg, int code, Long caseId);
 
     List<StepVO> getChildStepByCaseIdBeforeTime(Long id, String time);
+
+    List<StepVO> listByStepCodeAndCaseIds(List<Long> ids, Integer stepCode);
 }

+ 14 - 11
src/main/java/com/loan/system/utils/EsignSdkUtil.java

@@ -7,6 +7,8 @@ import cn.hutool.json.JSONUtil;
 import cn.hutool.core.util.StrUtil;
 import lombok.extern.slf4j.Slf4j;
 
+import java.util.Objects;
+
 /**
  * e签宝OAuth2.0鉴权工具类
  * 
@@ -38,17 +40,21 @@ public class EsignSdkUtil {
      * @return 访问令牌(access_token)
      */
     public static String getAccessToken(String appId, String appSecret, String apiUrl) {
-        // 缓存配置信息
-        cachedAppId = appId;
-        cachedAppSecret = appSecret;
-        cachedApiUrl = apiUrl;
-        
-        // 检查缓存的token是否仍然有效(提前5分钟刷新)
-        if (cachedToken != null && System.currentTimeMillis() < (tokenExpireTime - 5 * 60 * 1000)) {
+        // 检查是否需要重新获取token(缓存失效或配置信息改变)
+        if (cachedToken != null && 
+            System.currentTimeMillis() < (tokenExpireTime - 5 * 60 * 1000) &&
+            Objects.equals(cachedAppId, appId) &&
+            Objects.equals(cachedAppSecret, appSecret) &&
+            Objects.equals(cachedApiUrl, apiUrl)) {
             log.debug("使用缓存的e签宝OAuth2.0访问令牌");
             return cachedToken;
         }
         
+        // 更新缓存的配置信息
+        cachedAppId = appId;
+        cachedAppSecret = appSecret;
+        cachedApiUrl = apiUrl;
+        
         try {
             // OAuth2.0客户端凭证模式获取token
             // 标准请求:POST /v1/oauth2/access_token
@@ -83,8 +89,6 @@ public class EsignSdkUtil {
 
                             log.info("获取e签宝OAuth2.0访问令牌成功,有效期:{}秒", expiresIn);
                             return token;
-
-
                         }
                     }
                 } else {
@@ -132,5 +136,4 @@ public class EsignSdkUtil {
     public static boolean isTokenExpired() {
         return cachedToken == null || System.currentTimeMillis() >= tokenExpireTime;
     }
-}
-
+}

+ 28 - 24
src/main/java/com/loan/system/utils/RedisData.java

@@ -56,31 +56,35 @@ public class RedisData {
 
         List<ContractDTO> contractVOS = loanCaseDTO.getContracts();
         List<Contract> contracts = new ArrayList<>();
-        if(!ObjectUtils.isEmpty( contractVOS)){
-            contracts = BeanUtil.copyToList(contractVOS, Contract.class);
-            for (Contract contract : contracts) {
-                Long id = timestamp<<20 | index;
-                if (contract.getId() == null)
-                    //contract.setId(-id);
-                    continue;
-                String name=contract.getBusinessAttr().equals(BusinessAttrEnum.ESTATE_MORTGAGE.getMsg())?"抵押合同":"质押合同";
-                contract.setContractName("浙江宝路同典当"+name);
-                if(contract.getContractNo()==null)
-                    contract.setContractNo("临时编号:"+UUID.randomUUID().toString().replace("-",""));
-                contract.setIsDelete(false);
-                contract.setSignedByCustomer(false);
-                contract.setIsPush( false);
-
-                contract.setCreateTime(LocalDateTime.now()
-                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-                contract.setUpdateTime(LocalDateTime.now()
-                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-                contract.setIsDelete(false);
-
-                index++;
-            }
-            stringRedisTemplate.opsForValue().set(contractKey, JSONUtil.toJsonStr(contracts));
+        for (ContractDTO contractDTO : contractVOS){
+            Contract contract = BeanUtil.copyProperties(contractDTO, Contract.class);
+            Long id = timestamp<<20 | index;
+            if (contract.getId() == null)
+                //contract.setId(-id);
+                continue;
+            String[] split = contractDTO.getCustomerIds().split(",");
+
+            contract.setCustomerId(split.length>0?Long.valueOf(split[0]):null);
+            contract.setCustomerId1(split.length>1?Long.valueOf(split[1]):null);
+            contract.setCustomerId2(split.length>2?Long.valueOf(split[2]):null);
+            String name=contract.getBusinessAttr().equals(BusinessAttrEnum.ESTATE_MORTGAGE.getMsg())?"抵押合同":"质押合同";
+            contract.setContractName("浙江宝路同典当"+name);
+            if(contract.getContractNo()==null)
+                contract.setContractNo("临时编号:"+UUID.randomUUID().toString().replace("-",""));
+            contract.setIsDelete(false);
+            contract.setSignedByCustomer(false);
+            contract.setIsPush( false);
+
+            contract.setCreateTime(LocalDateTime.now()
+                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            contract.setUpdateTime(LocalDateTime.now()
+                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            contract.setIsDelete(false);
+
+            contracts.add( contract);
+            index++;
         }
+        stringRedisTemplate.opsForValue().set(contractKey, JSONUtil.toJsonStr(contracts));
 
         List<CollateralDTO> collateralVOS = loanCaseDTO.getCollateral();
         List<Long> collateralIds = new ArrayList<>();