Jelajahi Sumber

第二次合并前提交(10-29)

25057 5 bulan lalu
induk
melakukan
07b28f83e5
92 mengubah file dengan 3273 tambahan dan 455 penghapusan
  1. 10 10
      pom.xml
  2. 26 24
      src/main/java/com/loan/system/config/WebMvcConfiguration.java
  3. 179 0
      src/main/java/com/loan/system/controller/admin/AdminController.java
  4. 42 0
      src/main/java/com/loan/system/controller/admin/RecommenderController.java
  5. 94 49
      src/main/java/com/loan/system/controller/wechat/ApprovalController.java
  6. 145 21
      src/main/java/com/loan/system/controller/wechat/ContractController.java
  7. 55 0
      src/main/java/com/loan/system/controller/wechat/CustomerController.java
  8. 12 0
      src/main/java/com/loan/system/controller/wechat/DictionaryController.java
  9. 434 39
      src/main/java/com/loan/system/controller/wechat/DisbursementController.java
  10. 69 56
      src/main/java/com/loan/system/controller/wechat/LoanController.java
  11. 57 0
      src/main/java/com/loan/system/controller/wechat/MessageController.java
  12. 406 2
      src/main/java/com/loan/system/controller/wechat/RepaymentController.java
  13. 128 0
      src/main/java/com/loan/system/controller/wechat/StatisticsController.java
  14. 90 57
      src/main/java/com/loan/system/controller/wechat/UploadController.java
  15. 26 28
      src/main/java/com/loan/system/controller/wechat/UserController.java
  16. 28 0
      src/main/java/com/loan/system/domain/dto/BizRecommenderDTO.java
  17. 2 2
      src/main/java/com/loan/system/domain/dto/ContractDTO.java
  18. 4 4
      src/main/java/com/loan/system/domain/dto/DisbursementDTO.java
  19. 1 2
      src/main/java/com/loan/system/domain/dto/DisbursementRecordDTO.java
  20. 22 0
      src/main/java/com/loan/system/domain/dto/RepaymentRecordDTO.java
  21. 23 0
      src/main/java/com/loan/system/domain/dto/UserDTO.java
  22. 5 16
      src/main/java/com/loan/system/domain/entity/BizRecommender.java
  23. 3 7
      src/main/java/com/loan/system/domain/entity/Contract.java
  24. 3 0
      src/main/java/com/loan/system/domain/entity/Customer.java
  25. 3 3
      src/main/java/com/loan/system/domain/entity/Disbursement.java
  26. 4 1
      src/main/java/com/loan/system/domain/entity/DisbursementRecord.java
  27. 16 26
      src/main/java/com/loan/system/domain/entity/Repayment.java
  28. 31 6
      src/main/java/com/loan/system/domain/entity/RepaymentRecord.java
  29. 2 2
      src/main/java/com/loan/system/domain/entity/StatBusinessSnapshot.java
  30. 2 2
      src/main/java/com/loan/system/domain/entity/StatFundEfficiency.java
  31. 9 6
      src/main/java/com/loan/system/domain/entity/SysMessage.java
  32. 13 8
      src/main/java/com/loan/system/domain/enums/ExceptionEnum.java
  33. 38 0
      src/main/java/com/loan/system/domain/enums/MessageEnum.java
  34. 7 7
      src/main/java/com/loan/system/domain/enums/RoleEnum.java
  35. 11 8
      src/main/java/com/loan/system/domain/enums/StepPropertyEnum.java
  36. 42 0
      src/main/java/com/loan/system/domain/pojo/ContractInformation.java
  37. 20 0
      src/main/java/com/loan/system/domain/vo/ApprovalVO.java
  38. 28 0
      src/main/java/com/loan/system/domain/vo/BizRecommenderVO.java
  39. 2 2
      src/main/java/com/loan/system/domain/vo/ContractVO.java
  40. 1 0
      src/main/java/com/loan/system/domain/vo/CustomerVO.java
  41. 22 0
      src/main/java/com/loan/system/domain/vo/DictionarysVO.java
  42. 31 0
      src/main/java/com/loan/system/domain/vo/DisbursementDetailVO.java
  43. 27 0
      src/main/java/com/loan/system/domain/vo/DisbursementRecordVO.java
  44. 2 1
      src/main/java/com/loan/system/domain/vo/DisbursementVO.java
  45. 25 0
      src/main/java/com/loan/system/domain/vo/LoanCaseSimpleVO.java
  46. 2 3
      src/main/java/com/loan/system/domain/vo/LoanCaseVO.java
  47. 27 0
      src/main/java/com/loan/system/domain/vo/RepaymentDetailVO.java
  48. 32 0
      src/main/java/com/loan/system/domain/vo/RepaymentRecordVO.java
  49. 30 0
      src/main/java/com/loan/system/domain/vo/SysMessageVO.java
  50. 24 0
      src/main/java/com/loan/system/domain/vo/UserVO.java
  51. 123 0
      src/main/java/com/loan/system/interceptor/JwtTokenAdminInterceptor.java
  52. 2 1
      src/main/java/com/loan/system/interceptor/JwtTokenUserInterceptor.java
  53. 4 0
      src/main/java/com/loan/system/repository/ContractRepository.java
  54. 7 5
      src/main/java/com/loan/system/repository/CustomerRepository.java
  55. 20 0
      src/main/java/com/loan/system/repository/DisbursementRecordRepository.java
  56. 20 0
      src/main/java/com/loan/system/repository/DisbursementRepository.java
  57. 2 2
      src/main/java/com/loan/system/repository/DocumentRepository.java
  58. 5 1
      src/main/java/com/loan/system/repository/LoanRepository.java
  59. 19 0
      src/main/java/com/loan/system/repository/MessageRepository.java
  60. 24 0
      src/main/java/com/loan/system/repository/RecommenderRepository.java
  61. 34 0
      src/main/java/com/loan/system/repository/RepaymentRecordRepository.java
  62. 41 0
      src/main/java/com/loan/system/repository/RepaymentRepository.java
  63. 19 1
      src/main/java/com/loan/system/repository/UserRepository.java
  64. 1 0
      src/main/java/com/loan/system/service/ApprovalService.java
  65. 1 1
      src/main/java/com/loan/system/service/ContractAndCollateralService.java
  66. 2 0
      src/main/java/com/loan/system/service/ContractService.java
  67. 5 2
      src/main/java/com/loan/system/service/CustomerService.java
  68. 12 0
      src/main/java/com/loan/system/service/DisbursementRecordService.java
  69. 11 0
      src/main/java/com/loan/system/service/DisbursementService.java
  70. 2 0
      src/main/java/com/loan/system/service/DocumentService.java
  71. 1 1
      src/main/java/com/loan/system/service/Impl/ApprovalServiceImpl.java
  72. 2 1
      src/main/java/com/loan/system/service/Impl/ContractAndCollateralServiceImpl.java
  73. 15 6
      src/main/java/com/loan/system/service/Impl/ContractServiceImpl.java
  74. 18 4
      src/main/java/com/loan/system/service/Impl/CustomerServiceImpl.java
  75. 40 0
      src/main/java/com/loan/system/service/Impl/DisbursementRecordServiceImpl.java
  76. 41 2
      src/main/java/com/loan/system/service/Impl/DisbursementServiceImpl.java
  77. 6 1
      src/main/java/com/loan/system/service/Impl/DocumentServiceImpl.java
  78. 42 8
      src/main/java/com/loan/system/service/Impl/LoanServiceImpl.java
  79. 41 0
      src/main/java/com/loan/system/service/Impl/MessageServiceImpl.java
  80. 56 0
      src/main/java/com/loan/system/service/Impl/RecommenderServiceImpl.java
  81. 55 0
      src/main/java/com/loan/system/service/Impl/RepaymentRecordServiceImpl.java
  82. 57 0
      src/main/java/com/loan/system/service/Impl/RepaymentServiceImpl.java
  83. 48 4
      src/main/java/com/loan/system/service/Impl/UserServiceImpl.java
  84. 7 2
      src/main/java/com/loan/system/service/LoanService.java
  85. 15 0
      src/main/java/com/loan/system/service/MessageService.java
  86. 17 0
      src/main/java/com/loan/system/service/RecommenderService.java
  87. 19 0
      src/main/java/com/loan/system/service/RepaymentRecordService.java
  88. 17 0
      src/main/java/com/loan/system/service/RepaymentService.java
  89. 14 2
      src/main/java/com/loan/system/service/UserService.java
  90. 91 17
      src/main/java/com/loan/system/utils/PoiWordUtil.java
  91. 2 2
      src/main/resources/application-dev.yaml
  92. TEMPAT SAMPAH
      src/main/resources/file_store/template/template1.docx

+ 10 - 10
pom.xml

@@ -69,16 +69,16 @@
 
 
         <!-- Apache POI 最新稳定版 -->
-        <dependency>
-            <groupId>org.apache.poi</groupId>
-            <artifactId>poi</artifactId>
-            <version>3.16</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.poi</groupId>
-            <artifactId>poi-ooxml</artifactId>
-            <version>3.16</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.apache.poi</groupId>-->
+<!--            <artifactId>poi</artifactId>-->
+<!--            <version>3.16</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>org.apache.poi</groupId>-->
+<!--            <artifactId>poi-ooxml</artifactId>-->
+<!--            <version>3.16</version>-->
+<!--        </dependency>-->
 
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>

+ 26 - 24
src/main/java/com/loan/system/config/WebMvcConfiguration.java

@@ -1,5 +1,6 @@
 package com.loan.system.config;
 
+import com.loan.system.interceptor.JwtTokenAdminInterceptor;
 import com.loan.system.interceptor.JwtTokenUserInterceptor;
 import com.loan.system.json.JacksonObjectMapper;
 import lombok.extern.slf4j.Slf4j;
@@ -27,8 +28,8 @@ import java.util.List;
 @Slf4j
 public class WebMvcConfiguration extends WebMvcConfigurationSupport {
 
-//    @Autowired
-//    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
+    @Autowired
+    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
     @Autowired
     private JwtTokenUserInterceptor jwtTokenUserInterceptor;
 
@@ -38,9 +39,9 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
      */
     protected void addInterceptors(InterceptorRegistry registry) {
         log.info("开始注册自定义拦截器...");
-//        registry.addInterceptor(jwtTokenAdminInterceptor)
-//                .addPathPatterns("/admin/**")
-//                .excludePathPatterns("/admin/employee/login");
+        registry.addInterceptor(jwtTokenAdminInterceptor)
+                .addPathPatterns("/admin/**")
+                .excludePathPatterns("/admin/login");
 
         registry.addInterceptor(jwtTokenUserInterceptor)
                 .addPathPatterns("/wechat/**")
@@ -54,24 +55,24 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
      * 3.设置静态资源映射,否则接口文档页面无法访问
      * @return
      */
-//    @Bean
-//    public Docket docket1() {
-//        log.info("准备生成接口文件");
-//        ApiInfo apiInfo = new ApiInfoBuilder()
-//                .title("苍穹外卖项目接口文档")
-//                .version("2.0")
-//                .description("苍穹外卖项目接口文档")
-//                .build();
-//        Docket docket = new Docket(DocumentationType.SWAGGER_2)
-//                .groupName("管理端接口")
-//                .apiInfo(apiInfo)
-//                .select()
-//                //最重要:确定要扫描的包
-//                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
-//                .paths(PathSelectors.any())
-//                .build();
-//        return docket;
-//    }
+    @Bean
+    public Docket docket1() {
+        log.info("准备生成接口文件");
+        ApiInfo apiInfo = new ApiInfoBuilder()
+                .title("典当项目接口文档")
+                .version("2.0")
+                .description("典当项目接口文档")
+                .build();
+        Docket docket = new Docket(DocumentationType.SWAGGER_2)
+                .groupName("管理端接口")
+                .apiInfo(apiInfo)
+                .select()
+                //最重要:确定要扫描的包
+                .apis(RequestHandlerSelectors.basePackage("com.loan.system.controller.admin"))
+                .paths(PathSelectors.any())
+                .build();
+        return docket;
+    }
 
     @Bean
     public Docket docket2() {
@@ -99,7 +100,8 @@ public class WebMvcConfiguration extends WebMvcConfigurationSupport {
     protected void addResourceHandlers(ResourceHandlerRegistry registry) {
         log.info("设置静态资源映射");
         registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");
-        registry.addResourceHandler("/files/**").addResourceLocations("classpath:/META-INF/resources/file_store/");
+        registry.addResourceHandler("/wechat/files/**").addResourceLocations("classpath:/META-INF/resources/file_store/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
     }
 
     /*

+ 179 - 0
src/main/java/com/loan/system/controller/admin/AdminController.java

@@ -0,0 +1,179 @@
+package com.loan.system.controller.admin;
+
+import com.loan.system.constant.JwtClaimsConstant;
+import com.loan.system.domain.dto.UserDTO;
+import com.loan.system.domain.dto.UserLoginDTO;
+import com.loan.system.domain.entity.Role;
+import com.loan.system.domain.entity.User;
+import com.loan.system.domain.enums.ExceptionEnum;
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.UserLoginVO;
+import com.loan.system.properties.JwtProperties;
+import com.loan.system.repository.RoleRepository;
+import com.loan.system.service.CustomerService;
+import com.loan.system.service.Impl.UserServiceImpl;
+import com.loan.system.service.UserService;
+import com.loan.system.service.WxService;
+import com.loan.system.utils.JwtUtil;
+import com.loan.system.utils.ResultUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.ObjectUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Edwin
+ * @date 2020/9/2 - 19:11
+ */
+@RestController
+@RequestMapping("/admin")
+@Api(tags = "管理端用户接口")
+public class AdminController {//包含内部人员、外部人员
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private JwtProperties jwtProperties;
+
+    @Autowired
+    private RoleRepository roleRepository;
+
+    @Autowired
+    private CustomerService customerService;
+
+    @Autowired
+    private WxService wxService;
+
+    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
+
+    /*
+    1.先查询user查看是否为内部人员
+    2.若不是内部人员,查询外部人员
+    3.外部人员也不存在,进行注册(因为小程序端直接获取手机号,任何用户都可以登录)
+     */
+    @PostMapping("/login")
+    @ApiOperation("管理端登陆")
+    public Result login(@RequestBody UserLoginDTO userLoginDTO){
+
+        //账号密码验证
+        User user = userService.getUserByMobile(userLoginDTO.getTel());
+        UserLoginVO userLoginVO = new UserLoginVO();
+
+        //为微信用户生成jwt令牌
+        Map<String ,Object> claims=new HashMap<>();
+        Long userId = null;
+
+        if (!ObjectUtils.isEmpty(user)){
+            userLoginVO.setId(user.getId());
+            userLoginVO.setRole(user.getRole());
+        }else{
+            return ResultUtil.error(ExceptionEnum.USER_NOT_EXIST);
+        }
+
+        claims.put(JwtClaimsConstant.USER_ID,userLoginVO.getId());
+        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);
+        userLoginVO.setToken(token);
+
+        return ResultUtil.success("success", userLoginVO);
+    }
+
+//    @PostMapping("/login")
+//    @ApiOperation("账号登陆")
+//    public Result login(@RequestBody UserLoginDTO userLoginDTO){
+//        String phoneNumber=userLoginDTO.getTel();
+//        boolean user_is_exist = userService.existsByMobileAndIsDelete(phoneNumber);
+//        boolean customer_is_exist=customerService.existsBymobileAndIsDelete(phoneNumber);
+//        if(!customer_is_exist&&!user_is_exist){
+//            Customer customer = new Customer();
+//            customer.setMobile(phoneNumber);
+//            customer.setOpenid(userLoginDTO.getOpenid());
+//            return this.register(customer);
+//        }else if(customer_is_exist){
+//            Customer customer=customerService.findBymobileAndIsDelete(phoneNumber);
+//            return this.customer_login(customer);
+//        }else{
+//            return this.user_login(userLoginDTO);
+//        }
+//    }
+
+    @PutMapping("/{id}")
+    @ApiOperation("更新用户角色")
+    public Result updateRole(@PathVariable("id") Long id,@RequestBody String role){
+        User user1 = userService.findByIdAndIsDelete(id);
+        if(ObjectUtils.isEmpty(user1)){
+            return ResultUtil.error(ExceptionEnum.USER_NOT_EXIST);
+        }
+        userService.updateUserRole(role,id);
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping
+    @ApiOperation("新增用户")
+    @PreAuthorize("@pms.hasRole('SYSTEM_ADMIN')")
+    public Result addUser(@RequestBody UserDTO user){
+        userService.addUser(user);
+
+        return ResultUtil.success("success");
+    }
+
+    @PutMapping("/delete/{id}")
+    @ApiOperation("删除用户")
+    @PreAuthorize("@pms.hasRole('SYSTEM_ADMIN')")
+    public Result deleteUser(@PathVariable Long id){
+        User user = userService.findByIdAndIsDelete(id);
+        if(ObjectUtils.isEmpty(user)){
+            return ResultUtil.error(ExceptionEnum.USER_NOT_EXIST);
+        }
+        user.setIsDelete(true);
+        userService.deleteUserByLogic(id);
+
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/role")
+    @ApiOperation("添加用户角色")
+    public Result addRole(@RequestParam Long userId, @RequestBody Role role){
+        roleRepository.save(role);
+        return ResultUtil.success("success");
+    }
+
+    @GetMapping("/customers")
+    @ApiOperation("查询所有客户")
+    public Result findAllCustomers(Integer pageNum, Integer pageSize){
+        return ResultUtil.success("success", customerService.getAllCustomers(pageNum, pageSize,false));
+    }
+
+    @GetMapping("/customers/{id}")
+    @ApiOperation("按id选择客户")
+    public Result findCustomerById(@PathVariable Long id){
+        return ResultUtil.success("success", customerService.findByCustomerIdAndIsDelete( id, false));
+    }
+
+//    @GetMapping("/customers/{key}")
+//    @ApiOperation("按关键字(姓名/手机号)选择客户")
+//    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','LEAD_SALES', 'ASSIST_SALES')")
+//    public Result findCustomerByKey(@PathVariable("key") String key){
+//        return ResultUtil.success("success", customerService.getCustomerByKey(key,false));
+//    }
+
+    @GetMapping("/users")
+    @ApiOperation("查询所有用户")
+    public Result findAllUsers(Integer pageNum,Integer pageSize,Boolean isDelete){
+        return ResultUtil.success("success", userService.getAllUsers(pageNum,pageSize,isDelete));
+    }
+
+    @GetMapping("/users/sales")
+    @ApiOperation("查询所有业务员")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER')")
+    public Result findAllSales(){
+        return ResultUtil.success("success", userService.getAllSalesByIsDelete(false));
+    }
+
+
+}

+ 42 - 0
src/main/java/com/loan/system/controller/admin/RecommenderController.java

@@ -0,0 +1,42 @@
+package com.loan.system.controller.admin;
+
+import com.loan.system.domain.dto.BizRecommenderDTO;
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.service.RecommenderService;
+import com.loan.system.utils.ResultUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/admin/recommender")
+@Api(tags = "推荐人管理")
+public class RecommenderController {
+    @Autowired
+    private RecommenderService recommenderService;
+
+    @GetMapping
+    @ApiOperation("查询推荐人")
+    public Result getRecommenders(Integer pageNum, Integer pageSize){
+        return ResultUtil.success("success",recommenderService.getRecommenders(pageNum, pageSize));
+    }
+
+    @PostMapping
+    @ApiOperation("添加推荐人")
+    public Result addRecommender(@RequestBody BizRecommenderDTO bizRecommenderDTO){
+        recommenderService.addRecommender(bizRecommenderDTO);
+
+        return ResultUtil.success("success");
+    }
+
+    @PutMapping("/{id}")
+    @ApiOperation("修改推荐人")
+    public Result updateRecommender(@PathVariable("id")Long id, @RequestBody BizRecommenderDTO bizRecommenderDTO){
+        recommenderService.updateRecommenderById(bizRecommenderDTO,id);
+
+        return ResultUtil.success("success");
+    }
+
+
+}

+ 94 - 49
src/main/java/com/loan/system/controller/wechat/ApprovalController.java

@@ -1,5 +1,7 @@
 package com.loan.system.controller.wechat;
 
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.context.BaseContext;
 import com.loan.system.domain.dto.ApprovalDTO;
 import com.loan.system.domain.dto.PreApprovalDTO;
 import com.loan.system.domain.entity.*;
@@ -18,13 +20,17 @@ import io.swagger.annotations.ApiOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static com.loan.system.domain.enums.ExceptionEnum.*;
 
@@ -47,44 +53,39 @@ public class ApprovalController {
     private StepService stepService;
     @Autowired
     private JwtProperties jwtProperties;
+    @Autowired
+    private MessageService messageService;
 //    @Autowired
 //    private WxService wxService;
 
-    @GetMapping("/loan_case/{id}")
-    @ApiOperation("获取业务客户信息")
-    //TODO:给前端展示的VO补充完整
-    public Result info(@PathVariable Long id) {
-        log.info("获取业务客户信息: {}", id);
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(id,false);
-        CustomerVO customer = customerService.findByCustomerIdAndIsDelete(loanCase.getCustomer().getId(), false);
-        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(),id);
-        //List<Document> documentList = documentService.findDocumentByCaseIdAndIsDelete(customer.getId());
-        User user1= userService.findByIdAndIsDelete(step.getUserId1());
-        User user2= userService.findByIdAndIsDelete(step.getUserId2());
-        LoanCasePreApprovalVo loanCasePreApprovalVo = new LoanCasePreApprovalVo();
-        if(user1!=null){
-            loanCasePreApprovalVo.setLead_Sales(user1.getRealName());
-        }
-        if(user2!=null){
-            loanCasePreApprovalVo.setAssist_Sales(user2.getRealName());
-        }
-        //TODO 补充业务信息、客户信息
+    @GetMapping("preApproval/detail")
+    @ApiOperation("获取预审审详情")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result getPreApprovalDetail(@RequestParam Long caseId) {
+        ApprovalVO approvalVO = new ApprovalVO();
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(), caseId);
+        Map<UserVO,String> decision=new HashMap<>();
+        Map<UserVO,String> comment=new HashMap<>();
 
+        if (stepVO.getUserId2()!=null){
+            User user=userService.findByIdAndIsDelete(stepVO.getUserId2());
+            ApprovalRecordVO approvalRecordVO = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId, StepPropertyEnum.APPROVAL.getLabel(), user.getId());
+            decision.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getDecision());
+            comment.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getComments());
+        }
 
-        return ResultUtil.success("success",loanCasePreApprovalVo);
+        return ResultUtil.success("success",approvalVO);
     }
-    @PostMapping("/preapproval-assist/{caseId}/pass")
+
+    @PostMapping("/preapproval-assist/pass")
     @PreAuthorize("@pms.hasRole('ASSIST_SALES')")
     @ApiOperation("副业务员审核")
-    public Result pre_approval_save_primary(PreApprovalDTO preApprovalDTO, HttpServletRequest request) {
-        //请求头根据token获取用户信息
-        //String token = request.getHeader("Authorization").substring(7); // 去掉"Bearer "前缀
-        String token = request.getHeader("Authorization");
-        Long userId=Long.parseLong(JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token).get("userId").toString());
+    public Result pre_approval_save_primary(@RequestBody PreApprovalDTO preApprovalDTO) {
+        Long userId= BaseContext.getCurrentId();
         log.info("用户id: {}", userId);
         User user = userService.findByIdAndIsDelete(userId);
         log.info("用户: {}", user.getMobile());
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(preApprovalDTO.getCaseId(),false);
+        LoanCase loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(preApprovalDTO.getCaseId(),false);
         if(loanCase == null||loanCase.getIsDelete()){
             return ResultUtil.error(PROJECT_NOT_EXIST.getCode(), PROJECT_NOT_EXIST.getMsg());
         }
@@ -121,7 +122,17 @@ public class ApprovalController {
         stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(), StepPropertyEnum.APPROVAL.getLabel(), preApprovalDTO.getCaseId());
         loanCaseService.updateUpdatetimeByIdAndIsDeleted(preApprovalDTO.getCaseId(),false);
         //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
 //        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
         return ResultUtil.success("success","预审通过");
     }
 
@@ -167,18 +178,15 @@ public class ApprovalController {
 //        return ResultUtil.success("success","审批通过");
 //    }
 
-    @PostMapping("/preapproval-records/{caseId}/reject")
+    @PostMapping("/preapproval-records/reject")
     @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES','ASSIST_SALES')")
     @ApiOperation("业务预审拒绝")
-    public Result pre_approval_reject(PreApprovalDTO preApprovalDTO, HttpServletRequest request) {
-        //请求头根据token获取用户信息
-        //String token = request.getHeader("Authorization").substring(7); // 去掉"Bearer "前缀
-        String token = request.getHeader("Authorization");
-        Long userId=Long.parseLong(JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token).get("userId").toString());
+    public Result pre_approval_reject(@RequestBody PreApprovalDTO preApprovalDTO) {
+        Long userId= BaseContext.getCurrentId();
         log.info("用户id: {}", userId);
         User user = userService.findByIdAndIsDelete(userId);
         log.info("用户: {}", user.getMobile());
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(preApprovalDTO.getCaseId(),false);
+        LoanCase loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(preApprovalDTO.getCaseId(),false);
         StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(), preApprovalDTO.getCaseId());
         //判断过去处理人与目前处理人是否一致
         if(step.getUserId2()!=null&&userId!=step.getUserId2()){
@@ -210,21 +218,60 @@ public class ApprovalController {
             approvalService.updateDecisionByCaseIdAndStepNameAndIsDelete(DecisionEnum.REJECT.getMsg(),preApprovalDTO.getCaseId(),StepPropertyEnum.PRE_TRIAL.getLabel(),preApprovalDTO.getComments(),userId);
         }
         stepService.updateUserId2ByCaseIdAndStepName(StepPropertyEnum.PRE_TRIAL.getLabel(),userId,preApprovalDTO.getCaseId());
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.BUSINESS_ACCEPT.getLabel(),preApprovalDTO.getCaseId());
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.BUSINESS_ACCEPT_PARENT.getLabel(),preApprovalDTO.getCaseId());
+        stepService.updateStatusByCaseId(StepEnum.UNSTART.getMsg(),StepPropertyEnum.PRE_TRIAL_PARENT.getLabel(),preApprovalDTO.getCaseId());
+        stepService.updateStatusByCaseId(StepEnum.UNSTART.getMsg(),StepPropertyEnum.PRE_TRIAL.getLabel(),preApprovalDTO.getCaseId());
         loanCaseService.updateUpdatetimeByIdAndIsDeleted(preApprovalDTO.getCaseId(),false);
         //TODO:微信推送预审拒绝消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(caseId);
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
 //        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
         return ResultUtil.success("success","预审拒绝");
     }
 
-    @PostMapping("/approval/{caseId}/pass")
+    @GetMapping("approval/detail")
+    @ApiOperation("获取审批详情")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result getApprovalDetail(@RequestParam Long caseId) {
+        ApprovalVO approvalVO = new ApprovalVO();
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.APPROVAL.getLabel(), caseId);
+        Map<UserVO,String> decision=new HashMap<>();
+        Map<UserVO,String> comment=new HashMap<>();
+
+        if (stepVO.getUserId1()!=null){
+            User user=userService.findByIdAndIsDelete(stepVO.getUserId1());
+            ApprovalRecordVO approvalRecordVO = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId, StepPropertyEnum.APPROVAL.getLabel(), user.getId());
+            decision.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getDecision());
+            comment.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getComments());
+        }
+
+        if (stepVO.getUserId2()!=null){
+            User user=userService.findByIdAndIsDelete(stepVO.getUserId2());
+            ApprovalRecordVO approvalRecordVO = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId, StepPropertyEnum.APPROVAL.getLabel(), user.getId());
+            decision.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getDecision());
+            comment.put(BeanUtil.copyProperties(user,UserVO.class),approvalRecordVO.getComments());
+        }
+
+        return ResultUtil.success("success",approvalVO);
+    }
+
+    @PostMapping("/approval/pass")
     @PreAuthorize("@pms.hasRole('APPROVER')")
     @ApiOperation("业务审批通过")
-    public Result approval_pass(ApprovalDTO approvalDTO, HttpServletRequest request) {
-        String token = request.getHeader("Authorization");
-        Long userId=Long.parseLong(JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token).get("userId").toString());
+    public Result approval_pass(@RequestBody ApprovalDTO approvalDTO) {
+        Long userId= BaseContext.getCurrentId();
         log.info("用户id: {}", userId);
         //审批业务逻辑
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(), false);
+        LoanCase loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(), false);
         StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.APPROVAL.getLabel(), approvalDTO.getCaseId());
         //判断过去处理人与目前处理人是否一致
         if(step.getUserId1()!=null&&step.getUserId2()!=null&&userId != step.getUserId2()&&userId!=step.getUserId1()){
@@ -278,15 +325,14 @@ public class ApprovalController {
 
     }
 
-    @PostMapping("/approval/{caseId}/reject")
+    @PostMapping("/approval/reject")
     @PreAuthorize("@pms.hasRole('APPROVER')")
     @ApiOperation("业务审批拒绝")
-    public Result approval_reject(ApprovalDTO approvalDTO, HttpServletRequest request) {
-        String token = request.getHeader("Authorization");
-        Long userId=Long.parseLong(JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token).get("userId").toString());
+    public Result approval_reject(@RequestBody ApprovalDTO approvalDTO) {
+        Long userId= BaseContext.getCurrentId();
         log.info("用户id: {}", userId);
         //审批业务逻辑
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(),false);
+        LoanCase loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(),false);
         if(loanCase == null||loanCase.getIsDelete()){
             return ResultUtil.error(PROJECT_NOT_EXIST.getCode(), PROJECT_NOT_EXIST.getMsg());
         }
@@ -334,15 +380,14 @@ public class ApprovalController {
 
         return ResultUtil.success("success","审批驳回");
     }
-    @PostMapping("/approval/{caseId}/terminate")
+    @PostMapping("/approval/terminate")
     @PreAuthorize("@pms.hasRole('APPROVER')")
     @ApiOperation("业务审批终结")
-    public Result approval_end(ApprovalDTO approvalDTO, HttpServletRequest request) {
-        String token = request.getHeader("Authorization");
-        Long userId=Long.parseLong(JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token).get("userId").toString());
+    public Result approval_end(@RequestBody ApprovalDTO approvalDTO) {
+        Long userId= BaseContext.getCurrentId();
         log.info("用户id: {}", userId);
         //审批业务逻辑
-        LoanCaseVO loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(),false);
+        LoanCase loanCase = loanCaseService.findLoanCaseByIdAndIsDelete(approvalDTO.getCaseId(),false);
         if(loanCase == null||loanCase.getIsDelete()){
             return ResultUtil.error(PROJECT_NOT_EXIST.getCode(), PROJECT_NOT_EXIST.getMsg());
         }

+ 145 - 21
src/main/java/com/loan/system/controller/wechat/ContractController.java

@@ -2,30 +2,38 @@ package com.loan.system.controller.wechat;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.http.server.HttpServerResponse;
+import com.loan.system.context.BaseContext;
 import com.loan.system.domain.dto.DocumentDTO;
 import com.loan.system.domain.entity.Contract;
 import com.loan.system.domain.entity.Document;
+import com.loan.system.domain.enums.ExceptionEnum;
 import com.loan.system.domain.pojo.ContractInformation;
+import com.loan.system.domain.vo.CustomerVO;
+import com.loan.system.domain.vo.LoanCaseSimpleVO;
+import com.loan.system.exception.DescribeException;
+import com.loan.system.service.*;
 import com.loan.system.utils.PoiWordUtil;
 import com.loan.system.domain.enums.StepEnum;
 import com.loan.system.domain.enums.StepPropertyEnum;
 import com.loan.system.domain.pojo.Result;
 import com.loan.system.domain.vo.ContractVO;
 import com.loan.system.domain.vo.StepVO;
-import com.loan.system.service.ContractService;
-import com.loan.system.service.DocumentService;
-import com.loan.system.service.StepService;
 import com.loan.system.utils.ResultUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
 import java.util.List;
 import java.util.UUID;
 
+import static com.loan.system.domain.enums.ExceptionEnum.STEP_HAS_NOT_PROCESS;
+import static com.loan.system.domain.enums.ExceptionEnum.STEP_USER_NOT_EXPECTED;
+
 @RestController
 @RequestMapping("/wechat/contract")
 @Api(tags = "合同签订接口")
@@ -39,47 +47,157 @@ public class ContractController {
     private StepService stepService;
     @Autowired
     private DocumentService documentService;
+    @Autowired
+    private CustomerService customerService;
+    @Autowired
+    private LoanService loanService;
 
-    @GetMapping("/{caseId}")
-    @ApiOperation("显示所有合同详情(内部人员)")
-    public Result findContractsDetails(@PathVariable("caseId") Long caseId){
+    @GetMapping
+    @ApiOperation("显示所有合同(内部人员)")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findContracts(@RequestParam Long caseId){
+        return ResultUtil.success("success",contractService.findContractByCaseId(caseId));
+    }
+    @GetMapping("/{id}")
+    @ApiOperation("显示合同文件详情(内部人员)")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public void findContractsDetails(@PathVariable("id") Long contractId , @RequestParam Long caseId , HttpServletResponse response){
+        //获取合同信息
+        Contract contractById = contractService.findContractById(contractId);
+        if(ObjectUtils.isEmpty(contractById))
+            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
 
-        List<ContractVO> contracts = contractService.findContractByCaseId(caseId);
+        getContractInformation(response,caseId,BeanUtil.copyProperties(contractById,ContractVO.class));
 
-        return ResultUtil.success("success",contracts);
     }
 
+//    @GetMapping("/{contractSeq}")
+//    @ApiOperation("显示合同表详情(内部人员)")
+//    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+//    public Result findContractsDetails(@PathVariable("contractSeq") Integer contractSeq , @RequestParam Long caseId , HttpServletResponse response){
+//        //获取合同信息
+//        List<ContractVO> contractVOS = contractService.findContractByCaseId(caseId);
+//        if(contractVOS.size()<contractSeq)
+//            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
+//        ContractVO contractVO = contractVOS.get(contractSeq-1);
+//
+//        return ResultUtil.success("success",getContractInformation(response,caseId,contractVO));
+//    }
+
     @PostMapping("/{id}")
     @ApiOperation("推送合同")
-    public Result pushContract(@PathVariable("id") Long contractId){
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result pushContract(@PathVariable("id") Long contractId,@RequestParam Long caseId){
+        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(step)||!step.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = step.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        Contract contract = contractService.findContractById(contractId);
+        if(contract.getIsPush())
+            throw new DescribeException(ExceptionEnum.CONTRACT_HAS_PUSH);
+
         contractService.updateIsPushById(contractId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+
         return ResultUtil.success("success");
     }
 
-    @GetMapping("/case/{caseId}")
+    @GetMapping("/customer")
     @ApiOperation("显示所有合同详情(客户)")
-    public Result findContractsByCustomer(@PathVariable("caseId") Long caseId, HttpServletResponse response){
+    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
+    public Result findContractsByCustomer(@RequestParam Long caseId) {
+
+        return ResultUtil.success("success",contractService.findContractByCaseIdAndIsPush(caseId,true));
+    }
+    @GetMapping("/customer/{id}")
+    @ApiOperation("显示合同文件详情(客户)")
+    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
+    public void findContractsDetailByCustomer(@PathVariable("id") Long contractId ,@RequestParam Long caseId,HttpServletResponse response){
+        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
         //显示已经推送过的合同
-        List<ContractVO> contracts = contractService.findContractByCaseIdAndIsPush(caseId,true);
-        String downloadName = UUID.randomUUID().toString();
-        ContractInformation contractInformation = new ContractInformation();
+        Contract contractById = contractService.findContractById(contractId);
+        if(ObjectUtils.isEmpty(contractById))
+            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
 
-        PoiWordUtil.writeApprove(response,contractPath,contractInformation,downloadName);
+        if (!contractById.getIsPush())
+            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_PUSH);
 
-        return ResultUtil.success("success",contracts);
+        getContractInformation(response,caseId,BeanUtil.copyProperties(contractById,ContractVO.class));
     }
+
+//    @GetMapping("/customer/{contractSeq}")
+//    @ApiOperation("显示合同详情(客户)")
+//    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
+//    public Result findContractsByCustomer(@PathVariable("contractSeq") Integer contractSeq ,@RequestParam Long caseId,HttpServletResponse response){
+//        //显示已经推送过的合同
+//        List<ContractVO> contracts = contractService.findContractByCaseIdAndIsPush(caseId,true);
+//        if(contracts.size()<contractSeq)
+//            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
+//        ContractVO contractVO = contracts.get(contractSeq-1);
+//
+//        return ResultUtil.success("success",getContractInformation(response,caseId,contractVO));
+//    }
     //签署的电子信息先以附件上传
     //再修改合同状态
-    @PutMapping("/{id}")
+    @PostMapping("/{id}/sign")
     @ApiOperation("签署合同(客户)")
+    @PreAuthorize("@pms.hasAnyRoles('EXTERNAL')")
     public Result updateContract(@PathVariable("id")Long contractId,@RequestParam Long signId,@RequestParam Long commitedId){
+        Contract contract = contractService.findContractById(contractId);
+        if(ObjectUtils.isEmpty(contract))
+            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_EXIST);
+
+        if(!contract.getIsPush())
+            throw new DescribeException(ExceptionEnum.CONTRACT_NOT_PUSH);
+
+        if(contract.getSignedByCustomer())
+            throw new DescribeException(ExceptionEnum.CONTRACT_HAS_SIGNED);
+
+        if(!contract.getCustomerId().equals(BaseContext.getCurrentId()))
+            throw new DescribeException(ExceptionEnum.CONTRACT_SIGNED_PERMISSION_NOT_ALLOW);
+
         contractService.updateContractById1(contractId,commitedId,signId);
+
         return ResultUtil.success("success");
     }
 
     @PutMapping("/case/{caseId}")
     @ApiOperation("合同签订完成")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
     public Result completeContract(@PathVariable("caseId")Long caseId){
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);
+        if(ObjectUtils.isEmpty( step)||!step.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = step.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
         //合同签约完成
         stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(), StepPropertyEnum.CONTRACT_SIGN_PARENT.getLabel(),caseId);
         stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.CONTRACT_SIGN.getLabel(),caseId);
@@ -88,9 +206,7 @@ public class ContractController {
 //        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.DISBURSE_PARENT.getLabel(),caseId);
 //        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PLAN_REPORT.getLabel(),caseId);
 
-//        //回款开始环节
-//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_PARENT.getLabel(),caseId);
-//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_START.getLabel(),caseId);
+
 //
 //        //取证开始环节
 //        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.COLLATERAL_RECEIVE.getLabel(),caseId);
@@ -103,7 +219,15 @@ public class ContractController {
         return ResultUtil.success("success");
     }
 
+    private void getContractInformation(HttpServletResponse response, Long caseId,ContractVO contractVO){
+        LoanCaseSimpleVO loancase = loanService.findLoanCaseSimpleByIdAndIsDelete(caseId, false);
+        CustomerVO customer = customerService.findByCustomerIdAndIsDelete(loancase.getCustomerId(),false);
+        ContractInformation contractInformation = BeanUtil.copyProperties(customer, ContractInformation.class);
+        contractInformation.setContractNo(contractVO.getContractNo());
+        contractInformation.setInterestRate(contractVO.getInterestRate());
 
-
+        String downloadName = contractVO.getContractName()+"-"+contractVO.getId();
+        new PoiWordUtil().writeApprove(response,contractPath,contractInformation,downloadName);
+    }
 
 }

+ 55 - 0
src/main/java/com/loan/system/controller/wechat/CustomerController.java

@@ -0,0 +1,55 @@
+package com.loan.system.controller.wechat;
+
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.service.CustomerService;
+import com.loan.system.utils.ResultUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/wechat/customers")
+@Api(tags = "微信客户接口")
+public class CustomerController {
+    @Autowired
+    private CustomerService customerService;
+
+    @GetMapping
+    @ApiOperation("查询所有客户")
+    public Result findAllCustomers(Integer pageNum, Integer pageSize){
+        return ResultUtil.success("success", customerService.getAllCustomers(pageNum, pageSize,false));
+    }
+
+    @GetMapping("/{id}")
+    @ApiOperation("按id选择客户")
+    public Result findCustomerById(@PathVariable Long id){
+        return ResultUtil.success("success", customerService.findByCustomerIdAndIsDelete( id, false));
+    }
+
+    @GetMapping("/{key}")
+    @ApiOperation("按关键字(姓名/手机号)选择客户")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','LEAD_SALES', 'ASSIST_SALES')")
+    public Result findCustomerByKey(@PathVariable("key") String key,Integer pageNum, Integer pageSize){
+        return ResultUtil.success("success", customerService.getCustomerByKey(key,false , pageNum, pageSize));
+    }
+
+    @PostMapping("/confirm/main")
+    @ApiOperation("手机号与身份证鉴权")
+    public Result confirm(@RequestBody String mobile){
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/confirm/faceAuth")
+    @ApiOperation("人脸识别鉴权")
+    public Result faceAuth(@RequestBody String mobile){
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/confirm/bankAccount")
+    @ApiOperation("银行账号鉴权")
+    public Result bankAccount(@RequestBody String mobile){
+        return ResultUtil.success("success");
+    }
+}

+ 12 - 0
src/main/java/com/loan/system/controller/wechat/DictionaryController.java

@@ -1,6 +1,7 @@
 package com.loan.system.controller.wechat;
 
 import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.DictionarysVO;
 import com.loan.system.service.DictionaryService;
 import com.loan.system.utils.ResultUtil;
 import io.swagger.annotations.Api;
@@ -40,4 +41,15 @@ public class DictionaryController {
     public Result getLocations(){
         return ResultUtil.success("success",dictionaryService.getAllLocations(false));
     }
+
+    @GetMapping
+    @ApiOperation("查询业务字典表")
+    public Result getDictionarys(){
+        DictionarysVO dictionarys = new DictionarysVO();
+        dictionarys.setAttributes(dictionaryService.getAllDictAttributes(false));
+        dictionarys.setTypes( dictionaryService.getAllDictTypes(false));
+        dictionarys.setChannels(dictionaryService.getAllDictChannels(false));
+        dictionarys.setLocations(dictionaryService.getAllLocations(false));
+        return ResultUtil.success("success",dictionarys);
+    }
 }

+ 434 - 39
src/main/java/com/loan/system/controller/wechat/DisbursementController.java

@@ -1,19 +1,16 @@
 package com.loan.system.controller.wechat;
 
 import com.loan.system.context.BaseContext;
+import com.loan.system.domain.dto.ApprovalRecordDTO;
 import com.loan.system.domain.dto.DisbursementDTO;
 import com.loan.system.domain.dto.DisbursementRecordDTO;
-import com.loan.system.domain.dto.DocumentDTO;
-import com.loan.system.domain.entity.ContractSeq;
-import com.loan.system.domain.entity.Disbursement;
-import com.loan.system.domain.enums.BusinessAttrEnum;
-import com.loan.system.domain.enums.StepEnum;
-import com.loan.system.domain.enums.StepPropertyEnum;
+import com.loan.system.domain.entity.*;
+import com.loan.system.domain.enums.*;
 import com.loan.system.domain.pojo.Result;
-import com.loan.system.domain.vo.ContractVO;
-import com.loan.system.domain.vo.DisbursementVO;
-import com.loan.system.domain.vo.StepVO;
+import com.loan.system.domain.vo.*;
+import com.loan.system.exception.DescribeException;
 import com.loan.system.service.*;
+import com.loan.system.service.DisbursementRecordService;
 import com.loan.system.utils.ResultUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -26,6 +23,8 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
 
+import static com.loan.system.domain.enums.ExceptionEnum.*;
+
 @RestController
 @RequestMapping("/wechat/disbursement")
 @Api(tags = "出款接口")
@@ -42,34 +41,223 @@ public class DisbursementController {
     private ContractService contractService;
     @Autowired
     private ContractSeqService contractSeqService;
-
-    @GetMapping("/{caseId}/details")
-    @ApiOperation("显示业务详情")//与loanContraller的方法一致,但为了规范
-    public Result findLoanCaseDetails(@PathVariable("caseId")Long caseId){
-        return ResultUtil.success("success",loanService.findLoanCaseDetailsById(caseId));
+    @Autowired
+    private ApprovalService approvalService;
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private DisbursementRecordService disbursementRecordService;
+    @Autowired
+    private RepaymentService repaymentService;
+    @Autowired
+    private MessageService messageService;
+
+    @GetMapping("/planDetails")
+    @ApiOperation("显示计划详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails(@RequestParam Long caseId){
+        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        //填充
+        Disbursement disbursementByCaseId = disbursementService.getDisbursementByCaseId(caseId);
+        disbursementDetailVO.setDisbursementAmount(disbursementByCaseId.getPlannedAmount());
+        disbursementDetailVO.setCurrentLocation(disbursementByCaseId.getPlannedLocation());
+
+        return ResultUtil.success("success",disbursementDetailVO);
     }
 
-    @GetMapping("/{caseId}/details2")
-    @ApiOperation("显示出款计划详情")
-    public Result findDisbursementDetails(@PathVariable("caseId")Long caseId){
-        return ResultUtil.success("success",disbursementService.findDisbursementDetailsById(caseId));
-    }
 
     @PostMapping
     @ApiOperation(value = "上报出款计划")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
     public Result addDisbursement(@RequestBody DisbursementDTO disbursementDTO) {
+        if(ObjectUtils.isEmpty(disbursementDTO)||disbursementDTO.getCaseId()==null)
+            throw new DescribeException(INPUT_ERROR);
+
+        if(!loanService.existsByIdAndIsDelete(disbursementDTO.getCaseId()))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.PLAN_REPORT.getLabel(),disbursementDTO.getCaseId());
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
 
         //上报计划
         DisbursementVO disbursementVO = disbursementService.addDisbursement(disbursementDTO);
 
         //修改状态
         stepService.updateUserByCaseId(StepPropertyEnum.PLAN_REPORT.getLabel(), BaseContext.getCurrentId(), disbursementDTO.getCaseId());
-        stepService.updateStatusByCaseId(StepPropertyEnum.PLAN_REPORT.getLabel(), StepEnum.COMPLETED.getMsg(), disbursementDTO.getCaseId());
-        stepService.updateStatusByCaseId(StepPropertyEnum.PLAN_AUDIT.getLabel(), StepEnum.PROCESS.getMsg(),disbursementDTO.getCaseId());
+        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(), StepPropertyEnum.PLAN_REPORT.getLabel(),disbursementDTO.getCaseId());
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(),StepPropertyEnum.PLAN_AUDIT.getLabel(),disbursementDTO.getCaseId());
 
         return ResultUtil.success("success",disbursementVO);
     }
 
+    @GetMapping("/approvalDetails")
+    @ApiOperation("显示计划审批详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails2(@RequestParam Long caseId){
+        if(caseId == null||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        //填充
+        ApprovalRecordVO approvalRecord = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId,StepPropertyEnum.PLAN_AUDIT.getLabel(),BaseContext.getCurrentId());
+        disbursementDetailVO.setApprovalComment(approvalRecord.getComments());
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_START.getLabel(),caseId);
+        disbursementDetailVO.setRepaymentUser(userService.findByIdAndIsDelete(stepVO.getUserId1()));
+
+        return ResultUtil.success("success",disbursementDetailVO);
+
+    }
+
+    //TODO:选择回款业务员-在userController中
+
+    @PostMapping("/approval/pass1")
+    @ApiOperation(value = "计划审批")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result disbursementPlanApproval(@RequestBody ApprovalRecordDTO approvalRecordDTO, @RequestParam Long chargeId) {
+        if (ObjectUtils.isEmpty(approvalRecordDTO)||approvalRecordDTO.getCaseId()==null)
+            throw new DescribeException(INPUT_ERROR);
+
+        Long caseId = approvalRecordDTO.getCaseId();
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.PLAN_AUDIT.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+        //选择回款负责人,开启回款开始环节,创建回款单
+        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.REPAY_START.getLabel(),chargeId,caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_PARENT.getLabel(),caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_START.getLabel(),caseId);
+
+        Repayment repayment = new Repayment();
+        repayment.setCaseId(caseId);
+        repayment.setStartUserId(chargeId);
+        repayment.setTotalAmount(disbursementService.getDisbursementByCaseId(caseId).getPlannedAmount());
+        repaymentService.addRepayment(repayment);
+
+        //填写审批意见
+        ApprovalRecordVO approvalRecord_origin = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId,StepPropertyEnum.PLAN_AUDIT.getLabel(),BaseContext.getCurrentId());
+        if (approvalRecord_origin == null) {
+            ApprovalRecord approvalRecord = new ApprovalRecord();
+            approvalRecord.setCaseId(approvalRecord.getCaseId());
+            approvalRecord.setStepName(StepPropertyEnum.PLAN_AUDIT.getLabel());
+            approvalRecord.setApproverId(BaseContext.getCurrentId());
+            approvalRecord.setDecision(DecisionEnum.PASS.getMsg());
+            approvalRecord.setComments(approvalRecordDTO.getComments());
+            approvalRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setIsDelete(false);
+
+            approvalService.save(approvalRecord);
+        }else{
+            approvalService.updateDecisionByCaseIdAndStepNameAndIsDelete(DecisionEnum.PASS.getMsg(),caseId, StepPropertyEnum.PLAN_AUDIT.getLabel(), approvalRecordDTO.getComments(), BaseContext.getCurrentId());
+        }
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.PLAN_AUDIT.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.PLAN_AUDIT.getLabel(),caseId);
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(), StepPropertyEnum.DISBURSE_START.getLabel(),caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/approval/reject1")
+    @ApiOperation(value = "计划审批驳回")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result disbursementPlanApprovalReject(@RequestBody ApprovalRecordDTO approvalRecordDTO, @RequestParam Long chargeId) {
+        if (ObjectUtils.isEmpty(approvalRecordDTO)||approvalRecordDTO.getCaseId()==null)
+            throw new DescribeException(INPUT_ERROR);
+
+        Long caseId = approvalRecordDTO.getCaseId();
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.PLAN_AUDIT.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //选择回款负责人,但驳回不应该开启回款开始环节
+        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.REPAY_START.getLabel(),chargeId,caseId);
+//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_PARENT.getLabel(),caseId);
+//        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_START.getLabel(),caseId);
+
+        Repayment repayment = new Repayment();
+        repayment.setCaseId(caseId);
+        repayment.setStartUserId(chargeId);
+        repayment.setTotalAmount(disbursementService.getDisbursementByCaseId(caseId).getPlannedAmount());
+        repaymentService.addRepayment(repayment);
+
+        //填写驳回
+        ApprovalRecordVO approvalRecord_origin = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId,StepPropertyEnum.PLAN_AUDIT.getLabel(),BaseContext.getCurrentId());
+        if (approvalRecord_origin == null) {
+            ApprovalRecord approvalRecord = new ApprovalRecord();
+            approvalRecord.setCaseId(approvalRecord.getCaseId());
+            approvalRecord.setStepName(StepPropertyEnum.PLAN_AUDIT.getLabel());
+            approvalRecord.setApproverId(BaseContext.getCurrentId());
+            approvalRecord.setDecision(DecisionEnum.REJECT.getMsg());
+            approvalRecord.setComments(approvalRecordDTO.getComments());
+            approvalRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setIsDelete(false);
+
+            approvalService.save(approvalRecord);
+        }else{
+            approvalService.updateDecisionByCaseIdAndStepNameAndIsDelete(DecisionEnum.REJECT.getMsg(),caseId, StepPropertyEnum.PLAN_AUDIT.getLabel(), approvalRecordDTO.getComments(), BaseContext.getCurrentId());
+        }
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.PLAN_AUDIT.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(), StepPropertyEnum.PLAN_REPORT.getLabel(),caseId);
+        stepService.updateStatusByCaseId(StepEnum.UNSTART.getMsg(), StepPropertyEnum.PLAN_AUDIT.getLabel(),caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        StepVO stepVO1 = stepService.findByStepNameAndCaseId(StepPropertyEnum.PLAN_REPORT.getLabel(), caseId);
+//        message.setMobile(userService.findByIdAndIsDelete(stepVO1.getUserId1()).getMobile());
+//        message.setUserRole(null);
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName(StepPropertyEnum.PLAN_AUDIT.getLabel());
+//        message.setRelatedId(caseId);
+//        message.setRelatedType("");
+ //       messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
     //上传文件UploadController
     //显示文件列表
     @GetMapping("/{caseId}/files")
@@ -81,40 +269,251 @@ public class DisbursementController {
 
     @PutMapping("/commit")
     @ApiOperation(value = "出款启动")
-    @PreAuthorize("@pms.hasRole(RoleEnum.LEAD_SALES.getMsg())")
-    public Result commitDisbursement(@RequestBody DocumentDTO documentDTO) {
+    @PreAuthorize("@pms.hasAnyRoles('APPROVER','LEAD_SALES')")
+    public Result commitDisbursement(@RequestParam Long caseId) {
+        if(caseId == null ||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.DISBURSE_START.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_START.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.DISBURSE_START.getLabel(),caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.DISBURSE_AUDIT.getLabel(),  caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+
+        return ResultUtil.success("success");
+    }
+
+
+    @PostMapping("/approval/pass2")
+    @ApiOperation(value = "出款审批")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result disbursementApproval(@RequestBody ApprovalRecordDTO approvalRecordDTO) {
+        if(ObjectUtils.isEmpty(approvalRecordDTO)||approvalRecordDTO .getCaseId()== null)
+            throw new DescribeException(INPUT_ERROR);
+
+        Long caseId = approvalRecordDTO.getCaseId();
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //填写审批意见 //驳回呢?
+        ApprovalRecordVO approvalRecord_origin = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId,StepPropertyEnum.DISBURSE_AUDIT.getLabel(),BaseContext.getCurrentId());
+        if (approvalRecord_origin == null) {
+            ApprovalRecord approvalRecord = new ApprovalRecord();
+            approvalRecord.setCaseId(approvalRecord.getCaseId());
+            approvalRecord.setStepName(StepPropertyEnum.DISBURSE_AUDIT.getLabel());
+            approvalRecord.setApproverId(BaseContext.getCurrentId());
+            approvalRecord.setDecision(DecisionEnum.PASS.getMsg());
+            approvalRecord.setComments(approvalRecordDTO.getComments());
+            approvalRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setIsDelete(false);
+
+            approvalService.save(approvalRecord);
+        }else{
+            approvalService.updateDecisionByCaseIdAndStepNameAndIsDelete(DecisionEnum.PASS.getMsg(),caseId, StepPropertyEnum.DISBURSE_AUDIT.getLabel(), approvalRecordDTO.getComments(), BaseContext.getCurrentId());
+        }
+
+        //修改出款单
+        disbursementService.updateApprovalUserById(BaseContext.getCurrentId(),disbursementService.getDisbursementByCaseId(caseId).getId());
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(), StepEnum.COMPLETED.getMsg(),caseId);
+        stepService.updateStatusByCaseId(StepPropertyEnum.FINANCE_DISBURSE.getLabel(), StepEnum.PROCESS.getMsg(), caseId);
+
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/approval/reject2")
+    @ApiOperation(value = "出款审批驳回")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result disbursementApprovalReject(@RequestBody ApprovalRecordDTO approvalRecordDTO) {
+        if (ObjectUtils.isEmpty(approvalRecordDTO)||approvalRecordDTO.getCaseId() == null)
+            throw new DescribeException(INPUT_ERROR);
+
+        Long caseId = approvalRecordDTO.getCaseId();
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+//        //TODO:专门用于审批驳回,驳回后若上个步骤未重新提交,则无法审批
+//        StepVO stepVO1 = stepService.findByStepNameAndCaseId(StepPropertyEnum.DISBURSE_START.getLabel(),caseId);
+//        if (stepVO1.getStatus().equals(StepEnum.PROCESS.getMsg()))
+//            throw new DescribeException(PRE_STEP_NOT_COMPLETE);
+
+        //填写驳回意见
+        ApprovalRecordVO approvalRecord_origin = approvalService.findByCaseIdAndIsDeleteAndStepName(caseId,StepPropertyEnum.DISBURSE_AUDIT.getLabel(),BaseContext.getCurrentId());
+        if (approvalRecord_origin == null) {
+            ApprovalRecord approvalRecord = new ApprovalRecord();
+            approvalRecord.setCaseId(approvalRecord.getCaseId());
+            approvalRecord.setStepName(StepPropertyEnum.DISBURSE_AUDIT.getLabel());
+            approvalRecord.setApproverId(BaseContext.getCurrentId());
+            approvalRecord.setDecision(DecisionEnum.REJECT.getMsg());
+            approvalRecord.setComments(approvalRecordDTO.getComments());
+            approvalRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+            approvalRecord.setIsDelete(false);
+
+            approvalService.save(approvalRecord);
+        }else{
+            approvalService.updateDecisionByCaseIdAndStepNameAndIsDelete(DecisionEnum.REJECT.getMsg(),caseId, StepPropertyEnum.DISBURSE_AUDIT.getLabel(), approvalRecordDTO.getComments(), BaseContext.getCurrentId());
+        }
+
+        //修改出款单
+        disbursementService.updateApprovalUserById(BaseContext.getCurrentId(),disbursementService.getDisbursementByCaseId(caseId).getId());
 
         //修改状态
-        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_START.getLabel(), BaseContext.getCurrentId(), documentDTO.getCaseId());
-        stepService.updateStatusByCaseId(StepPropertyEnum.DISBURSE_START.getLabel(), StepEnum.COMPLETED.getMsg(),documentDTO.getCaseId());
-        stepService.updateStatusByCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(), StepEnum.PROCESS.getMsg(), documentDTO.getCaseId());
+        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_AUDIT.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(),StepPropertyEnum.DISBURSE_START.getLabel(),caseId);//重新出款
+        stepService.updateStatusByCaseId( StepEnum.UNSTART.getMsg(),StepPropertyEnum.DISBURSE_AUDIT.getLabel(),caseId);
 
         return ResultUtil.success("success");
     }
 
-    @PostMapping("/{id}/amount")
+    @GetMapping("/financeDetails")
+    @ApiOperation("显示财务出款详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails3(@RequestParam Long caseId){
+        if(caseId == null || !loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        //填充
+        List<DisbursementRecordVO> records = disbursementRecordService.findRecordById(disbursementService.getDisbursementByCaseId(caseId).getId());
+        disbursementDetailVO.setDisbursementRecords(records);
+        disbursementDetailVO.setTotalAmount(disbursementService.getDisbursementByCaseId(caseId).getPlannedAmount());
+
+        return ResultUtil.success("success",loanService.findLoanCaseDetailsById(caseId));
+    }
+
+    @PostMapping("/amount")
     @ApiOperation(value = "财务出款")
-    public Result disbursement(@RequestBody DisbursementRecordDTO disbursementRecordDTO) {
+    @PreAuthorize("@pms.hasRole('FINANCE')")
+    public Result financeDisbursement(@RequestBody DisbursementRecordDTO disbursementRecordDTO,@RequestParam Long caseId) {
+        if (ObjectUtils.isEmpty(disbursementRecordDTO)||disbursementRecordDTO.getDisbursementId() == null)
+            throw new DescribeException(INPUT_ERROR);
+
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.FINANCE_DISBURSE.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+//        Long currentId = stepVO.getUserId1();
+//        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+//            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+//        }
+
+        //修改出款单
+        //disbursementService.updateOperationUserById(BaseContext.getCurrentId(),disbursementService.getDisbursementByCaseId(caseId).getId());
+
         //添加出款记录
+        disbursementRecordService.addDisbursementRecord(disbursementRecordDTO);
 
         //修改状态
-//        stepService.updateUserByCaseId(StepPropertyEnum.FINANCE_DISBURSE.getLabel(), BaseContext.getCurrentId(), disbursementDTO.getCaseId());
-//        stepService.updateStatusByCaseId(StepPropertyEnum.FINANCE_DISBURSE.getLabel(), StepEnum.COMPLETED.getMsg(),disbursementDTO.getCaseId());
-//        stepService.updateStatusByCaseId(StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), StepEnum.PROCESS.getMsg(), disbursementDTO.getCaseId());
+        //stepService.updateUserByCaseId(StepPropertyEnum.FINANCE_DISBURSE.getLabel(), BaseContext.getCurrentId(), caseId);TODO:分多次出款,不一定是同一个人
+        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.FINANCE_DISBURSE.getLabel(),caseId);
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(),StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
 
 
         return ResultUtil.success("success");
     }
 
+    @GetMapping("/confirmDetails")
+    @ApiOperation("显示业务确认详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails4(@RequestParam Long caseId){
+        if(caseId == null ||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        //填充
+        List<DisbursementRecordVO> records = disbursementRecordService.findRecordById(disbursementService.getDisbursementByCaseId(caseId).getId());
+        disbursementDetailVO.setDisbursementRecords(records);
+
+        Disbursement disbursement = disbursementService.getDisbursementByCaseId(caseId);
+        disbursementDetailVO.setTotalAmount(disbursement.getPlannedAmount());
+        disbursementDetailVO.setConfirmComment(disbursement.getComments());
+
+        return ResultUtil.success("success",loanService.findLoanCaseDetailsById(caseId));
+    }
+
     @PostMapping("/confirm")
     @ApiOperation(value = "业务确认")
-    public Result confirmDisbursement(@RequestBody DisbursementDTO disbursementDTO) {
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
+    public Result confirmDisbursement(@RequestParam("caseId") Long caseId,@RequestParam("comments") String comments) {
+        if(caseId == null ||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.DISBURSE_CONFIRM.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //设置说明
+        disbursementService.updateCommentsById(comments,disbursementService.getDisbursementByCaseId(caseId).getId());
+
         //修改状态
-        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), BaseContext.getCurrentId(), disbursementDTO.getCaseId());
-        stepService.updateStatusByCaseId(StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), StepEnum.COMPLETED.getMsg(),disbursementDTO.getCaseId());
+        stepService.updateUserByCaseId(StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.DISBURSE_CONFIRM.getLabel(), caseId);
 
         //填写合同编号
-        List<ContractVO> contractByCaseId = contractService.findContractByCaseId(disbursementDTO.getCaseId());
+        List<ContractVO> contractByCaseId = contractService.findContractByCaseId(caseId);
         String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
 
         contractByCaseId.forEach(contractVO -> {
@@ -142,8 +541,4 @@ public class DisbursementController {
     }
 
 
-
-
-
-
 }

+ 69 - 56
src/main/java/com/loan/system/controller/wechat/LoanController.java

@@ -4,6 +4,7 @@ import com.loan.system.context.BaseContext;
 import com.loan.system.domain.dto.*;
 import com.loan.system.domain.entity.*;
 import com.loan.system.domain.enums.ExceptionEnum;
+import com.loan.system.domain.enums.RoleEnum;
 import com.loan.system.domain.enums.StepEnum;
 import com.loan.system.domain.enums.StepPropertyEnum;
 import com.loan.system.domain.pojo.Result;
@@ -12,15 +13,20 @@ import com.loan.system.domain.vo.StepVO;
 import com.loan.system.exception.DescribeException;
 import com.loan.system.service.*;
 import com.loan.system.utils.ResultUtil;
+import com.mysql.cj.protocol.Message;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import static com.loan.system.domain.enums.ExceptionEnum.STEP_HAS_NOT_PROCESS;
+import static com.loan.system.domain.enums.ExceptionEnum.STEP_USER_NOT_EXPECTED;
+
 @RestController
 @RequestMapping("/wechat/case")
 @Api(tags = "业务受理接口")
@@ -42,27 +48,36 @@ public class LoanController {
     private CollateralService collateralService;
     @Autowired
     private ContractAndCollateralService contractAndCollateralService;
+    @Autowired
+    private MessageService messageService;
 
     @GetMapping("/dealing")
     @ApiOperation("显示处理中的业务")
-    public Result findLoanCaseByIsComplete(@RequestParam("isComplete") Boolean isComplete ){
-        List<LoanCaseVO> loanCases = loanService.findLoanCaseByIsComplete(isComplete,false);
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseByIsComplete(@RequestParam(value = "isComplete",defaultValue =  "false") Boolean isComplete ,Integer pageNum, Integer pageSize){
+        List<LoanCaseVO> loanCases = loanService.findLoanCaseByIsComplete(pageNum, pageSize,isComplete,false);
         return ResultUtil.success("success",loanCases);
     }
 
     @GetMapping("/{id}/details")
     @ApiOperation("显示业务详情")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
     public Result findLoanCaseDetails(@PathVariable("id")Long caseId){
         return ResultUtil.success("success",loanService.findLoanCaseDetailsById(caseId));
     }
 
     @PostMapping("/create")
     @ApiOperation("创建业务")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES','ASSIST_SALES')")
     public Result createLoanCase(@RequestParam("customerId") Long customerId){
+        if(!customerService.existsByIdAndIsDelete(customerId))
+            throw new DescribeException(ExceptionEnum.USER_NOT_EXIST);
         //创建订单
         LoanCaseVO loanCase = loanService.addLoanCaseByCustomerId(customerId);
         //创建流程
         stepService.addStepByCaseId(loanCase.getId());
+        //设置当前处理人
+        stepService.updateUserByCaseId(StepPropertyEnum.BUSINESS_ACCEPT.getLabel(),BaseContext.getCurrentId(),loanCase.getId());
         return ResultUtil.success("success",loanCase);
     }
 
@@ -72,10 +87,22 @@ public class LoanController {
      */
     @PostMapping("/{id}")//请求中操作复杂,putmapping仅适用于更新操作
     @ApiOperation("提交/保存业务")
-    public Result saveLoanCase(@PathVariable("id")Long caseId, @RequestBody LoanCaseDTO loanCaseDTO, @RequestParam("IsComplete")Boolean isComplete){//isComplete 若保存,则设置为未完成,若提交,则设置为已完成
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
+    public Result saveLoanCase(@PathVariable("id")Long caseId, @RequestBody LoanCaseDTO loanCaseDTO, @RequestParam("isComplete")Boolean isComplete){//isComplete 若保存,则设置为未完成,若提交,则设置为已完成
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        if (ObjectUtils.isEmpty(loanCaseDTO))
+            throw new DescribeException(ExceptionEnum.INPUT_ERROR);
+
         StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.BUSINESS_ACCEPT.getLabel(),caseId);
-        if(stepVO.getStatus().equals(StepEnum.COMPLETED.getMsg()))
-            throw new DescribeException(ExceptionEnum.LOANCASE_IS_Completed);
+        if(ObjectUtils.isEmpty(stepVO) || !stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
 
         //1.补充业务信息
         loanService.updateLoanCaseById(loanCaseDTO,caseId);
@@ -103,15 +130,11 @@ public class LoanController {
         for(int i=0 ; i < loanCaseDTO.getCollateralAndContract().size(); i++){
             Contract contract = contracts.get( i);
             List<Integer> collaterals = loanCaseDTO.getCollateralAndContract().get(i).get(contract.getBusinessAttr());
+
             for (Integer collateralId : collaterals)
-                contractAndCollateralService.addContractAndCollateral(contract.getId(),collateralIds.get(collateralId-1));
+                contractAndCollateralService.addContractAndCollateral(contract.getId(),collateralIds.get(collateralId-1),caseId);
         }
-//        //4.设置附件
-//        for(DocumentDTO documentDTO : loanCaseDTO.getDocuments()){
-//            //若存在,则修改
-//
-//            //若不存在,则添加
-//        }
+
         //5.添加其它客户
         customerOtherService.deleteAllByCaseId(caseId);
         if(!ObjectUtils.isEmpty(loanCaseDTO.getCustomers1()))
@@ -125,16 +148,26 @@ public class LoanController {
         customerService.updateMarriedStatusById(loanCaseDTO.getCustomerId(),loanCaseDTO.getMarriedStatus());
 
         //7.设置阶段负责人与状态(如果第一个人是辅办人员,那第二个人必须是主办)
-        stepService.updateUserByCaseId(StepPropertyEnum.BUSINESS_ACCEPT.getLabel(),BaseContext.getCurrentId(),caseId);
         if(isComplete){
             stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.BUSINESS_ACCEPT_PARENT.getLabel(),caseId);
             stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.BUSINESS_ACCEPT.getLabel(),caseId);
             //设置当阶段为完成,下阶段为开始
             stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PRE_TRIAL_PARENT.getLabel(),caseId);
             stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.PRE_TRIAL.getLabel(),caseId);
-        }
 
-        //8.消息推送
+            //TODO:8.微信推送预审通过消息和通知下一环节
+//            SysMessage message = new SysMessage();
+//            message.setMobile(null);
+ //           message.setUserRole(RoleEnum.ASSIST_SALES.getMsg());
+//            message.setMessageTitle("");
+//            message.setMessageContent("");
+ //           message.setStepName(StepPropertyEnum.PRE_TRIAL.getLabel());
+  //          message.setRelatedId(caseId);
+//            message.setRelatedType("");
+ //           messageService.addMessage(message);
+//            wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        }
 
         return ResultUtil.success("success");
     }
@@ -189,58 +222,38 @@ public class LoanController {
 //
 
 
-    @PutMapping("/{id}/preApprove/cancel")
+    @PostMapping("/{id}/preApprove/cancel")
     @ApiOperation("取消预审")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
     public Result cancelPreApprove(@PathVariable("id")Long caseId){
-        //设置预审核阶段已完成,审批阶段开始
-        completePreApproveMethod(caseId);
-        StepVO stepVO = stepService.updateUserByCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(), BaseContext.getCurrentId(), caseId);
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
 
-        //添加审批记录
-        approveService.addPreApprovalRecord(StepPropertyEnum.PRE_TRIAL.getLabel(),BaseContext.getCurrentId(),caseId);
-
-        //List<StepVO> list = stepService.getStepByCaseId(caseId);
+        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(),caseId);
+        if(ObjectUtils.isEmpty( step)||!step.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
 
-        return ResultUtil.success("success");
-    }
-
-//    @PutMapping("/{id}/preApprove/commit")
-//    @ApiOperation("预审提交")
-//    public Result preApproveCommit(@RequestBody ApprovalRecordDTO approvalRecordDTO, @PathVariable("id")Long caseId ){
-//        //修改阶段负责人
-//        StepVO  stepVo = stepService.updateUserByCaseId(approvalRecordDTO.getStepName(), approvalRecordDTO.getApproverId(), caseId);
-//        //添加审批记录
-//        approveService.addApprovalRecord(approvalRecordDTO);
-//        //修改阶段状态
-//        if (stepVo.getUserId2()!= null)
-//            completePreApproveMethod(caseId);
-//
-//        List<StepVO> list = stepService.getStepByCaseId(caseId);
-//
-//        return ResultUtil.success("success",list);
-//    }
-//
-//    @PutMapping("/{id}/preApprove/back")
-//    @ApiOperation("预审退回(未)")//驳回后的负责人还是同一个吗
-//    public Result preApproveBack(@RequestBody ApprovalRecordDTO approvalRecordDTO, @PathVariable("id")Long caseId ){
-//        //修改阶段负责人
-//        stepService.updateUserByCaseId(approvalRecordDTO.getStepName(),approvalRecordDTO.getApproverId(),caseId);
-//        //添加审批记录
-//        approveService.addApprovalRecord(approvalRecordDTO);
-//        //修改阶段状态
-//        completePreApproveMethod(caseId);
-//
-//        List<StepVO> list = stepService.getStepByCaseId(caseId);
-//        return ResultUtil.success("success",list);
-//    }
+        Long currentId = step.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
 
-    private void completePreApproveMethod(Long caseId){
         //设置预审核阶段已完成,审批阶段开始
         stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.PRE_TRIAL_PARENT.getLabel(),caseId);
         stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.PRE_TRIAL.getLabel(),caseId);
 
         stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.APPROVAL_PARENT.getLabel(),caseId);
         stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.APPROVAL.getLabel(),caseId);
+
+        stepService.updateUserByCaseId(StepPropertyEnum.PRE_TRIAL.getLabel(), BaseContext.getCurrentId(), caseId);
+
+        //添加审批记录
+        approveService.addPreApprovalRecord(StepPropertyEnum.PRE_TRIAL.getLabel(),BaseContext.getCurrentId(),caseId);
+
+        //List<StepVO> list = stepService.getStepByCaseId(caseId);
+
+        return ResultUtil.success("success");
     }
 
+
 }

+ 57 - 0
src/main/java/com/loan/system/controller/wechat/MessageController.java

@@ -0,0 +1,57 @@
+package com.loan.system.controller.wechat;
+
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.entity.User;
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.SysMessageVO;
+import com.loan.system.domain.vo.UserVO;
+import com.loan.system.service.CustomerService;
+import com.loan.system.service.MessageService;
+import com.loan.system.service.UserService;
+import com.loan.system.utils.ResultUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Comparator;
+import java.util.List;
+
+@RestController
+@RequestMapping("/wechat/message")
+@Api(tags = "推送信息接口")
+public class MessageController {
+    @Autowired
+    private UserService userService;
+    @Autowired
+    private CustomerService customerService;
+    @Autowired
+    private MessageService messageService;
+
+
+    @GetMapping
+    @ApiOperation(value = "获取消息")
+    public Result getMessageByMobile(@RequestParam String mobile,@RequestParam Boolean isCustomer) {
+        //按手机号获取消息
+        List<SysMessageVO> messageByMobiles = messageService.getMessageByMobile(mobile);
+        if (isCustomer)
+            return ResultUtil.success("success", messageByMobiles);
+
+        //按角色获取消息
+        User user = userService.findByPhoneNumberAndIsDelete(mobile);
+        String userRole = user.getRole();
+        String[] roles=userRole.split(",");
+        for (String role : roles)
+            messageByMobiles.addAll(messageService.getMessageByRole(role));
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        messageByMobiles.sort(Comparator.comparing(
+                (SysMessageVO vo) -> LocalDateTime.parse(vo.getCreateTime(), formatter)
+        ));
+
+        return ResultUtil.success("success", messageByMobiles);
+    }
+}

+ 406 - 2
src/main/java/com/loan/system/controller/wechat/RepaymentController.java

@@ -1,11 +1,415 @@
 package com.loan.system.controller.wechat;
 
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.dto.*;
+import com.loan.system.domain.entity.ApprovalRecord;
+import com.loan.system.domain.entity.Disbursement;
+import com.loan.system.domain.entity.Repayment;
+import com.loan.system.domain.entity.RepaymentRecord;
+import com.loan.system.domain.enums.*;
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.*;
+import com.loan.system.exception.DescribeException;
+import com.loan.system.service.*;
+import com.loan.system.service.DisbursementRecordService;
+import com.loan.system.utils.ResultUtil;
 import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.ApiOperation;
+import net.bytebuddy.dynamic.scaffold.MethodRegistry;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+import static com.loan.system.domain.enums.ExceptionEnum.*;
 
 @RestController
 @RequestMapping("/wechat/repayment")
 @Api(tags = "还款接口")
 public class RepaymentController {
+
+    @Autowired
+    private DisbursementService disbursementService;
+    @Autowired
+    private StepService stepService;
+    @Autowired
+    private DisbursementRecordService disbursementRecordService;
+    @Autowired
+    private RepaymentService repaymentService;
+    @Autowired
+    private RepaymentRecordService repaymentRecordService;
+    @Autowired
+    private LoanService loanService;
+
+    @GetMapping("/{caseId}/repayDetails")
+    @ApiOperation("显示回款详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails(@PathVariable("caseId")Long caseId){
+        if(!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        RepaymentDetailVO repaymentDetailVO = new RepaymentDetailVO();
+        repaymentDetailVO.setCustomer(disbursementDetailVO.getCustomer());
+        repaymentDetailVO.setLoanCase(disbursementDetailVO.getLoanCase());
+
+        //填充
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
+        Double currentAmount= 0.0;
+        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
+            if(!repaymentRecordVO.getIsInterest())//审批、财务环节显示审批通过后的总额
+                currentAmount += repaymentRecordVO.getAmount();
+
+        repaymentDetailVO.setRepaymentRecords(repaymentRecordVOS);
+        repaymentDetailVO.setCurrentAmount(currentAmount);
+        repaymentDetailVO.setTotalAmount(repayment.getTotalAmount());
+        //财务核算后
+        repaymentDetailVO.setInterests(repayment.getInterest());
+        //余额回款
+        repaymentDetailVO.setWay(repayment.getRepayWay());
+
+        return ResultUtil.success("success",repaymentDetailVO);
+    }
+
+
+    @PostMapping
+    @ApiOperation(value = "启动回款")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
+    public Result addDisbursement(@RequestBody RepaymentRecordDTO repaymentRecordDTO, @RequestParam Long caseId, @RequestParam Long recordId) {
+        if(ObjectUtils.isEmpty(repaymentRecordDTO))
+            throw new DescribeException(INPUT_ERROR);
+
+        if(caseId == null ||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_START.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO) || !stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //最新回款记录还在审批中,则不能回款
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
+
+        //上报计划
+        if(recordId == -1){
+            //审批意见为驳回,无法新增
+            if(repaymentRecordVOS.get(repaymentRecordVOS.size()-1).getApprovalDecision().equals(DecisionEnum.REJECT.getMsg()))
+                throw new DescribeException(DISBURSEMENT_HAS_NOT_COMPLETED);
+            repaymentRecordService.addRepaymentRecord(repaymentRecordDTO,repayment.getId());
+        } else{
+            //审批意见为通过,无法修改
+            if(repaymentRecordVOS.get(repaymentRecordVOS.size()-1).getApprovalDecision().equals(DecisionEnum.PASS.getMsg()))
+                throw new DescribeException(DISBURSEMENT_HAS_COMPLETED);
+            repaymentRecordService.updateRepaymentRecordById(repaymentRecordDTO,recordId);
+        }
+        // DisbursementVO disbursementVO = disbursementService.addDisbursement(disbursementDTO);
+
+        //修改状态
+        if(isCleared(caseId)){//若结清,则回款完成
+            repaymentService.updateIsClearedByCaseId(true,caseId);
+            stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.REPAY_START.getLabel(), caseId);
+        }
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(),StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
+    @GetMapping("/{caseId}/appravalDetails")
+    @ApiOperation("显示审批详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails2(@PathVariable("caseId")Long caseId){
+        return ResultUtil.success("success",getDetails(caseId));
+    }
+
+    //TODO:在回款记录添加审批记录,且每次审批完之后才能再回款
+    @PostMapping("/approval/pass")
+    @ApiOperation(value = "回款审批")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result repaymentApproval(@RequestBody ApprovalDTO approvalDTO) {
+        if(ObjectUtils.isEmpty(approvalDTO)||approvalDTO.getCaseId() == null)
+            throw new DescribeException(INPUT_ERROR);
+
+        if(!loanService.existsByIdAndIsDelete(approvalDTO.getCaseId()))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        Long caseId = approvalDTO.getCaseId();
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);
+        if(!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //填写审批意见
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        repaymentRecordService.updateApprovalById(approvalDTO.getComments(),DecisionEnum.REJECT.getMsg(),repayment.getId());
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        //修改出款单
+        repaymentService.updateApprovalUserByCaseId(BaseContext.getCurrentId(),caseId);
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(), BaseContext.getCurrentId(), caseId);
+        if(isCleared(caseId))
+            stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.REPAY_APPROVAL.getLabel(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.PROCESS.getMsg(), StepPropertyEnum.FINANCE_CHECK.getLabel(),caseId);
+
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/approval/reject")
+    @ApiOperation(value = "回款审批驳回")
+    @PreAuthorize("@pms.hasRole('APPROVER')")
+    public Result repaymentCancel(@RequestBody ApprovalDTO approvalDTO) {
+        if(ObjectUtils.isEmpty(approvalDTO)||approvalDTO.getCaseId() == null)
+            throw new DescribeException(INPUT_ERROR);
+
+        if(!loanService.existsByIdAndIsDelete(approvalDTO.getCaseId()))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        Long caseId = approvalDTO.getCaseId();
+        StepVO step = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_START.getLabel(), caseId);
+        if(step.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(PRE_STEP_NOT_COMPLETE);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(),caseId);
+        if(stepVO.getStatus().equals(StepEnum.COMPLETED.getMsg()))
+            throw new DescribeException(ExceptionEnum.STEP_HAS_COMPLETEED);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        //填写驳回意见
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        repaymentRecordService.updateApprovalById(approvalDTO.getComments(),DecisionEnum.REJECT.getMsg(),repayment.getId());
+
+        //修改出款单
+        repaymentService.updateApprovalUserByCaseId(BaseContext.getCurrentId(),caseId);
+
+        //修改负责人
+        stepService.updateUserByCaseId(StepPropertyEnum.REPAY_APPROVAL.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(), StepPropertyEnum.REPAY_START.getLabel(),  caseId);
+        stepService.updateStatusByCaseId(StepEnum.UNSTART.getMsg(), StepPropertyEnum.REPAY_APPROVAL.getLabel(), caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
+    @GetMapping("/financeDetails")
+    @ApiOperation("显示财务核算详情")//与loanContraller的方法一致,但为了规范
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER','LEAD_SALES', 'ASSIST_SALES', 'FINANCE', 'BACK_OFFICE')")
+    public Result findLoanCaseDetails3(@RequestParam Long caseId){
+        if(caseId==null)
+            throw new DescribeException(INPUT_ERROR);
+        return ResultUtil.success("success",getDetails(caseId));
+    }
+
+    @PostMapping("/financeCheck")
+    @ApiOperation(value = "财务核算")
+    @PreAuthorize("@pms.hasRole('FINANCE')")
+    public Result financeDisbursement( @RequestParam Long caseId,@RequestParam Double interest) {
+        if(caseId==null||!loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.FINANCE_CHECK.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        if(!repayment.getIsCleared())
+            throw new DescribeException(FUND_NOT_CLEAR);
+
+//        Long currentId = stepVO.getUserId1();
+//        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+//            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+//        }
+
+        //修改回款单
+        repaymentService.updateIntersetsByCaseId(interest,caseId);
+
+        //修改状态
+        stepService.updateUserByCaseId(StepPropertyEnum.FINANCE_CHECK.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId( StepEnum.COMPLETED.getMsg(),StepPropertyEnum.FINANCE_CHECK.getLabel(),caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.BALANCE_REPAY.getLabel(), caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
+    private Boolean isCleared(Long caseId){
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        //获取回款记录
+        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
+
+        Double currentAmount= 0.0;
+        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
+            currentAmount += repaymentRecordVO.getAmount();
+
+        Double totalAmount = repaymentService.findByCaseIdAndIsDelete(caseId, false).getTotalAmount();
+
+        return (totalAmount-currentAmount)< Double.MIN_VALUE;
+
+    }
+
+    @PostMapping("/balanceRepay")
+    @ApiOperation(value = "费息回款")
+    @PreAuthorize("@pms.hasAnyRoles('LEAD_SALES', 'ASSIST_SALES')")
+    public Result balanceRepay(@RequestParam Long caseId , @RequestBody RepaymentRecordDTO repaymentRecordDTO , @RequestParam String way) {
+        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.findByStepNameAndCaseId(StepPropertyEnum.BALANCE_REPAY.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        repaymentService.updateRepayWayByCaseId(way,caseId);
+        //添加回款记录
+        repaymentRecordDTO.setIsInterest( true);
+        repaymentRecordService.addRepaymentRecord(repaymentRecordDTO, repaymentService.findByCaseIdAndIsDelete(caseId, false).getId());
+
+        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.BALANCE_REPAY.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.BALANCE_REPAY.getLabel(),caseId);
+        stepService.updateStatusByCaseId(StepEnum.PROCESS.getMsg(),StepPropertyEnum.FINANCE_CONFIRM.getLabel(), caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
+    @PostMapping("/financeConfirm")
+    @ApiOperation(value = "财务确认")
+    @PreAuthorize("@pms.hasRole('FINANCE')")
+    public Result financeConfirm(@RequestParam Long caseId) {
+        if(caseId==null || !loanService.existsByIdAndIsDelete(caseId))
+            throw new DescribeException(ExceptionEnum.PROJECT_NOT_EXIST);
+
+        StepVO stepVO = stepService.findByStepNameAndCaseId(StepPropertyEnum.FINANCE_CONFIRM.getLabel(),caseId);
+        if(ObjectUtils.isEmpty(stepVO)||!stepVO.getStatus().equals(StepEnum.PROCESS.getMsg()))
+            throw new DescribeException(STEP_HAS_NOT_PROCESS);
+
+        Long currentId = stepVO.getUserId1();
+        if(currentId!=null && !BaseContext.getCurrentId().equals(currentId)){
+            throw new DescribeException(STEP_USER_NOT_EXPECTED);
+        }
+
+        stepService.updateUserId1ByCaseIdAndStepName(StepPropertyEnum.FINANCE_CONFIRM.getLabel(), BaseContext.getCurrentId(), caseId);
+        stepService.updateStatusByCaseId(StepEnum.COMPLETED.getMsg(),StepPropertyEnum.FINANCE_CONFIRM.getLabel(),caseId);
+
+        //TODO:微信推送预审通过消息和通知下一环节
+//        SysMessage message = new SysMessage();
+//        message.setMobile(null);
+//        message.setUserRole("");
+//        message.setMessageTitle("");
+//        message.setMessageContent("");
+//        message.setStepName("");
+//        message.setRelatedId(loanCase.getId());
+//        message.setRelatedType("");
+//        messageService.addMessage(message);
+//        wxService.sendTemplateMessage(loanCase.getCustomer().getMobile(),new TemplateMessage());
+
+        return ResultUtil.success("success");
+    }
+
+    private RepaymentDetailVO getDetails(Long caseId){
+        DisbursementDetailVO disbursementDetailVO = disbursementService.getLoanCaseAndCustomerByCaseId(caseId);
+        RepaymentDetailVO repaymentDetailVO = new RepaymentDetailVO();
+        repaymentDetailVO.setCustomer(disbursementDetailVO.getCustomer());
+        repaymentDetailVO.setLoanCase(disbursementDetailVO.getLoanCase());
+
+        //填充
+        Repayment repayment = repaymentService.findByCaseIdAndIsDelete(caseId, false);
+        List<RepaymentRecordVO> repaymentRecordVOS = repaymentRecordService.findByRepaymentIdAndIsDelete(repayment.getId(), false);
+        Double currentAmount= 0.0;
+        for (RepaymentRecordVO repaymentRecordVO : repaymentRecordVOS)
+            if(repaymentRecordVO.getApprovalDecision().equals(DecisionEnum.PASS.getMsg())&& !repaymentRecordVO.getIsInterest())//审批、财务环节显示审批通过后的总额
+                currentAmount += repaymentRecordVO.getAmount();
+
+        repaymentDetailVO.setRepaymentRecords(repaymentRecordVOS);
+        repaymentDetailVO.setCurrentAmount(currentAmount);
+        repaymentDetailVO.setTotalAmount(repayment.getTotalAmount());
+        //财务核算后
+        repaymentDetailVO.setInterests(repayment.getInterest());
+        //余额回款
+        repaymentDetailVO.setWay(repayment.getRepayWay());
+
+        return repaymentDetailVO;
+    }
+
 }

+ 128 - 0
src/main/java/com/loan/system/controller/wechat/StatisticsController.java

@@ -0,0 +1,128 @@
+package com.loan.system.controller.wechat;
+
+import com.loan.system.domain.pojo.Result;
+import com.loan.system.utils.ResultUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/wechat/statistics")
+@Api("数据统计接口")
+public class StatisticsController {
+
+    @GetMapping("/dailyReport")
+    @ApiOperation("获取日报表")
+    public Result dailyReport(@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
+                              @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
+
+        //TODO:统计echart数据
+//        Map<String, Object> stats = new HashMap<>();
+//
+//        // 示例数据 - 需要替换为真实数据库查询
+//        stats.put("roles", Map.of(
+//                "student", userService.countByRole("student"),
+//                "school_admin", userService.countByRole("school_admin"),
+//                "admin", userService.countByRole("admin")
+//        ));
+//
+//        stats.put("status", Map.of(
+//                "active", userService.countByStatus("active"),
+//                "inactive", userService.countByStatus("inactive")
+//        ));
+
+        return ResultUtil.success();
+    }
+
+    @GetMapping("/financeEfficiency")
+    @ApiOperation("获取资金效率表")
+    public Result financeEfficiency(@DateTimeFormat(pattern = "yyyy-MM") LocalDate begin,
+                                    @DateTimeFormat(pattern = "yyyy-MM") LocalDate end) {
+        return ResultUtil.success();
+    }
+
+    @GetMapping("/financeBalance")
+    @ApiOperation("获取资金余额")
+    public Result financeBalance(@DateTimeFormat(pattern = "yyyy-MM") LocalDate begin,
+                                 @DateTimeFormat(pattern = "yyyy-MM") LocalDate end) {
+        return ResultUtil.success();
+    }
+
+    @GetMapping("/schedule")
+    @ApiOperation("获取业务安排表")
+    public Result schedule(@RequestParam Long caseId) {
+        return ResultUtil.success();
+    }
+
+    //到处数据
+    public void exportBusinessData(HttpServletResponse response) {
+        LocalDate begin = LocalDate.now().minusDays(30);
+        LocalDate end = LocalDate.now().minusDays(1);
+
+        //查询概览运营数据,提供给Excel模板文件
+        //BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
+
+        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
+        try {
+            //基于提供好的模板文件创建一个新的Excel表格对象
+            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
+
+            //获得Excel文件中的一个Sheet页
+            XSSFSheet sheet = excel.getSheet("Sheet1");
+            sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
+
+            //获得第4行
+            XSSFRow row = sheet.getRow(3);
+            //获取单元格
+//            row.getCell(2).setCellValue(businessData.getTurnover());
+//            row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
+//            row.getCell(6).setCellValue(businessData.getNewUsers());
+//
+//            row = sheet.getRow(4);
+//            row.getCell(2).setCellValue(businessData.getValidOrderCount());
+//            row.getCell(4).setCellValue(businessData.getUnitPrice());
+//
+//            for (int i = 0; i < 30; i++) {
+//                LocalDate date = begin.plusDays(i);
+//                //准备明细数据
+//                businessData = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
+//                row = sheet.getRow(7 + i);
+//                row.getCell(1).setCellValue(date.toString());
+//                row.getCell(2).setCellValue(businessData.getTurnover());
+//                row.getCell(3).setCellValue(businessData.getValidOrderCount());
+//                row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
+//                row.getCell(5).setCellValue(businessData.getUnitPrice());
+//                row.getCell(6).setCellValue(businessData.getNewUsers());
+//            }
+            //通过输出流将文件下载到客户端浏览器中
+            ServletOutputStream out = response.getOutputStream();
+            excel.write(out);
+
+            //关闭资源
+            out.flush();
+            out.close();
+            excel.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+}

+ 90 - 57
src/main/java/com/loan/system/controller/wechat/UploadController.java

@@ -11,6 +11,8 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.io.FilenameUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -18,6 +20,8 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.net.URLEncoder;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
@@ -35,61 +39,88 @@ public class UploadController {
     /** 上传文件(支持任意类型,只要在白名单内) */
     @PostMapping("/upload/{caseId}/{type}")
     @ApiOperation("文件上传")//若合同不是统一提交,则合同1,合同2,合同3
-    public Result uploadFile(@PathVariable("caseId") Long caseId,@PathVariable("type") String fileType,@RequestParam("file") MultipartFile[] files) throws IOException{
-        fileService.deleteFileByCaseIdAndDictType(caseId,fileType);
-        //删除本地文件
-        deleteFile(caseId,fileType);
+    public Result uploadFile(@PathVariable("caseId") Long caseId,@PathVariable("type") String fileType,@RequestParam MultipartFile file,@RequestParam Map<String , String>  isDelete) throws IOException{
+        Iterator<Map.Entry<String, String>> iterator = isDelete.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, String> entry = iterator.next();
+            System.out.println(entry.getKey());
+            Long id = Long.parseLong(entry.getKey());
+            System.out.println(entry.getValue());
+            Integer value = Integer.parseInt(entry.getValue());
+            Document document = fileService.findById(id);
+            if (ObjectUtils.isEmpty( document))
+                break;
 
-        List<DocumentVO> fileList = new ArrayList<>();
-        for (int i=0 ; i < files.length ; i++){
-            MultipartFile file =files[i];
+            if( value!= 0 ){
+                fileService.deleteFileById(id);
+                //删除本地文件
+               deleteFile1(document.getFilePath());
+            }
+        }
 
-            if (file.isEmpty())
-                return ResultUtil.error(ExceptionEnum.FILE_IS_EMPTY);
+        if (file.isEmpty())
+            return ResultUtil.error(ExceptionEnum.FILE_IS_EMPTY);
 
-            String originalName = file.getOriginalFilename();
-            String ext = FilenameUtils.getExtension(originalName).toLowerCase(Locale.ROOT);
+        String originalName = file.getOriginalFilename();
+        String ext = FilenameUtils.getExtension(originalName).toLowerCase(Locale.ROOT);
 
-            // 从配置中读取允许的扩展名
-            Set<String> allowed = config.getAllowedExtensions();
-            if (!allowed.contains(ext)) {
-                ResultUtil.error(ExceptionEnum.FILE_UPLOAD_TYPE_NOT_DEFINED);
-            }
+        // 从配置中读取允许的扩展名
+        Set<String> allowed = config.getAllowedExtensions();
+        if (!allowed.contains(ext)) {
+            ResultUtil.error(ExceptionEnum.FILE_UPLOAD_TYPE_NOT_DEFINED);
+        }
 
-            String newFileName = null;
-            // 生成新的文件名
-            if(i == 0)
-                newFileName = String.format("%d-%s-%s.%s", caseId, fileType, originalName, ext);
-            else
-                newFileName = String.format("%d-%s-%s(%d).%s", caseId, fileType, originalName, i, ext);
-
-            // 创建目录
-            File uploadDir = new File(config.getUploadDir(), caseId + "/" + fileType);
-            if (!uploadDir.exists() && !uploadDir.mkdirs()) {
-                return ResultUtil.error(ExceptionEnum.DIRECTORY_CREATE_ERROR);
-            }
+        String newFileName = String.format("%d-%s-%s.%s", caseId, fileType, UUID.randomUUID(), ext);;
+        // 生成新的文件名
 
-            // 使用NIO复制流,稳定性更好
-            File destFile = new File(uploadDir, newFileName);
-            try (InputStream in = file.getInputStream()) {
-                Files.copy(in, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
-            }
+        // 创建目录
+        File uploadDir = new File(config.getUploadDir(), caseId + "/" + fileType);
+        System.out.println(uploadDir);
+        System.out.println(newFileName);
+        if (!uploadDir.exists() && !uploadDir.mkdirs()) {
+            return ResultUtil.error(ExceptionEnum.DIRECTORY_CREATE_ERROR);
+        }
+
+        // 使用NIO复制流,稳定性更好
+        File destFile = new File(uploadDir, newFileName);
+        try (InputStream in = file.getInputStream()) {
+            System.out.println(destFile.toPath());
+            Files.copy(in, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+        }
+
+        Document document = new Document();
+        document.setCaseId(caseId);
+        document.setFileName(newFileName);
+        document.setOriginName(originalName);
+        document.setFilePath(destFile.getPath());
+        document.setFileSize(file.getSize());
+        document.setDocType(ext);
+        document.setDictType(fileType); // 简单转换为整数
+        document.setIsDelete( false);
+        document.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        document.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        DocumentVO documentVO = fileService.uploadFile(document);
+
+        return ResultUtil.success("上传成功",documentVO);
+    }
 
-            Document document = new Document();
-            document.setCaseId(caseId);
-            document.setFileName(newFileName);
-            document.setOriginName(originalName);
-            document.setFilePath(destFile.getPath());
-            document.setFileSize(file.getSize());
-            document.setDocType(ext);
-            document.setDictType(fileType);
-            document.setIsDelete( false);
-            document.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-            document.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
-            fileList.add(fileService.uploadFile(document));
+    private void deleteFile1(String filePath) {
+        if (filePath == null || filePath.isEmpty()) {
+            return;
         }
 
-        return ResultUtil.success("上传成功", fileList);
+        try {
+            Path path = Paths.get(filePath);
+            boolean deleted = Files.deleteIfExists(path);
+            if (deleted) {
+                System.out.println("文件删除成功: " + filePath);
+            } else {
+                System.out.println("文件不存在或已被删除: " + filePath);
+            }
+        } catch (IOException e) {
+            System.err.println("删除文件时发生错误: " + e.getMessage());
+            e.printStackTrace();
+        }
     }
 
 
@@ -134,42 +165,44 @@ public class UploadController {
         return ResultUtil.success("文件删除成功");
     }
 
+    /** 删除文件 */
     /** 删除文件 */
     private void deleteFile(Long caseId, String fileType) {
         // 构造待删除文件所在的目录路径
         File uploadDir = new File(config.getUploadDir(), caseId + "/" + fileType);
 
         if (!uploadDir.exists()) {
+            System.out.println("Directory does not exist: " + uploadDir.getAbsolutePath());
             return; // 目录不存在,直接返回
         }
 
         // 获取目录下所有文件
         File[] files = uploadDir.listFiles();
         if (files == null || files.length == 0) {
+            System.out.println("No files to delete in directory: " + uploadDir.getAbsolutePath());
             return; // 没有文件需要删除
         }
 
         boolean allDeleted = true;
         for (File file : files) {
+            System.out.println("Attempting to delete file: " + file.getAbsolutePath());
             if (!file.delete()) { // 尝试删除每个文件
                 allDeleted = false; // 如果有文件未能成功删除,则标记为false
-                break;
+                System.out.println("Failed to delete file: " + file.getAbsolutePath());
+            } else {
+                System.out.println("Successfully deleted file: " + file.getAbsolutePath());
             }
         }
 
-//        if (allDeleted) {
-//            // 尝试删除空目录
-//            if (!uploadDir.delete()) {
-//                // 如果删除目录失败,可以记录日志或采取其他措施
-//                System.out.println("Failed to delete empty directory: " + uploadDir.getAbsolutePath());
-//            }
-//        } else {
-//            // 如果有文件未能成功删除,可以记录日志或采取其他措施
-//            System.out.println("Failed to delete some files in directory: " + uploadDir.getAbsolutePath());
-//        }
+        if (!allDeleted) {
+            System.out.println("Failed to delete some files in directory: " + uploadDir.getAbsolutePath());
+        } else {
+            System.out.println("All files deleted successfully in directory: " + uploadDir.getAbsolutePath());
+        }
     }
 
 
+
 //    @PostMapping("save/{caseId}/{type}")
 //    public Result saveFile(@PathVariable("caseId") Long caseId,@PathVariable("type") String type,@RequestParam String fileName){
 //        return ResultUtil.success();

+ 26 - 28
src/main/java/com/loan/system/controller/wechat/UserController.java

@@ -1,14 +1,17 @@
 package com.loan.system.controller.wechat;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.loan.system.constant.JwtClaimsConstant;
 import com.loan.system.domain.dto.UserLoginDTO;
 import com.loan.system.domain.dto.WeChatLoginDTO;
+import com.loan.system.domain.entity.BizRecommender;
 import com.loan.system.domain.entity.Customer;
 import com.loan.system.domain.entity.Role;
 import com.loan.system.domain.entity.User;
 import com.loan.system.domain.enums.ExceptionEnum;
 import com.loan.system.domain.enums.RoleEnum;
 import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.BizRecommenderVO;
 import com.loan.system.domain.vo.CustomerLoginVO;
 import com.loan.system.domain.vo.CustomerVO;
 import com.loan.system.domain.vo.UserLoginVO;
@@ -27,14 +30,17 @@ import org.apache.commons.lang3.ObjectUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import javax.security.auth.login.LoginException;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @author Edwin
@@ -220,39 +226,31 @@ public class UserController {//包含内部人员、外部人员
         return ResultUtil.success("success");
     }
 
-    @GetMapping("/user/info")
-    @ApiOperation("查询用户信息")
-    public Result findUserInfo(){
-        return ResultUtil.success("success");
-    }
-
-    @GetMapping("/customers")
-    @ApiOperation("查询所有客户")
-    public Result findAllCustomers(){
-        return ResultUtil.success("success", customerService.getAllCustomers(false));
-    }
-
-    @GetMapping("/customers/{id}")
-    @ApiOperation("按id选择客户")
-    public Result findCustomerById(@PathVariable Long id){
-        return ResultUtil.success("success", customerService.findByCustomerIdAndIsDelete( id, false));
-    }
-
-    @GetMapping("/customers/{key}")
-    @ApiOperation("按关键字(姓名/手机号)选择客户")
-    public Result findCustomerByKey(@PathVariable("key") String key){
-        return ResultUtil.success("success", customerService.getCustomerByKey(key,false));
-    }
+//    @GetMapping("/users")
+//    @ApiOperation("查询所有用户")
+//    public Result findAllUsers(Boolean isDelete){
+//        return ResultUtil.success("success", userService.getAllUsers(isDelete));
+//    }
 
-    @GetMapping("/users")
-    @ApiOperation("查询所有用户")
-    public Result findAllUsers(Boolean isDelete){
-        return ResultUtil.success("success", userService.getAllUsers(isDelete));
+    @GetMapping("/users/sales")
+    @ApiOperation("查询所有业务员")
+    @PreAuthorize("@pms.hasAnyRoles('SYSTEM_ADMIN','APPROVER')")
+    public Result findAllSales(){
+        return ResultUtil.success("success", userService.getAllSalesByIsDelete(false));
     }
 
     @GetMapping("/recommenders")
     @ApiOperation("查询所有推荐人")
     public Result findAllRecommenders(Boolean isDelete){
-        return ResultUtil.success("success", userService.getAllRecommenders(isDelete));
+        List<BizRecommender> allRecommenders = userService.getAllRecommenders(isDelete);
+
+        return ResultUtil.success("success", allRecommenders.stream()
+                .collect(Collectors.groupingBy(
+                        BizRecommender::getChannelName,         // 第一层 key:channel
+                        Collectors.groupingBy(
+                                BizRecommender::getGroup,   // 第二层 key:group
+                                Collectors.toList()) // 第三层
+                        )
+                ));
     }
 }

+ 28 - 0
src/main/java/com/loan/system/domain/dto/BizRecommenderDTO.java

@@ -0,0 +1,28 @@
+package com.loan.system.domain.dto;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BizRecommenderDTO implements Serializable {
+    private String recommenderCode;
+    private String recommenderName;
+    private String mobile;
+    private String channelName;
+    private String group;
+    private String idCard;
+    private String bankAccount;
+    private BigDecimal commissionRate;
+    private String company;
+    private String remark;//备注
+    private Boolean isDelete;
+
+}

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

@@ -19,8 +19,8 @@ public class ContractDTO implements Serializable {
     private Long customerId;//客户id
     private String contractNo;// 合同编号
     private String contractName;//合同名称
-    private BigDecimal contractAmount;//借款金额
-    private BigDecimal interestRate;//年利率
+    private Double contractAmount;//借款金额
+    private Double interestRate;//年利率
     private Integer loanPeriod;//借款期限
     private String content;//合同内容
 }

+ 4 - 4
src/main/java/com/loan/system/domain/dto/DisbursementDTO.java

@@ -15,11 +15,11 @@ import java.time.Instant;
 @NoArgsConstructor
 public class DisbursementDTO extends BaseEntity {
     private Long caseId;//业务id
-    private Long payoutApproveUserId;//出款审批人 id
-    private Long payoutOperatorUserId;//财务出款人
-    private Long applyBy;//出款上报人id
+//    private Long payoutApproveUserId;//出款审批人 id
+//    private Long payoutOperatorUserId;//财务出款人
+//    private Long applyBy;//出款上报人id
     //private String disbursementType;//押品/财务
-    private BigDecimal plannedAmount;//计划金额
+    private Double plannedAmount;//计划金额
     private String plannedLocation;//计划地点
     private String disbursementStatus;//出款状态
     //private Long contractId;//合同id

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

@@ -16,8 +16,7 @@ import java.math.BigDecimal;
 @NoArgsConstructor
 public class DisbursementRecordDTO implements Serializable {
     private Long disbursementId;
-    private BigDecimal amount;
-    private String createTime;
+    private Double amount;
     private String disbursementLocation;
     private String disbursementAccount;
     private String disbursementBank;

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

@@ -0,0 +1,22 @@
+package com.loan.system.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RepaymentRecordDTO implements Serializable {
+
+    private Long repaymentId;
+    private Double amount;
+    private String repayBank;
+    private String repayLocation;
+    private String repayAccount;
+    private Boolean isInterest;//是否为费息
+
+}

+ 23 - 0
src/main/java/com/loan/system/domain/dto/UserDTO.java

@@ -0,0 +1,23 @@
+package com.loan.system.domain.dto;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserDTO implements Serializable {
+    private String username;
+    private String password;
+    private String realName;
+    private String sex;
+    private String mobile;
+    private String role;
+    private String dept;
+
+}

+ 5 - 16
src/main/java/com/loan/system/domain/entity/BizRecommender.java

@@ -7,9 +7,7 @@ import java.math.BigDecimal;
 import java.time.Instant;
 
 @Entity
-@Table(name = "biz_recommender", uniqueConstraints = {
-        @UniqueConstraint(name = "recommender_code", columnNames = {"recommender_code"})
-})
+@Table(name = "biz_recommender")
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
@@ -22,14 +20,11 @@ public class BizRecommender extends BaseEntity{
     @Column(name = "recommender_name", length = 100)
     private String recommenderName;
 
-    @Column(name = "recommender_type", length = 50)
-    private String recommenderType;
+    @Column(name = "mobile", length = 20)
+    private String mobile;
 
-    @Column(name = "phone", length = 20)
-    private String phone;
-
-    @Column(name = "channel", length = 50)
-    private String channel;
+    @Column(name = "channel_name", length = 50)
+    private String channelName;
 
     @Column(name = "group" ,length = 50)
     private String group;
@@ -56,12 +51,6 @@ public class BizRecommender extends BaseEntity{
     @Column(name = "update_time")
     private String updateTime;
 
-    @Column(name = "create_user_id")
-    private Long createUserId;
-
-    @Column(name = "update_user_id")
-    private Long updateUserId;
-
     @Column(name = "is_delete")
     private Boolean isDelete;
 

+ 3 - 7
src/main/java/com/loan/system/domain/entity/Contract.java

@@ -7,11 +7,7 @@ import java.math.BigDecimal;
 import java.time.Instant;
 
 @Entity
-@Table(name = "contract", indexes = {
-        @Index(name = "idx_case_id", columnList = "case_id")
-}, uniqueConstraints = {
-        @UniqueConstraint(name = "contract_no", columnNames = {"contract_no"})
-})
+@Table(name = "contract")
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
@@ -37,10 +33,10 @@ public class Contract extends BaseEntity{
     private Integer contractVersion;
 
     @Column(name = "contract_amount", precision = 15, scale = 2)
-    private BigDecimal contractAmount;
+    private Double contractAmount;
 
     @Column(name = "interest_rate", precision = 5, scale = 4)
-    private BigDecimal interestRate;
+    private Double interestRate;
 
     @Column(name = "loan_period")
     private Integer loanPeriod;

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

@@ -40,6 +40,9 @@ public class Customer extends BaseEntity{
     @Column(name = "bank_account", length = 64)
     private String bankAccount;
 
+    @Column(name = "bank_name", length = 50)
+    private String bankName;
+
     @Column(name = "face_auth")
     private Boolean faceAuth;
 

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

@@ -38,7 +38,7 @@ public class Disbursement extends BaseEntity{
     private String disbursementType;
 
     @Column(name = "planned_amount", precision = 18, scale = 2)
-    private BigDecimal plannedAmount;
+    private Double plannedAmount;
 
     @Column(name = "planned_location")
     private String plannedLocation;
@@ -49,8 +49,8 @@ public class Disbursement extends BaseEntity{
     @Column(name = "contract_id")
     private Long contractId;
 
-    @Column(name = "payout_time")
-    private String payoutTime;
+    @Column(name="comments", length = 200)
+    private String comments;
 
     @Column(name = "create_time")
     private String createTime;

+ 4 - 1
src/main/java/com/loan/system/domain/entity/DisbursementRecord.java

@@ -20,8 +20,11 @@ public class DisbursementRecord extends BaseEntity{
     @Column(name = "disbursement_id")
     private Long disbursementId;
 
+    @Column(name = "finance_id",length = 20)
+    private Long financeId;
+
     @Column(name = "amount", precision = 18, scale = 2)
-    private BigDecimal amount;
+    private Double amount;
 
     @Column(name = "create_time")
     private String createTime;

+ 16 - 26
src/main/java/com/loan/system/domain/entity/Repayment.java

@@ -7,11 +7,7 @@ import java.math.BigDecimal;
 import java.time.Instant;
 
 @Entity
-@Table(name = "repayment", indexes = {
-        @Index(name = "idx_case_id", columnList = "case_id"),
-        @Index(name = "idx_repay_at", columnList = "repay_at"),
-        @Index(name = "idx_is_cleared", columnList = "is_cleared")
-})
+@Table(name = "repayment")
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
@@ -24,42 +20,36 @@ public class Repayment extends BaseEntity{
     @Column(name = "contract_id")
     private Long contractId;
 
-    @Column(name = "repay_by_customer_id")
-    private Long repayByCustomerId;
+    @Column(name = "customer_id")
+    private Long customerId;
 
-    @Column(name = "repayment_plan_user_id")
-    private Long repaymentPlanUserId;
+    @Column(name = "start_user_id")
+    private Long startUserId;
 
-    @Column(name = "repayment_operator_user_id")
-    private Long repaymentOperatorUserId;
+    @Column(name = "approval_user_id")
+    private Long approvalUserId;
 
     @Column(name = "repayment_type", length = 10)
     private String repaymentType;
 
-    @Column(name = "repay_amount", precision = 18, scale = 2)
-    private BigDecimal repayAmount;
+    @Column(name = "total_amount", precision = 18, scale = 2)
+    private Double totalAmount;
 
-    @Column(name = "repay_at")
-    private Instant repayAt;
-
-    @Column(name = "repay_bank", length = 2000)
-    private String repayBank;
-
-    @Column(name = "repay_record_id")
-    private Long repayRecordId;
-
-    @Column(name = "confirmed_by")
-    private Long confirmedBy;
+    @Column(name = "confirmed_id")
+    private Long confirmedId;
 
     @Column(name = "confirmed_at")
-    private Instant confirmedAt;
+    private String confirmedAt;
 
     @Column(name = "interest", precision = 18, scale = 2)
-    private BigDecimal interest;
+    private Double interest;
 
     @Column(name = "is_cleared")
     private Boolean isCleared;
 
+    @Column(name = "repay_way",length = 10)
+    private String repayWay;
+
     @Column(name = "create_time")
     private String createTime;
 

+ 31 - 6
src/main/java/com/loan/system/domain/entity/RepaymentRecord.java

@@ -2,29 +2,54 @@ package com.loan.system.domain.entity;
 
 import lombok.*;
 
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.Table;
+import javax.persistence.*;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.time.Instant;
 
+
 @Entity
 @Table(name = "repayment_record")
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
-public class RepaymentRecord extends BaseEntity{
+public class RepaymentRecord extends BaseEntity {
     private static final long serialVersionUID = 19L;
+
     @Column(name = "repayment_id")
     private Long repaymentId;
 
     @Column(name = "amount", precision = 18, scale = 2)
-    private BigDecimal amount;
+    private Double amount;
 
     @Column(name = "create_time")
     private String createTime;
 
+    @Size(max = 200)
+    @Column(name = "repay_bank", length = 200)
+    private String repayBank;
+
+    @Size(max = 200)
+    @Column(name = "repay_location", length = 200)
+    private String repayLocation;
+
+    @Size(max = 20)
+    @Column(name = "repay_account", length = 20)
+    private String repayAccount;
+
+    @Column(name = "approval_comment")
+    private String approvalComment;
+
+    @Column(name = "approval_decision")
+    private String approvalDecision;
+
+    @Column(name = "approval_user_id")
+    private Long approvalUserId;
+
+    @Column(name = "is_interest")
+    private Boolean isInterest;
+
     @Column(name = "is_delete")
     private Boolean isDelete;
 

+ 2 - 2
src/main/java/com/loan/system/domain/entity/StatBusinessSnapshot.java

@@ -19,7 +19,7 @@ public class StatBusinessSnapshot extends BaseEntity{
     private static final long serialVersionUID = 20L;
 
     @Column(name = "stat_date")
-    private LocalDate statDate;
+    private String statDate;
 
     @Column(name = "channel", length = 50)
     private String channel;
@@ -31,7 +31,7 @@ public class StatBusinessSnapshot extends BaseEntity{
     private Integer applicationCount;
 
     @Column(name = "total_loan_amount", precision = 15, scale = 2)
-    private BigDecimal totalLoanAmount;
+    private Double totalLoanAmount;
 
     @Column(name = "user_id")
     private Long userId;

+ 2 - 2
src/main/java/com/loan/system/domain/entity/StatFundEfficiency.java

@@ -21,13 +21,13 @@ public class StatFundEfficiency extends BaseEntity{
     private String statMonth;
 
     @Column(name = "daily_loan_balance", precision = 15, scale = 2)
-    private BigDecimal dailyLoanBalance;
+    private Double dailyLoanBalance;
 
     @Column(name = "actual_days")
     private Integer actualDays;
 
     @Column(name = "interest_income", precision = 15, scale = 2)
-    private BigDecimal interestIncome;
+    private Double interestIncome;
 
     @Column(name = "create_time")
     private String createTime;

+ 9 - 6
src/main/java/com/loan/system/domain/entity/SysMessage.java

@@ -13,8 +13,11 @@ import java.time.Instant;
 public class SysMessage extends BaseEntity{
     private static final long serialVersionUID = 23L;
 
-    @Column(name = "user_id")
-    private Long userId;
+    @Column(name = "mobile",length = 11)
+    private String  mobile;
+
+    @Column(name = "user_role",length = 20)
+    private String userRole;
 
     @Column(name = "message_title", length = 200)
     private String messageTitle;
@@ -23,11 +26,11 @@ public class SysMessage extends BaseEntity{
     @Column(name = "message_content")
     private String messageContent;
 
-    @Column(name = "message_type", length = 50)
-    private String messageType;
+    @Column(name = "step_name", length = 50)
+    private String stepName;
 
     @Column(name = "read_status")
-    private Byte readStatus;
+    private Boolean readStatus;
 
     @Column(name = "related_id")
     private Long relatedId;
@@ -36,7 +39,7 @@ public class SysMessage extends BaseEntity{
     private String relatedType;
 
     @Column(name = "create_time")
-    private Instant createTime;
+    private String createTime;
 
     @Column(name = "is_delete")
     private Boolean isDelete;

+ 13 - 8
src/main/java/com/loan/system/domain/enums/ExceptionEnum.java

@@ -16,9 +16,9 @@ public enum ExceptionEnum {
      * -150 ~   -199    用户管理
      * -200 ~   -249    业务管理
      * -250 ~   -299    合同管理
-     * -300 ~   -349    模块管理
+     * -300 ~   -349    审批管理
      * -350 ~   -399    环节管理
-     * -400 ~   -449    支付管理
+     * -400 ~   -449    出款/回款管理
      * -450 ~   -499    系统管理
      */
 
@@ -64,7 +64,7 @@ public enum ExceptionEnum {
     USER_NUMBER_EXIST(-114, "工号已存在"),
 
     PROJECT_EXIST(-200,"项目已存在"),
-    PROJECT_NOT_EXIST(-201,"项目不存在"),
+    PROJECT_NOT_EXIST(-201,"业务不存在"),
     PROJECT_LABEL_EXIST(-202,"项目标签已存在"),
     PROJECT_LABEL_NOT_EXIST(-203,"项目标签不存在"),
     LOANCASE_IS_Completed(-204,"项目已经完成,无法重复提交"),
@@ -88,12 +88,15 @@ public enum ExceptionEnum {
     CONTRACT_SELECT_NOT_EXIST(-266, "合同采购方式不存在"),
     CONTRACT_PAYMENT_EXIST(-270,"付款已存在"),
     CONTRACT_PAYMENT_NOT_EXIST(-271,"付款不存在"),
-    CONTRACT_PAYMENT_HAS_NOT_EXIST(-272,"存在付款不存在"),
-    CONTRACT_HAS_NOT_COMPELETED(-280,"合同未完成所有支付"),
+    CONTRACT_SIGNED_PERMISSION_NOT_ALLOW(-272,"没有签署合同权限"),
+    CONTRACT_HAS_SIGNED(-280,"合同以签署完成,请勿重复操作"),
+    CONTRACT_HAS_PUSH(-281,"合同已推送,请勿重复操作"),
+    CONTRACT_NOT_PUSH(-282,"合同未推送,禁止操作"),
 
 
-    MODULE_EXIST(-300,"已存在"),
-    MODULE_NOT_EXIST(-301,"模块不存在"),
+    CANCEL_PREAPPROVAL_IS_COMPLETED(-300, "取消预审已完成,请勿重复操作"),
+    DISBURSEMENT_HAS_NOT_COMPLETED(-301, "出款未完成,无法新增"),
+    DISBURSEMENT_HAS_COMPLETED(-302, "出款已完成,无法修改"),
 
 
     STEP_EXIST(-350, "项目环节已存在"),
@@ -106,10 +109,12 @@ public enum ExceptionEnum {
     STEP_TEMPLATE_NODE_NOT_EXIST(-357,"环节模板节点读取失败"),
     STEP_USER_NOT_EXPECTED(-358,"环节处理人不是预期用户"),
     STEP_HAS_COMPLETEED(-359,"环节已完成,不能重复操作"),
+    PRE_STEP_NOT_COMPLETE(-360,"上一环节未完成,无法操作"),
+    STEP_HAS_NOT_PROCESS(-361,"环节不在进行中,无法操作"),
 
 
     FUND_EXIST(-400,"经费已存在"),
-    FUND_NOT_EXIST(-401,"经费不存在"),
+    FUND_NOT_CLEAR(-401,"财务未结清,输入无效"),
     FUND_OUTPUT_EXIST(-402,"支出表已存在"),
     FUND_OUTPUT_NOT_EXIST(-403,"支出表不存在"),
     FUND_OUTPUT_HAS_NOT_EXIST(-404,"存在支出表不存在"),

+ 38 - 0
src/main/java/com/loan/system/domain/enums/MessageEnum.java

@@ -0,0 +1,38 @@
+package com.loan.system.domain.enums;
+
+
+/**
+ * @author xuhong
+ * @date 2020/9/2 - 20:05
+ * @Description 错误枚举类
+ */
+public enum MessageEnum {
+
+    SUCCESS(200,"成功"),
+    ERROR(500,"失败"),
+    NOT_FOUND(404,"未找到"),
+    NOT_ALLOWED(405,"不允许"),
+    NOT_AUTHORIZED(401,"未授权"),
+    NOT_SUPPORTED(415,"不支持"),
+    NOT_ACCEPTABLE(406,"不可接受"),
+    NOT_FOUND_USER(404,"用户不存在"),
+    NOT_FOUND_ROLE(404,"角色不存在"),
+    NOT_FOUND_PERMISSION(404,"权限不存在")
+    ;
+
+    private Integer code;
+    private String msg;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    MessageEnum(Integer code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 7 - 7
src/main/java/com/loan/system/domain/enums/RoleEnum.java

@@ -6,13 +6,13 @@ package com.loan.system.domain.enums;
  */
 public enum RoleEnum {
     // 这里似乎不需要三个角色
-    SYSTEM_ADMIN(1, "系统管理员"),
-    APPROVER(2, "审批人员"),
-    LEAD_SALES(3, "主办业务员"),
-    ASSIST_SALES(4, "辅办业务员"),
-    FINANCE(5, "财务人员"),
-    BACK_OFFICE(6, "综合内勤"),
-    EXTERNAL(7, "外部人员");
+    SYSTEM_ADMIN(1, "SYSTEM_ADMIN"),//系统管理员
+    APPROVER(2, "APPROVER"),//审批人员
+    LEAD_SALES(3, "LEAD_SALES"),//主办业务员
+    ASSIST_SALES(4, " ASSIST_SALES"),//辅办业务员
+    FINANCE(5, "FINANCE"),//财务人员
+    BACK_OFFICE(6, "BACK_OFFICE"),//综合内勤
+    EXTERNAL(7, "EXTERNAL");//外部人员
 
     private Integer code;
     private String msg;

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

@@ -34,16 +34,19 @@ public enum StepPropertyEnum {
     REPAY_START(517, "回款启动", false),
     REPAY_APPROVAL(518, "回款审批", false),
     FINANCE_CHECK(519, "财务核算", false),
+    BALANCE_REPAY(520, "余额回款", false),
+    FINANCE_CONFIRM(521, "财务确认", false),
 
-    COLLATERAL_RECEIVE(520, "押品取证环节", true),
-    PLAN_SUBMISSION(521, "计划上报", false),
-    APPROVAL_ASSIGNMENT(522, "审批分派", false),
-    EVIDENCE_CONFIRMATION(523, "确认取证", false),
 
-    COLLATERAL_DELIVERY(524, "押品送证环节", true),
-    PLAN_SUBMISSION_2(525, "计划上报", false),
-    APPROVAL_ASSIGNMENT_2(526, "审批分派", false),
-    DELIVERY_CONFIRMATION(527, "送证确认", false);
+    COLLATERAL_RECEIVE(522, "押品取证环节", true),
+    PLAN_SUBMISSION(523, "计划上报", false),
+    APPROVAL_ASSIGNMENT(524, "审批分派", false),
+    EVIDENCE_CONFIRMATION(525, "确认取证", false),
+
+    COLLATERAL_DELIVERY(526, "押品送证环节", true),
+    PLAN_SUBMISSION_2(527, "计划上报", false),
+    APPROVAL_ASSIGNMENT_2(528, "审批分派", false),
+    DELIVERY_CONFIRMATION(529, "送证确认", false);
 
     /* ========== 字段 & 构造 ========== */
     private final int code;

+ 42 - 0
src/main/java/com/loan/system/domain/pojo/ContractInformation.java

@@ -1,4 +1,46 @@
 package com.loan.system.domain.pojo;
 
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
 public class ContractInformation {
+    //合同信息
+    private String contractNo;
+    private String contractType;
+    private String contractUsage;
+    private Double contractAmount;//合同金额
+    private Integer contractPeriod;
+    private String startDateTime;
+    private String endDateTime;
+    private Double interestRate;//合同利率
+    //客户信息
+    private String name;//客户姓名
+    private String idNumber;//客户身份证号
+    private String mobile;//客户手机号
+    private String bankName;//客户银行
+    private String bankAccount;//客户银行账号
+    private String signature1;
+    private String contactAddress1;
+    //押品信息
+    private String address;//押品地址
+    private String collateralNumber;
+    private String collateralArea;
+
+    //业务方
+    private String signature2;
+    private String contactAddress2;
+    private String userMobile;
+
+    //else
+    private Double serviceCost;
+    private Integer leastDay;
+    private Integer pages1;
+    private Integer pages2;
+    private String signLocation1;
+    private String signLocation2;
+
 }

+ 20 - 0
src/main/java/com/loan/system/domain/vo/ApprovalVO.java

@@ -0,0 +1,20 @@
+package com.loan.system.domain.vo;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ApprovalVO implements Serializable {
+    private Long CaseId;
+    private Map<UserVO, String> ApprovalDecision;
+    private Map<UserVO, String> ApprovalComment;
+
+}

+ 28 - 0
src/main/java/com/loan/system/domain/vo/BizRecommenderVO.java

@@ -0,0 +1,28 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class BizRecommenderVO implements Serializable {
+    private Long id;
+    private String recommenderCode;
+    private String recommenderName;
+    private String mobile;
+    private String channelName;
+    private String group;
+    private String idCard;
+    private String bankAccount;
+    private BigDecimal commissionRate;
+    private String company;
+    private String remark;
+
+}

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

@@ -17,8 +17,8 @@ public class ContractVO implements Serializable {
     private Long customerId;//客户id
     private String contractNo;// 合同编号
     private String contractName;//合同名称
-    private BigDecimal contractAmount;//借款金额
-    private BigDecimal interestRate;//年利率
+    private Double contractAmount;//借款金额
+    private Double interestRate;//年利率
     private Integer loanPeriod;//借款期限
     private String content;//合同内容
     private Boolean signedByCustomer;//是否签署

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

@@ -19,5 +19,6 @@ public class CustomerVO implements Serializable {
     private String mobile;
     private String marriedStatus;
     private String bankAccount;
+    private String bankName;
     private Boolean faceAuth;
 }

+ 22 - 0
src/main/java/com/loan/system/domain/vo/DictionarysVO.java

@@ -0,0 +1,22 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.DictAttribute;
+import com.loan.system.domain.entity.DictBusinessType;
+import com.loan.system.domain.entity.DictChannel;
+import com.loan.system.domain.entity.DictLocation;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DictionarysVO implements Serializable {
+    List<DictAttribute> attributes;
+    List<DictBusinessType> types;
+    List<DictLocation> locations;
+    List<DictChannel> channels;
+}

+ 31 - 0
src/main/java/com/loan/system/domain/vo/DisbursementDetailVO.java

@@ -0,0 +1,31 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.DisbursementRecord;
+import com.loan.system.domain.entity.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DisbursementDetailVO implements Serializable {
+    private CustomerVO customer;
+    private LoanCaseSimpleVO loanCase;
+    //计划上报
+    private Double disbursementAmount;
+    private String currentLocation;
+    //计划审批
+    private User repaymentUser;
+    private String approvalComment;
+    //财务出款
+    private List<DisbursementRecordVO> disbursementRecords;
+    private Double totalAmount;//总金额
+    //业务确认
+    private String confirmComment;
+
+
+}

+ 27 - 0
src/main/java/com/loan/system/domain/vo/DisbursementRecordVO.java

@@ -0,0 +1,27 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DisbursementRecordVO implements Serializable {
+    private Long id;//记录id
+    private Long disbursementId;//出款单id
+    private Long financeId;//出款负责人id
+    private Double amount;//出款金额
+    private String createTime;//创建时间
+    private String disbursementLocation;//出款地点
+    private String disbursementAccount;//出款账户
+    private String disbursementBank;//出款银行
+
+}

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

@@ -18,9 +18,10 @@ public class DisbursementVO extends BaseEntity {
     private Long applyBy;//出款上报人id
     private String applyAt;//出款申请时间
     //private String disbursementType;//押品/财务
-    private BigDecimal plannedAmount;//计划金额
+    private Double plannedAmount;//计划金额
     private String plannedLocation;//计划地点
     private String disbursementStatus;//出款状态
+    private String comments;//说明
     private String collateralStatus;//押品状态
 
 

+ 25 - 0
src/main/java/com/loan/system/domain/vo/LoanCaseSimpleVO.java

@@ -0,0 +1,25 @@
+package com.loan.system.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoanCaseSimpleVO implements Serializable {
+    private Long id;
+    private Long customerId;
+    private String businessType;
+    private String businessAttrs;
+    private String channelName;
+    private String group;
+    private Long recommenderId;
+    private BigDecimal totalLoanAmount;
+    private Boolean isComplete;
+
+}

+ 2 - 3
src/main/java/com/loan/system/domain/vo/LoanCaseVO.java

@@ -27,9 +27,7 @@ public class LoanCaseVO implements Serializable {
     private String address;//房产实际地点
     private List<Map<Long,List<Long>>> collateralAndContract;
     private List<CollateralVO> collateral;//押品
-    private String channelName;//渠道名称
-    private String group;//组别
-    private Long recommenderId;//推荐人id
+    private BizRecommenderVO recommender;//推荐人id
     private String businessType;//业务类型
     private CustomersOtherVO customers1;//其它客户1
     private CustomersOtherVO customers2;//其它客户2
@@ -38,4 +36,5 @@ public class LoanCaseVO implements Serializable {
     private String currentAddress;// 房产产证地址
     private Boolean isInvolvedInLitigation;//是否涉及诉讼
     private Boolean IsDelete;
+    private String createTime;
 }

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

@@ -0,0 +1,27 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RepaymentDetailVO implements Serializable {
+    private CustomerVO customer;
+    private LoanCaseSimpleVO loanCase;
+    //回款启动
+    private List<RepaymentRecordVO> repaymentRecords;//回款记录+审批
+    private Double totalAmount;//业务回款总额
+    private Double currentAmount;//目前回款总额
+
+    //财务核算
+    private Double interests;//利息
+    //费息回款
+    private String way;//打包还是正常
+
+}

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

@@ -0,0 +1,32 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.BaseEntity;
+import com.loan.system.domain.entity.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.validation.constraints.Size;
+import java.io.Serializable;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RepaymentRecordVO implements Serializable {
+    private Long id;
+    private Long repaymentId;
+    private Double amount;
+    private String createTime;
+    private String repayBank;
+    private String repayLocation;
+    private String repayAccount;
+    private String approvalComment;
+    private String approvalDecision;
+    private User approvalUser;
+    private Boolean isInterest;//是否为费息
+
+}

+ 30 - 0
src/main/java/com/loan/system/domain/vo/SysMessageVO.java

@@ -0,0 +1,30 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import java.io.Serializable;
+import java.time.Instant;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SysMessageVO implements Serializable {
+    private Long id;
+    private String  mobile;
+    private String userRole;
+    private String messageTitle;
+    private String messageContent;
+    private String stepName;
+    private Boolean readStatus;
+    private Long relatedId;
+    private String relatedType;
+    private String createTime;
+
+}

+ 24 - 0
src/main/java/com/loan/system/domain/vo/UserVO.java

@@ -0,0 +1,24 @@
+package com.loan.system.domain.vo;
+
+import com.loan.system.domain.entity.BaseEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserVO implements Serializable {
+    private Long id;
+    private String openid;
+    private String username;
+    private String password;
+    private String realName;
+    private String sex;
+    private String mobile;
+    private String role;
+
+}

+ 123 - 0
src/main/java/com/loan/system/interceptor/JwtTokenAdminInterceptor.java

@@ -0,0 +1,123 @@
+package com.loan.system.interceptor;
+
+import com.loan.system.constant.JwtClaimsConstant;
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.entity.User;
+import com.loan.system.properties.JwtProperties;
+import com.loan.system.service.UserService;
+import com.loan.system.utils.JwtUtil;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * jwt令牌校验的拦截器
+ */
+@Component
+@Slf4j
+public class JwtTokenAdminInterceptor implements HandlerInterceptor {
+
+    @Autowired
+    private JwtProperties jwtProperties;
+    @Autowired
+    private UserService userService;
+
+    /**
+     * 在拦截的请求前校验jwt
+     */
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        //判断当前拦截到的是Controller的方法还是其他资源
+        if (!(handler instanceof HandlerMethod)) {
+            //当前拦截到的不是动态方法,直接放行
+            return true;
+        }
+
+        //1、从请求头中获取令牌
+        String token = request.getHeader(jwtProperties.getAdminTokenName());
+
+        //2、校验令牌
+        try {
+            log.info("jwt校验:{}", token);
+            Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
+            Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
+            BaseContext.setCurrentId(userId);
+            setSpringSecurityAuthentication(userId);
+            //3、通过,放行
+            return true;
+        } catch (Exception ex) {
+            //4、不通过,响应401状态码
+            response.setStatus(401);
+            return false;
+        }
+    }
+
+    /**
+     * 设置Spring Security认证信息
+     */
+    private void setSpringSecurityAuthentication(Long userId) {
+        try {
+            // 查询用户信息和权限
+            User user = userService.findByIdAndIsDelete(userId);
+            if (user == null) {
+                log.info("用户不存在: {}", userId);
+                return;
+            }else{
+                log.info("用户信息: {}", user.getId());
+            }
+
+            // 获取用户角色并转换为Spring Security权限
+            List<GrantedAuthority> authorities = getUserAuthorities(user);
+
+            // 创建认证信息
+            UsernamePasswordAuthenticationToken authentication =
+                    new UsernamePasswordAuthenticationToken(user, null, authorities);
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+
+            log.info("Spring Security认证设置完成 - 用户: {}, 角色: {}",
+                    user.getUsername(), authorities);
+        } catch (Exception e) {
+            log.info("设置Spring Security认证信息失败: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 根据用户信息获取权限列表
+     * role字段是逗号分隔的字符串,如 "ADMIN,USER,MANAGER"
+     */
+    private List<GrantedAuthority> getUserAuthorities(User user) {
+        List<GrantedAuthority> authorities = new ArrayList<>();
+        log.info("用户角色字符串: {}", user.getRole());
+        if (user.getRole() != null && !user.getRole().trim().isEmpty()) {
+            // 分割逗号分隔的角色字符串
+            String[] roleArray = user.getRole().split(",");
+            // 为每个角色添加ROLE_前缀并创建权限对象
+            for (String role : roleArray) {
+                log.info("角色: {}", role);
+                String trimmedRole = role.trim();
+                if (!trimmedRole.isEmpty()) {
+                    authorities.add(new SimpleGrantedAuthority(trimmedRole));
+                }
+            }
+        }
+        log.info("用户角色解析: {} -> {}", user.getRole(),
+                authorities.stream()
+                        .map(GrantedAuthority::getAuthority)
+                        .collect(Collectors.toList()));
+
+        return authorities;
+    }
+
+}

+ 2 - 1
src/main/java/com/loan/system/interceptor/JwtTokenUserInterceptor.java

@@ -54,11 +54,12 @@ public class JwtTokenUserInterceptor implements HandlerInterceptor {
             Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);
             Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());
             BaseContext.setCurrentId(userId);
+            setSpringSecurityAuthentication(userId);
             //3、通过,放行
             return true;
         } catch (Exception ex) {
             //4、不通过,响应401状态码
-            response.setStatus(401);
+            response.setStatus(404);
             return false;
         }
     }

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

@@ -1,6 +1,7 @@
 package com.loan.system.repository;
 
 import com.loan.system.domain.entity.Contract;
+import com.loan.system.domain.vo.ContractVO;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
@@ -61,4 +62,7 @@ public interface ContractRepository extends JpaRepository<Contract,Long> {
     @Modifying
     @Query("UPDATE Contract c SET c.contractNo = ?2 WHERE c.id = ?1")
     void updateContractNoById(Long id, String contractNo);
+
+    @Query("SELECT c FROM Contract c WHERE c.id = ?1")
+    Contract findContractById(Long contractId);
 }

+ 7 - 5
src/main/java/com/loan/system/repository/CustomerRepository.java

@@ -1,8 +1,8 @@
 package com.loan.system.repository;
 
 import com.loan.system.domain.entity.Customer;
-import com.loan.system.domain.entity.CustomersOther;
-import com.loan.system.domain.entity.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
@@ -21,12 +21,12 @@ public interface CustomerRepository extends JpaRepository<Customer,Long> {
     @Query("select c from Customer c where c.mobile = ?1 and c.isDelete = ?2")
     Customer findByMobile(String mobile,Boolean isDelete);
 
-    List<Customer> findByIsDelete(Boolean isDelete);
+    Page<Customer> findByIsDelete(Boolean isDelete, Pageable pageable);
 
     Customer findByIdAndIsDelete(Long id, Boolean isDelete);
     
-    @Query("select c from Customer c where (c.mobile = ?1 or c.name = ?1) and c.isDelete = ?2")
-    Customer findByKey(String key, boolean b);
+    @Query("select c from Customer c where (c.mobile like ?1 or c.name like ?1) and c.isDelete = ?2")
+    Page<Customer> findByKey(String key, boolean isDelete, Pageable pageable);
 
     @Transactional
     @Modifying
@@ -35,4 +35,6 @@ public interface CustomerRepository extends JpaRepository<Customer,Long> {
 
     @Query("select co from Customer co where co.id = ?1 and co.isDelete = ?2")
     Customer findByCustomerId(Long customerId , Boolean isDelete);
+
+    boolean existsByIdAndIsDelete(Long customerId, boolean isDelete);
 }

+ 20 - 0
src/main/java/com/loan/system/repository/DisbursementRecordRepository.java

@@ -0,0 +1,20 @@
+package com.loan.system.repository;
+
+import com.loan.system.domain.entity.ApprovalRecord;
+import com.loan.system.domain.entity.DisbursementRecord;
+import com.loan.system.domain.vo.DisbursementRecordVO;
+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;
+
+/**
+ * @author EdwinXu
+ * @date 2020/9/2 - 15:35
+ * @Description
+ */
+public interface DisbursementRecordRepository extends JpaRepository<DisbursementRecord,Long> {
+    List<DisbursementRecord> findByDisbursementIdAndIsDelete(Long id, boolean isDelete);
+}

+ 20 - 0
src/main/java/com/loan/system/repository/DisbursementRepository.java

@@ -3,7 +3,9 @@ package com.loan.system.repository;
 import com.loan.system.domain.entity.Collateral;
 import com.loan.system.domain.entity.Disbursement;
 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;
 
@@ -16,4 +18,22 @@ public interface DisbursementRepository extends JpaRepository<Disbursement,Long>
 
     @Query("select d from Disbursement d where d.caseId = ?1")
     Disbursement findDisbursementDetailsById(Long caseId);
+
+    @Query("select d from Disbursement d where d.caseId = ?1 and d.isDelete = ?2")
+    Disbursement getDisbursementByCaseIdAndIsDelete(Long caseId, boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query("update Disbursement d set d.payoutApproveUserId = ?1 where d.id = ?2")
+    void updateApprovalUserById(Long currentId, Long id);
+
+    @Transactional
+    @Modifying
+    @Query("update Disbursement d set d.payoutOperatorUserId = ?1 where d.id = ?2")
+    void updateOperationUserById(Long currentId, Long id);
+
+    @Transactional
+    @Modifying
+    @Query("update Disbursement d set d.comments = ?1 where d.id = ?2")
+    void updateCommentsById(String comments, Long id);
 }

+ 2 - 2
src/main/java/com/loan/system/repository/DocumentRepository.java

@@ -19,8 +19,8 @@ public interface DocumentRepository extends JpaRepository<Document,Long> {
 
     List<Document> findByCaseId(Long caseId);
 
-    @Query("select d from Document d where d.id = ?1")
-    Document findByDocumentId(Long signId);
+    @Query("select d from Document d where d.id = ?1 and d.isDelete =?2")
+    Document findByDocumentIdAndIsDelete(Long signId, Boolean isDelete);
 
     @Transactional
     @Modifying

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

@@ -2,6 +2,8 @@ package com.loan.system.repository;
 
 import com.loan.system.domain.entity.LoanCase;
 import com.loan.system.domain.entity.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
@@ -17,7 +19,7 @@ import java.util.List;
  */
 public interface LoanRepository extends JpaRepository<LoanCase,Long> {
 
-    List<LoanCase> findByIsCompleteAndIsDelete(Boolean isComplete, boolean isDelete);
+    Page<LoanCase> findByIsCompleteAndIsDelete(Boolean isComplete, boolean isDelete, Pageable pageable);
 
     @Transactional
     @Modifying
@@ -45,4 +47,6 @@ public interface LoanRepository extends JpaRepository<LoanCase,Long> {
     @Transactional
     @Query("UPDATE LoanCase SET updateTime = ?3, isDelete = ?2 WHERE id = ?1 AND isDelete = ?2")
     void logic_delete(Long id, boolean isDelete, String updateTime);
+
+    Boolean existsByIdAndIsDelete(Long caseId, boolean isDelete);
 }

+ 19 - 0
src/main/java/com/loan/system/repository/MessageRepository.java

@@ -0,0 +1,19 @@
+package com.loan.system.repository;
+
+import com.loan.system.domain.entity.Role;
+import com.loan.system.domain.entity.SysMessage;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author EdwinXu
+ * @date 2020/9/2 - 15:35
+ * @Description
+ */
+public interface MessageRepository extends JpaRepository<SysMessage,Long> {
+    List<SysMessage> findByMobileAndIsDelete(String mobile, boolean isDelete);
+
+    List<SysMessage> findByUserRoleAndIsDelete(String role, boolean isDelete);
+}

+ 24 - 0
src/main/java/com/loan/system/repository/RecommenderRepository.java

@@ -1,8 +1,12 @@
 package com.loan.system.repository;
 
+import com.loan.system.domain.dto.BizRecommenderDTO;
 import com.loan.system.domain.entity.BizRecommender;
 import com.loan.system.domain.entity.User;
 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;
 
@@ -13,4 +17,24 @@ import java.util.List;
  */
 public interface RecommenderRepository extends JpaRepository<BizRecommender,Long> {
     List<BizRecommender> findByIsDelete(Boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query(value = "UPDATE BizRecommender r SET " +
+            "r.recommenderCode = CASE WHEN :#{#dto.recommenderCode} IS NOT NULL THEN :#{#dto.recommenderCode} ELSE r.recommenderCode END, " +
+            "r.recommenderName = CASE WHEN :#{#dto.recommenderName} IS NOT NULL THEN :#{#dto.recommenderName} ELSE r.recommenderName END, " +
+            "r.mobile = CASE WHEN :#{#dto.mobile} IS NOT NULL THEN :#{#dto.mobile} ELSE r.mobile END, " +
+            "r.channelName = CASE WHEN :#{#dto.channelName} IS NOT NULL THEN :#{#dto.channelName} ELSE r.channelName END, " +
+            "r.group = CASE WHEN :#{#dto.group} IS NOT NULL THEN :#{#dto.group} ELSE r.group END, " +
+            "r.idCard = CASE WHEN :#{#dto.idCard} IS NOT NULL THEN :#{#dto.idCard} ELSE r.idCard END, " +
+            "r.bankAccount = CASE WHEN :#{#dto.bankAccount} IS NOT NULL THEN :#{#dto.bankAccount} ELSE r.bankAccount END, " +
+            "r.commissionRate = CASE WHEN :#{#dto.commissionRate} IS NOT NULL THEN :#{#dto.commissionRate} ELSE r.commissionRate END, " +
+            "r.company = CASE WHEN :#{#dto.company} IS NOT NULL THEN :#{#dto.company} ELSE r.company END, " +
+            "r.remark = CASE WHEN :#{#dto.remark} IS NOT NULL THEN :#{#dto.remark} ELSE r.remark END, " +
+            "r.isDelete = CASE WHEN :#{#dto.isDelete} IS NOT NULL THEN :#{#dto.isDelete} ELSE r.isDelete END " +
+            "WHERE r.id = :id")
+    void updateRecommenderById(BizRecommenderDTO dto, Long id);
+
+    @Query(value = "SELECT r FROM BizRecommender r WHERE r.id= :id and r.isDelete = :isDelete")
+    BizRecommender findByIdAndIsDelete(Long id,boolean isDelete);
 }

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

@@ -0,0 +1,34 @@
+package com.loan.system.repository;
+
+import com.loan.system.domain.dto.ApprovalRecordDTO;
+import com.loan.system.domain.entity.Repayment;
+import com.loan.system.domain.entity.RepaymentRecord;
+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;
+
+/**
+ * @author EdwinXu
+ * @date 2020/9/2 - 15:35
+ * @Description
+ */
+public interface RepaymentRecordRepository extends JpaRepository<RepaymentRecord,Long> {
+
+    List<RepaymentRecord> findByRepaymentIdAndIsDelete(Long repaymentId, boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query("update RepaymentRecord r set r.approvalComment = ?1," +
+            "r.approvalDecision=?2," +
+            "r.approvalUserId= ?3 where r.id = ?4")
+    void updateApprovalByRepaymentId(String comments, String decision, Long approvalId,Long id);
+
+    @Transactional
+    @Modifying
+    @Query("update RepaymentRecord r set r.amount = ?1," +
+            "r.repayBank = ?2, r.repayLocation = ?3 ,r.repayAccount = ?4 where  r.id = ?5")
+    void updateRepaymentRecordById(Double amount, String repayBank, String repayLocation, String repayAccount, Long recordId);
+}

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

@@ -0,0 +1,41 @@
+package com.loan.system.repository;
+
+import com.loan.system.domain.entity.Collateral;
+import com.loan.system.domain.entity.Repayment;
+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;
+
+/**
+ * @author EdwinXu
+ * @date 2020/9/2 - 15:35
+ * @Description
+ */
+public interface RepaymentRepository extends JpaRepository<Repayment,Long> {
+
+    @Query("select r from Repayment r where r.caseId = ?1 and r.isDelete = ?2")
+    Repayment findByCaseIdAndIsDelete(Long caseId, boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query("update Repayment r set r.approvalUserId = ?1 where r.caseId = ?2")
+    void updateApprovalUserByCaseId(Long currentId, Long caseId);
+
+    @Transactional
+    @Modifying
+    @Query("update Repayment r set r.isCleared = ?1 where r.caseId = ?2")
+    void updateIsClearedByCaseId(boolean isClear, Long caseId);
+
+    @Transactional
+    @Modifying
+    @Query("update Repayment r set r.interest = ?1 , r.confirmedId = ?2 , r.confirmedAt = ?3 where  r.caseId = ?4")
+    void updateIntersetsByCaseId(Double interest, Long conformId, String conformTime,Long caseId);
+
+    @Transactional
+    @Modifying
+    @Query("update Repayment r set r.repayWay = ?1 where r.caseId = ?2")
+    void updateRepayWayByCaseId(String repayWay, Long caseId);
+}

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

@@ -1,11 +1,13 @@
 package com.loan.system.repository;
 
 import com.loan.system.domain.entity.User;
+import com.loan.system.domain.vo.UserVO;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 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;
 import java.util.Set;
@@ -18,7 +20,7 @@ import java.util.Set;
 public interface UserRepository extends JpaRepository<User,Long> {
     User findByMobile(String mobile);
 
-    List<User> findByIsDelete(Boolean isDelete);
+    Page<User> findByIsDelete(Boolean isDelete, Pageable pageable);
 
     @Query("select u from User u where u.id in ?1 and u.isDelete = ?2")
     User findByUserIdAndIsDelete(Long userId, Boolean isDelete);
@@ -28,4 +30,20 @@ public interface UserRepository extends JpaRepository<User,Long> {
     User findByMobileAndIsDelete(String phoneNumber,Boolean isDelete);
 
     User findByIdAndIsDelete(Long mobile, Boolean isDelete);
+
+    @Query("select u from User u where u.isDelete = ?1 and( u.role like '%LEAD_SALES%' or u.role like '%ASSIST_SALES%')")
+    List<User> findAllSalesByIsDelete(boolean b);
+
+    @Query("select u from User u where u.role like ?1 and u.isDelete = ?2")
+    List<User> getUsersByRoleAndIsDelete(String role, boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query("update User u set u.isDelete = ?2 where u.id = ?1")
+    void updateIsDeleteById(Long id, boolean isDelete);
+
+    @Transactional
+    @Modifying
+    @Query("update User u set u.role = ?1 where u.id = ?2")
+    void updateRoleById(String role,Long id);
 }

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

@@ -18,4 +18,5 @@ public interface ApprovalService {
     void updateDecisionByCaseIdAndStepNameAndIsDelete(String decision, Long caseId, String stepName,String  comments,Long approverId);
 
     ApprovalRecordVO findByCaseIdAndIsDeleteAndStepName(Long caseId, String stepName, Long approverId);
+
 }

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

@@ -5,7 +5,7 @@ import com.loan.system.domain.entity.ContractAndCollateral;
 import java.util.List;
 
 public interface ContractAndCollateralService {
-    void addContractAndCollateral(Long contractId, Long collateralId);
+    void addContractAndCollateral(Long contractId, Long collateralId,Long caseId);
 
     void deleteAllByCaseId(Long caseId);
 

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

@@ -24,4 +24,6 @@ public interface ContractService {
     void deleteAllByCaseId(Long caseId);
 
     void updateContractNoById(Long id, String contractNo);
+
+    Contract findContractById(Long contractId);
 }

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

@@ -17,13 +17,16 @@ public interface CustomerService {
 
     CustomerVO findByCustomerIdAndIsDelete(Long customerId,Boolean isDelete);
 
-    List<CustomerVO> getAllCustomers(boolean b);
+    List<CustomerVO> getAllCustomers(Integer pageNum, Integer pageSize,boolean isDelete);
 
-    CustomerVO getCustomerByKey(String key, boolean b);
+    List<CustomerVO> getCustomerByKey(String key, boolean isDelete,Integer pageNum, Integer pageSize);
 
     CustomerVO getCustomerByMobile(String tel);
 
     Customer findBymobileAndIsDelete(String phoneNumber);
     boolean existsBymobileAndIsDelete(String phoneNumber);
+
     Customer findByIdAndIsDelete(Long id);
+
+    boolean existsByIdAndIsDelete(Long customerId);
 }

+ 12 - 0
src/main/java/com/loan/system/service/DisbursementRecordService.java

@@ -0,0 +1,12 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.dto.DisbursementRecordDTO;
+import com.loan.system.domain.vo.DisbursementRecordVO;
+
+import java.util.List;
+
+public interface DisbursementRecordService {
+    void addDisbursementRecord(DisbursementRecordDTO disbursementRecordDTO);
+
+    List<DisbursementRecordVO> findRecordById(Long id);
+}

+ 11 - 0
src/main/java/com/loan/system/service/DisbursementService.java

@@ -2,10 +2,21 @@ package com.loan.system.service;
 
 import com.loan.system.domain.dto.DisbursementDTO;
 import com.loan.system.domain.entity.Disbursement;
+import com.loan.system.domain.vo.DisbursementDetailVO;
 import com.loan.system.domain.vo.DisbursementVO;
 
 public interface DisbursementService {
     DisbursementVO addDisbursement(DisbursementDTO disbursementDTO);
 
     DisbursementVO findDisbursementDetailsById(Long caseId);
+
+    DisbursementDetailVO getLoanCaseAndCustomerByCaseId(Long caseId);
+
+    Disbursement getDisbursementByCaseId(Long caseId);
+
+    void updateApprovalUserById(Long currentId, Long id);
+
+    void updateOperationUserById(Long currentId, Long id);
+
+    void updateCommentsById(String comments, Long id);
 }

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

@@ -16,4 +16,6 @@ public interface DocumentService {
     void updateDocumentByCaseIdAndDicType(Long caseId, String dictType, DocumentDTO documentDTO);
 
     void deleteFileByCaseIdAndDictType(Long caseId, String fileType);
+
+    void deleteFileById(Long id);
 }

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

@@ -36,7 +36,7 @@ public class ApprovalServiceImpl implements ApprovalService {
     public void addPreApprovalRecord(String label, Long currentId, Long caseId) {
         ApprovalRecord approvalRecord = new ApprovalRecord();
         approvalRecord.setCaseId(caseId);
-        approvalRecord.setStepName(StepPropertyEnum.PRE_TRIAL.getLabel());
+        approvalRecord.setStepName(label);
         approvalRecord.setApproverId(currentId);
         approvalRecord.setDecision("通过");
         approvalRecord.setComments("跳过审批环节");

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

@@ -17,10 +17,11 @@ public class ContractAndCollateralServiceImpl implements ContractAndCollateralSe
         this.contractAndCollateralRepository = contractAndCollateralRepository;
     }
     @Override
-    public void addContractAndCollateral(Long contractId, Long collateralId) {
+    public void addContractAndCollateral(Long contractId, Long collateralId, Long caseId) {
         ContractAndCollateral contractAndCollateral = new ContractAndCollateral();
         contractAndCollateral.setContractId(contractId);
         contractAndCollateral.setCollateralId(collateralId);
+        contractAndCollateral.setCaseId(caseId);
         contractAndCollateral.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
         contractAndCollateral.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
         contractAndCollateral.setIsDelete(false);

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

@@ -13,6 +13,7 @@ import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.List;
+import java.util.UUID;
 
 @Service
 public class ContractServiceImpl implements ContractService {
@@ -25,13 +26,16 @@ public class ContractServiceImpl implements ContractService {
     @Override
     public Contract saveContract(ContractDTO contractDTO) {
         Contract contract = BeanUtil.copyProperties(contractDTO, Contract.class);
-        contract.setIsDelete( false);
+        String name=contract.getBusinessAttr().equals("房产抵押")?"抵押合同":"质押合同";
+        contract.setContractName("浙江宝路同典当"+name);
+        contract.setIsDelete(false);
         contract.setSignedByCustomer(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" ) ) );
-        return contractRepository.save( contract );
+        
+        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")));
+        return contractRepository.save(contract);
     }
 
     @Override
@@ -84,4 +88,9 @@ public class ContractServiceImpl implements ContractService {
         contractRepository.updateContractNoById(id,contractNo);
     }
 
+    @Override
+    public Contract findContractById(Long contractId) {
+        return contractRepository.findContractById(contractId);
+    }
+
 }

+ 18 - 4
src/main/java/com/loan/system/service/Impl/CustomerServiceImpl.java

@@ -6,6 +6,9 @@ import com.loan.system.domain.vo.CustomerVO;
 import com.loan.system.repository.CustomerRepository;
 import com.loan.system.service.CustomerService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
@@ -34,13 +37,19 @@ public class CustomerServiceImpl implements CustomerService {
     }
 
     @Override
-    public List<CustomerVO> getAllCustomers(boolean b) {
-        return BeanUtil.copyToList(customerRepository.findByIsDelete(b),CustomerVO.class);
+    public List<CustomerVO> getAllCustomers(Integer pageNum,Integer pageSize,boolean isDelete) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        Page<Customer> customerPage = customerRepository.findByIsDelete(isDelete,pageable);
+        List<Customer> customerList = customerPage.getContent();
+        return BeanUtil.copyToList(customerList,CustomerVO.class);
     }
 
     @Override
-    public CustomerVO getCustomerByKey(String key, boolean b) {
-        return BeanUtil.copyProperties(customerRepository.findByKey(key,b),CustomerVO.class);
+    public List<CustomerVO> getCustomerByKey(String key, boolean isDelete,Integer pageNum, Integer pageSize) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        key ="%"+key+"%";
+        Page<Customer> customerPage=customerRepository.findByKey(key,isDelete,pageable);
+        return BeanUtil.copyToList(customerPage.getContent(),CustomerVO.class);
     }
 
     @Override
@@ -60,4 +69,9 @@ public class CustomerServiceImpl implements CustomerService {
     public Customer findByIdAndIsDelete(Long id){
         return customerRepository.findByIdAndIsDelete(id,false);
     }
+
+    @Override
+    public boolean existsByIdAndIsDelete(Long customerId) {
+        return customerRepository.existsByIdAndIsDelete(customerId,false);
+    }
 }

+ 40 - 0
src/main/java/com/loan/system/service/Impl/DisbursementRecordServiceImpl.java

@@ -0,0 +1,40 @@
+package com.loan.system.service.Impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.dto.DisbursementRecordDTO;
+import com.loan.system.domain.entity.DisbursementRecord;
+import com.loan.system.domain.vo.DisbursementRecordVO;
+import com.loan.system.repository.DisbursementRecordRepository;
+import com.loan.system.service.DisbursementRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Base64;
+import java.util.List;
+
+@Service
+public class DisbursementRecordServiceImpl implements DisbursementRecordService {
+    private final DisbursementRecordRepository  disbursementRecordRepository;
+
+    @Autowired
+    public DisbursementRecordServiceImpl(DisbursementRecordRepository disbursementRecordRepository) {
+        this.disbursementRecordRepository = disbursementRecordRepository;
+    }
+    @Override
+    public void addDisbursementRecord(DisbursementRecordDTO disbursementRecordDTO) {
+        DisbursementRecord disbursementRecord = BeanUtil.copyProperties(disbursementRecordDTO, DisbursementRecord.class);
+        disbursementRecord.setFinanceId(BaseContext.getCurrentId());
+        disbursementRecord.setIsDelete(false);
+        disbursementRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+
+        disbursementRecordRepository.save(disbursementRecord);
+    }
+
+    @Override
+    public List<DisbursementRecordVO> findRecordById(Long id) {
+        return BeanUtil.copyToList(disbursementRecordRepository.findByDisbursementIdAndIsDelete(id,false), DisbursementRecordVO.class);
+    }
+}

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

@@ -1,11 +1,14 @@
 package com.loan.system.service.Impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.context.BaseContext;
 import com.loan.system.domain.dto.DisbursementDTO;
 import com.loan.system.domain.entity.Disbursement;
-import com.loan.system.domain.vo.DisbursementVO;
+import com.loan.system.domain.vo.*;
 import com.loan.system.repository.DisbursementRepository;
+import com.loan.system.service.CustomerService;
 import com.loan.system.service.DisbursementService;
+import com.loan.system.service.LoanService;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -16,14 +19,19 @@ import java.time.format.DateTimeFormatter;
 @Service
 public class DisbursementServiceImpl implements DisbursementService {
     private final DisbursementRepository disbursementRepository;
+    private final CustomerService customerSrevice;
+    private final LoanService loanService;
 
     @Autowired
-    public DisbursementServiceImpl(DisbursementRepository disbursementRepository) {
+    public DisbursementServiceImpl(DisbursementRepository disbursementRepository, CustomerService customerSrevice, LoanService loanService) {
         this.disbursementRepository = disbursementRepository;
+        this.customerSrevice = customerSrevice;
+        this.loanService = loanService;
     }
     @Override
     public DisbursementVO addDisbursement(DisbursementDTO disbursementDTO) {
         Disbursement disbursement = BeanUtil.copyProperties(disbursementDTO, Disbursement.class);
+        disbursement.setApplyBy(BaseContext.getCurrentId());
         disbursement.setApplyAt(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
         disbursement.setCreateTime(LocalDateTime.now()
                 .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
@@ -38,4 +46,35 @@ public class DisbursementServiceImpl implements DisbursementService {
     public DisbursementVO findDisbursementDetailsById(Long caseId) {
         return BeanUtil.copyProperties(disbursementRepository.findDisbursementDetailsById(caseId), DisbursementVO.class);
     }
+
+    @Override
+    public DisbursementDetailVO getLoanCaseAndCustomerByCaseId(Long caseId) {
+        LoanCaseSimpleVO loanCaseSimpleVO = loanService.findLoanCaseSimpleByIdAndIsDelete(caseId, false);
+        CustomerVO customerVO = customerSrevice.findByCustomerIdAndIsDelete(loanCaseSimpleVO.getCustomerId(), false);
+
+        DisbursementDetailVO disbursementDetailVO =new DisbursementDetailVO();
+        disbursementDetailVO.setCustomer(customerVO);
+        disbursementDetailVO.setLoanCase(loanCaseSimpleVO);
+        return disbursementDetailVO;
+    }
+
+    @Override
+    public Disbursement getDisbursementByCaseId(Long caseId) {
+        return disbursementRepository.getDisbursementByCaseIdAndIsDelete(caseId, false);
+    }
+
+    @Override
+    public void updateApprovalUserById(Long currentId,Long id) {
+        disbursementRepository.updateApprovalUserById(currentId,id);
+    }
+
+    @Override
+    public void updateOperationUserById(Long currentId, Long id) {
+        disbursementRepository.updateOperationUserById(currentId,id);
+    }
+
+    @Override
+    public void updateCommentsById(String comments, Long id) {
+        disbursementRepository.updateCommentsById(comments,id);
+    }
 }

+ 6 - 1
src/main/java/com/loan/system/service/Impl/DocumentServiceImpl.java

@@ -33,7 +33,7 @@ public class DocumentServiceImpl implements DocumentService {
 
     @Override
     public Document findById(Long signId) {
-        return documentRepository.findByDocumentId(signId);
+        return documentRepository.findByDocumentIdAndIsDelete(signId, false);
     }
 
     @Override
@@ -47,4 +47,9 @@ public class DocumentServiceImpl implements DocumentService {
     public void deleteFileByCaseIdAndDictType(Long caseId, String fileType) {
         documentRepository.deleteFileByCaseIdAndDictType(caseId, fileType);
     }
+
+    @Override
+    public void deleteFileById(Long id) {
+        documentRepository.deleteById(id);
+    }
 }

+ 42 - 8
src/main/java/com/loan/system/service/Impl/LoanServiceImpl.java

@@ -10,6 +10,9 @@ import com.loan.system.repository.CustomerRepository;
 import com.loan.system.repository.LoanRepository;
 import com.loan.system.service.*;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
 
@@ -31,11 +34,12 @@ public class LoanServiceImpl implements LoanService {
     private final ContractService contractService;
     private final StepService stepService;
     private final ContractAndCollateralService contractAndCollateralService;
+    private final RecommenderService recommender;
 
     @Autowired
     public LoanServiceImpl(LoanRepository loanRepository, CustomerOtherService customerOtherService,CustomerService customerRepository ,
                            DocumentService documentService, CollateralService collateralService, ContractService contractService,
-                           StepService stepService, ContractAndCollateralService contractAndCollateralService) {
+                           StepService stepService, ContractAndCollateralService contractAndCollateralService, RecommenderService recommender) {
         this.loanRepository = loanRepository;
         this.customerOtherService = customerOtherService;
         this.customerService = customerRepository;
@@ -44,11 +48,22 @@ public class LoanServiceImpl implements LoanService {
         this.contractService = contractService;
         this.stepService = stepService;
         this.contractAndCollateralService = contractAndCollateralService;
+        this.recommender = recommender;
     }
 
     @Override
-    public List<LoanCaseVO> findLoanCaseByIsComplete(Boolean isComplete, boolean isDelete) {
-        return BeanUtil.copyToList(loanRepository.findByIsCompleteAndIsDelete(isComplete,isDelete), LoanCaseVO.class);
+    public List<LoanCaseVO> findLoanCaseByIsComplete(Integer pageNum,Integer pageSize,Boolean isComplete, boolean isDelete) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        Page<LoanCase> loanCases = loanRepository.findByIsCompleteAndIsDelete(isComplete, isDelete,pageable);
+        List<LoanCaseVO> loanCaseVO = new ArrayList<>();
+        for (LoanCase loanCase1 : loanCases.getContent()) {
+            Long customerId = loanCase1.getCustomerId();
+            CustomerVO customer = customerService.findByCustomerIdAndIsDelete(customerId,false);
+            LoanCaseVO loanCaseVO1 = BeanUtil.copyProperties(loanCase1, LoanCaseVO.class);
+            loanCaseVO1.setCustomer(customer);
+            loanCaseVO.add(loanCaseVO1);
+        }
+        return loanCaseVO;
     }
 
     @Override
@@ -95,19 +110,26 @@ public class LoanServiceImpl implements LoanService {
 
         Map<Long,List<Long>> relation = new java.util.HashMap<>();
         List<Long> collateralIds = new ArrayList<>();
-        for(int i=0 ,j=0; i < contractAndCollaterals.size() && j < contracts.size(); i++) {
+        int j=0;
+        for(int i=0; i < contractAndCollaterals.size() && j < contracts.size(); i++) {
             if (contractAndCollaterals.get(i).getContractId().equals(contracts.get(j).getId())) {
                 collateralIds.add(contractAndCollaterals.get(i).getCollateralId());
-            }else{
+            }else {
                 relation.put(contracts.get(j).getId(),collateralIds);
                 relations.add(relation);
                 j++;
                 relation = new java.util.HashMap<>();
                 collateralIds = new ArrayList<>();
                 i--;
+                loanCaseVO.setCollateralAndContract(relations);
             }
         }
-        loanCaseVO.setCollateralAndContract(relations);
+        if(j < contracts.size()){
+            relation.put(contracts.get(j).getId(),collateralIds);
+            relations.add(relation);
+            loanCaseVO.setCollateralAndContract(relations);
+        }
+
 
         //5.获取其它客户信息
         List<CustomersOtherVO> customersOtherVOS = customerOtherService.findByCaseId(caseId);
@@ -121,13 +143,15 @@ public class LoanServiceImpl implements LoanService {
         loanCaseVO.setDocuments(BeanUtil.copyToList(documentService.findByCaseId(caseId), DocumentVO.class));
 //        //7.获取步骤信息
 //        loanCaseVO.setSteps(stepService.getStepByCaseId(caseId));
+        //7.获取推荐人
+        loanCaseVO.setRecommender(BeanUtil.copyProperties(recommender.getRecommenderById(loanCase.getRecommenderId()), BizRecommenderVO.class));
 
         return loanCaseVO;
     }
 
     @Override
-    public LoanCaseVO findLoanCaseByIdAndIsDelete(Long caseId, boolean isDelete) {
-        return BeanUtil.copyProperties(loanRepository.findLoanCaseById(caseId, isDelete), LoanCaseVO.class);
+    public LoanCase findLoanCaseByIdAndIsDelete(Long caseId, boolean isDelete) {
+        return loanRepository.findLoanCaseById(caseId, isDelete);
     }
 
     @Override
@@ -138,4 +162,14 @@ public class LoanServiceImpl implements LoanService {
     public void logic_delete(Long id){
         loanRepository.logic_delete(id, true, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
     }
+
+    @Override
+    public LoanCaseSimpleVO findLoanCaseSimpleByIdAndIsDelete(Long caseId, boolean isDelete) {
+        return BeanUtil.copyProperties(loanRepository.findLoanCaseById(caseId, isDelete),LoanCaseSimpleVO.class);
+    }
+
+    @Override
+    public Boolean existsByIdAndIsDelete(Long caseId) {
+        return loanRepository.existsByIdAndIsDelete(caseId, false);
+    }
 }

+ 41 - 0
src/main/java/com/loan/system/service/Impl/MessageServiceImpl.java

@@ -0,0 +1,41 @@
+package com.loan.system.service.Impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.domain.entity.SysMessage;
+import com.loan.system.domain.vo.SysMessageVO;
+import com.loan.system.repository.MessageRepository;
+import com.loan.system.service.MessageService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Service
+public class MessageServiceImpl implements MessageService {
+    private final MessageRepository messageRepository;
+
+    @Autowired
+    public MessageServiceImpl(MessageRepository messageRepository) {
+        this.messageRepository = messageRepository;
+    }
+    @Override
+    public List<SysMessageVO> getMessageByMobile(String mobile) {
+        return BeanUtil.copyToList(messageRepository.findByMobileAndIsDelete(mobile,false), SysMessageVO.class);
+    }
+
+    @Override
+    public List<SysMessageVO> getMessageByRole(String role) {
+        return BeanUtil.copyToList(messageRepository.findByUserRoleAndIsDelete(role,false), SysMessageVO.class);
+    }
+
+    @Override
+    public void addMessage(SysMessage message) {
+        message.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        message.setReadStatus(false);
+        message.setIsDelete(false);
+        messageRepository.save(message);
+    }
+}

+ 56 - 0
src/main/java/com/loan/system/service/Impl/RecommenderServiceImpl.java

@@ -0,0 +1,56 @@
+package com.loan.system.service.Impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.domain.dto.BizRecommenderDTO;
+import com.loan.system.domain.entity.BizRecommender;
+import com.loan.system.repository.RecommenderRepository;
+import com.loan.system.service.RecommenderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Service
+public class RecommenderServiceImpl implements RecommenderService {
+    private final RecommenderRepository recommenderRepository;
+
+    @Autowired
+    public RecommenderServiceImpl(RecommenderRepository recommenderRepository) {
+        this.recommenderRepository = recommenderRepository;
+    }
+
+    @Override
+    public void addRecommender(BizRecommenderDTO bizRecommenderDTO) {
+        BizRecommender bizRecommender = BeanUtil.copyProperties(bizRecommenderDTO, BizRecommender.class);
+        bizRecommender.setIsDelete(false);
+        bizRecommender.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        bizRecommender.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+
+        recommenderRepository.save(bizRecommender);
+    }
+
+    @Override
+    public List<BizRecommender> getRecommenders(Integer pageNum, Integer pageSize) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        Page<BizRecommender> page = recommenderRepository.findAll(pageable);
+
+        return page.getContent();
+    }
+
+    @Override
+    public void updateRecommenderById(BizRecommenderDTO bizRecommenderDTO,Long  id) {
+        recommenderRepository.updateRecommenderById(bizRecommenderDTO,id);
+    }
+
+    @Override
+    public BizRecommender getRecommenderById(Long recommenderId) {
+        return recommenderRepository.findByIdAndIsDelete( recommenderId,false);
+    }
+
+
+}

+ 55 - 0
src/main/java/com/loan/system/service/Impl/RepaymentRecordServiceImpl.java

@@ -0,0 +1,55 @@
+package com.loan.system.service.Impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.dto.ApprovalDTO;
+import com.loan.system.domain.dto.ApprovalRecordDTO;
+import com.loan.system.domain.dto.RepaymentRecordDTO;
+import com.loan.system.domain.entity.Repayment;
+import com.loan.system.domain.entity.RepaymentRecord;
+import com.loan.system.domain.vo.RepaymentRecordVO;
+import com.loan.system.repository.RepaymentRecordRepository;
+import com.loan.system.repository.RepaymentRepository;
+import com.loan.system.service.RepaymentRecordService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+@Service
+public class RepaymentRecordServiceImpl implements RepaymentRecordService {
+    private final RepaymentRecordRepository repaymentRecordRepository;
+
+    @Autowired
+    public RepaymentRecordServiceImpl(RepaymentRecordRepository repaymentRepository) {
+        this.repaymentRecordRepository = repaymentRepository;
+    }
+    @Override
+    public void addRepaymentRecord(RepaymentRecordDTO repaymentRecordDTO, Long id) {
+        RepaymentRecord repaymentRecord = BeanUtil.copyProperties(repaymentRecordDTO, RepaymentRecord.class);
+        repaymentRecord.setRepaymentId(id);
+        repaymentRecord.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        repaymentRecord.setIsDelete( false);
+
+        repaymentRecordRepository.save(repaymentRecord);
+    }
+
+    @Override
+    public List<RepaymentRecordVO> findByRepaymentIdAndIsDelete(Long repaymentId, boolean b) {
+        return BeanUtil.copyToList(repaymentRecordRepository.findByRepaymentIdAndIsDelete(repaymentId, b), RepaymentRecordVO.class);
+    }
+
+    @Override
+    public void updateApprovalById(String comments, String decision, Long id) {
+        repaymentRecordRepository.updateApprovalByRepaymentId(comments, decision, BaseContext.getCurrentId(),id);
+    }
+
+    @Override
+    public void updateRepaymentRecordById(RepaymentRecordDTO repaymentRecordDTO, Long recordId) {
+        repaymentRecordRepository.updateRepaymentRecordById(repaymentRecordDTO.getAmount(), repaymentRecordDTO.getRepayBank(), repaymentRecordDTO.getRepayLocation(), repaymentRecordDTO.getRepayAccount(), recordId);
+    }
+
+}

+ 57 - 0
src/main/java/com/loan/system/service/Impl/RepaymentServiceImpl.java

@@ -0,0 +1,57 @@
+package com.loan.system.service.Impl;
+
+import com.loan.system.context.BaseContext;
+import com.loan.system.domain.entity.Repayment;
+import com.loan.system.repository.RepaymentRepository;
+import com.loan.system.service.RepaymentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.naming.Context;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Service
+public class RepaymentServiceImpl implements RepaymentService {
+    private final RepaymentRepository repaymentRepository;
+
+    @Autowired
+    public RepaymentServiceImpl(RepaymentRepository repaymentRepository) {
+        this.repaymentRepository = repaymentRepository;
+    }
+    @Override
+    public void addRepayment(Repayment repayment) {
+        repayment.setIsCleared( false);
+        repayment.setIsDelete(false);
+        repayment.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        repayment.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+
+        repaymentRepository.save(repayment);
+    }
+
+    @Override
+    public Repayment findByCaseIdAndIsDelete(Long caseId, boolean isDelete) {
+        return repaymentRepository.findByCaseIdAndIsDelete(caseId,isDelete);
+    }
+
+    @Override
+    public void updateApprovalUserByCaseId(Long currentId, Long caseId) {
+        repaymentRepository.updateApprovalUserByCaseId(currentId,caseId);
+    }
+
+    @Override
+    public void updateIsClearedByCaseId(boolean isClear, Long caseId) {
+        repaymentRepository.updateIsClearedByCaseId(isClear,caseId);
+    }
+
+    @Override
+    public void updateIntersetsByCaseId(Double interest , Long caseId) {
+        repaymentRepository.updateIntersetsByCaseId(interest, BaseContext.getCurrentId(),
+                LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),caseId);
+    }
+
+    @Override
+    public void updateRepayWayByCaseId(String repayWay, Long caseId) {
+        repaymentRepository.updateRepayWayByCaseId(repayWay,caseId);
+    }
+}

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

@@ -1,13 +1,16 @@
 package com.loan.system.service.Impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.alibaba.fastjson.JSON;
 import com.loan.system.constant.MessageConstant;
+import com.loan.system.domain.dto.UserDTO;
 import com.loan.system.domain.dto.UserLoginDTO;
 import com.loan.system.domain.entity.BizRecommender;
 import com.loan.system.domain.entity.Customer;
 import com.loan.system.domain.entity.User;
 import com.loan.system.domain.enums.ExceptionEnum;
 import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.UserVO;
 import com.loan.system.exception.DescribeException;
 import com.loan.system.properties.WeChatProperties;
 import com.loan.system.repository.CustomerRepository;
@@ -20,6 +23,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import okhttp3.OkHttpClient;
@@ -27,6 +33,7 @@ import okhttp3.Request;
 import okhttp3.Response;
 
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -61,13 +68,18 @@ public class UserServiceImpl implements UserService {
 
 
     @Override
-    public List<Customer> getAllCustomers(Boolean isDelete) {
-        return customerRepository.findByIsDelete(isDelete);
+    public List<Customer> getAllCustomers(Integer pageNum,Integer pageSize,Boolean isDelete) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        Page<Customer> customerPage = customerRepository.findByIsDelete(isDelete,pageable);
+        return customerPage.getContent();
     }
 
     @Override
-    public List<User> getAllUsers(Boolean isDelete) {
-        return userRepository.findByIsDelete(isDelete);
+    public List<User> getAllUsers( Integer pageNum,Integer pageSize,Boolean isDelete) {
+        Pageable pageable = PageRequest.of(pageNum, pageSize);
+        Page<User> userPage = userRepository.findByIsDelete(isDelete,pageable);
+
+        return userPage.getContent();
     }
 
     @Override
@@ -175,6 +187,38 @@ public class UserServiceImpl implements UserService {
     public boolean existsByMobileAndIsDelete(String phoneNumber){
         return userRepository.existsByMobileAndIsDelete(phoneNumber,false);
     }
+
+    @Override
+    public List<UserVO> getAllSalesByIsDelete(boolean b) {
+        return BeanUtil.copyToList(userRepository.findAllSalesByIsDelete(b), UserVO.class);
+    }
+
+    @Override
+    public List<UserVO> getUsersByRole(String role) {
+        String roleSql = "%" + role + "%";
+        return BeanUtil.copyToList(userRepository.getUsersByRoleAndIsDelete(roleSql,false), UserVO.class);
+    }
+
+    @Override
+    public void addUser(UserDTO user) {
+        User user1 = BeanUtil.copyProperties(user, User.class);
+        user1.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        user1.setUpdateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
+        user1.setIsDelete( false);
+
+        userRepository.save(user1);
+    }
+
+    @Override
+    public void deleteUserByLogic(Long id) {
+        userRepository.updateIsDeleteById(id,true);
+    }
+
+    @Override
+    public void updateUserRole(String role,Long id) {
+        userRepository.updateRoleById(role,id);
+    }
+
     @Override
     public User findByPhoneNumberAndIsDelete(String phoneNumber){
         return userRepository.findByMobileAndIsDelete(phoneNumber,false);

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

@@ -2,12 +2,13 @@ package com.loan.system.service;
 
 import com.loan.system.domain.dto.LoanCaseDTO;
 import com.loan.system.domain.entity.LoanCase;
+import com.loan.system.domain.vo.LoanCaseSimpleVO;
 import com.loan.system.domain.vo.LoanCaseVO;
 
 import java.util.List;
 
 public interface LoanService {
-    List<LoanCaseVO> findLoanCaseByIsComplete(Boolean isComplete, boolean isDelete) ;
+    List<LoanCaseVO> findLoanCaseByIsComplete(Integer pageNum, Integer pageSize,Boolean isComplete, boolean isDelete) ;
 
     LoanCaseVO addLoanCaseByCustomerId(Long customerId);
     
@@ -15,9 +16,13 @@ public interface LoanService {
 
     LoanCaseVO findLoanCaseDetailsById(Long caseId);
 
-    LoanCaseVO findLoanCaseByIdAndIsDelete(Long caseId, boolean isDelete);
+    LoanCase findLoanCaseByIdAndIsDelete(Long caseId, boolean isDelete);
 
     void updateUpdatetimeByIdAndIsDeleted(Long id,boolean isDelete);
 
     void logic_delete(Long id);
+
+    LoanCaseSimpleVO findLoanCaseSimpleByIdAndIsDelete(Long caseId, boolean isDelete);
+
+    Boolean existsByIdAndIsDelete(Long caseId);
 }

+ 15 - 0
src/main/java/com/loan/system/service/MessageService.java

@@ -0,0 +1,15 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.entity.SysMessage;
+import com.loan.system.domain.vo.SysMessageVO;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface MessageService {
+    List<SysMessageVO> getMessageByMobile(String mobile);
+
+    List<SysMessageVO> getMessageByRole(String role);
+
+    void addMessage(SysMessage message);
+}

+ 17 - 0
src/main/java/com/loan/system/service/RecommenderService.java

@@ -0,0 +1,17 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.dto.BizRecommenderDTO;
+import com.loan.system.domain.entity.BizRecommender;
+
+import java.util.List;
+
+public interface RecommenderService {
+    void addRecommender(BizRecommenderDTO bizRecommenderDTO);
+
+    List<BizRecommender> getRecommenders(Integer pageNum, Integer pageSize);
+
+
+    void updateRecommenderById(BizRecommenderDTO bizRecommenderDTO,Long  id);
+
+    BizRecommender getRecommenderById(Long recommenderId);
+}

+ 19 - 0
src/main/java/com/loan/system/service/RepaymentRecordService.java

@@ -0,0 +1,19 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.dto.ApprovalDTO;
+import com.loan.system.domain.dto.ApprovalRecordDTO;
+import com.loan.system.domain.dto.RepaymentRecordDTO;
+import com.loan.system.domain.entity.Repayment;
+import com.loan.system.domain.vo.RepaymentRecordVO;
+
+import java.util.List;
+
+public interface RepaymentRecordService {
+    void addRepaymentRecord(RepaymentRecordDTO repaymentRecordDTO, Long id);
+
+    List<RepaymentRecordVO> findByRepaymentIdAndIsDelete(Long repaymentId, boolean b);
+
+    void updateApprovalById(String comments, String decision, Long id);
+
+    void updateRepaymentRecordById(RepaymentRecordDTO repaymentRecordDTO, Long recordId);
+}

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

@@ -0,0 +1,17 @@
+package com.loan.system.service;
+
+import com.loan.system.domain.entity.Repayment;
+
+public interface RepaymentService {
+    void addRepayment(Repayment repayment);
+
+    Repayment findByCaseIdAndIsDelete(Long caseId, boolean isDelete);
+
+    void updateApprovalUserByCaseId(Long currentId, Long caseId);
+
+    void updateIsClearedByCaseId(boolean isClear, Long caseId);
+
+    void updateIntersetsByCaseId(Double interest,Long caseId);
+
+    void updateRepayWayByCaseId(String repayWay, Long caseId);
+}

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

@@ -1,10 +1,12 @@
 package com.loan.system.service;
 
+import com.loan.system.domain.dto.UserDTO;
 import com.loan.system.domain.dto.UserLoginDTO;
 import com.loan.system.domain.entity.BizRecommender;
 import com.loan.system.domain.entity.Customer;
 import com.loan.system.domain.entity.User;
 import com.loan.system.domain.pojo.Result;
+import com.loan.system.domain.vo.UserVO;
 
 import java.util.List;
 
@@ -12,9 +14,9 @@ public interface UserService {
     User getUserByMobile(String  mobile);
 
 
-    List<Customer> getAllCustomers(Boolean isDelete);
+    List<Customer> getAllCustomers(Integer pageNum,Integer pageSize,Boolean isDelete);
 
-    List<User> getAllUsers(Boolean isDelete);
+    List<User> getAllUsers(Integer pageNum,Integer pageSize,Boolean isDelete);
 
     List<BizRecommender> getAllRecommenders(Boolean isDelete);
 
@@ -26,4 +28,14 @@ public interface UserService {
     Result get_sessionId(String code);
     User findByPhoneNumberAndIsDelete(String phoneNumber);
     boolean existsByMobileAndIsDelete(String phoneNumber);
+
+    List<UserVO> getAllSalesByIsDelete(boolean b);
+
+    List<UserVO> getUsersByRole(String role);
+
+    void addUser(UserDTO user);
+
+    void deleteUserByLogic(Long id);
+
+    void updateUserRole(String role,Long id);
 }

+ 91 - 17
src/main/java/com/loan/system/utils/PoiWordUtil.java

@@ -1,15 +1,20 @@
 package com.loan.system.utils;
 
 import com.deepoove.poi.XWPFTemplate;
+import com.deepoove.poi.data.PictureRenderData;
 import com.deepoove.poi.util.PoitlIOUtils;
+import com.loan.system.config.FileUploadConfig;
 import com.loan.system.domain.entity.Contract;
 import com.loan.system.domain.pojo.ContractInformation;
+import org.apache.poi.util.Units;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFPictureData;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
+import java.io.*;
 import java.text.SimpleDateFormat;
 import java.util.HashMap;
 
@@ -18,24 +23,71 @@ import java.util.HashMap;
  * @date : Created in 2021/1/26 16:15
  */
 public class PoiWordUtil {
-    public static void writeApprove(HttpServletResponse response, String path, ContractInformation contract, String downloadName){
+    @Autowired
+    private FileUploadConfig config;
+    public  void writeApprove(HttpServletResponse response, String path, ContractInformation contract, String downloadName){
+       // final String cacheFilePath = config.getUploadDir() + "file_store"+File.separator + downloadName + ".docx";
+
         File file = new File(path);
+        System.out.println(file.getAbsolutePath());
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+
+        // 检查缓存文件若存在且仅查看
+//        if ( new File(cacheFilePath).exists() ) {
+//            try (FileInputStream fis = new FileInputStream(cacheFilePath);
+//                 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
+//                byte[] buffer = new byte[1024];
+//                int bytesRead;
+//                while ((bytesRead = fis.read(buffer)) != -1) {
+//                    bos.write(buffer, 0, bytesRead);
+//                }
+//                bos.flush();
+//                return; // 如果找到缓存文件则直接返回
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+
+        // 假设签名图片路径是 contract.getSignatureImagePath()
+        final String signaturePath = config.getUploadDir()+ "file_store"+File.separator +"sign.png";
+
+        // 构造图片数据(支持本地路径、URL、byte[])
+        final PictureRenderData signaturePicture;
+        if (signaturePath != null && !signaturePath.isEmpty()) {
+            signaturePicture = new PictureRenderData(100, 50, signaturePath); // 宽200,高100
+        }else
+            signaturePicture = null;
+
         XWPFTemplate template = XWPFTemplate.compile(file).render(
                 new HashMap<String, Object>(){{
-//                    put("projectName", approveById.getProjectName());
-//                    put("copies", approveById.getCopies());
-//                    put("submittingDepartment", approveById.getSubmittingDepartment());
-//                    put("submittingDate", format.format(approveById.getSubmittingDate()));
-//                    put("submitter", approveById.getSubmitter());
-//                    put("acceptDate", format.format(approveById.getAcceptDate()));
-//                    put("accepter", approveById.getAccepter());
-//                    put("logisticsServicesReviewComments", approveById.getLogisticsServicesReviewComments());
-//                    put("publicAffairsReviewComments", approveById.getPublicAffairsReviewComments());
-//                    put("leadersInChargeReviewComments", approveById.getLeadersInChargeReviewComments());
-//                    put("contractCommissionSignedOptions", approveById.getContractCommissionSignedOptions());
-//                    put("contractNumber", approveById.getContractNumber());
+                    put("contractNo",contract.getContractNo());
+                    put("customerName",contract.getName());
+                    put("customerIdNumber",contract.getIdNumber());
+                    put("contractType",contract.getContractType());
+                    put("contractUsage",contract.getContractUsage());
+                    put("contractAmount",contract.getContractAmount());
+                    put("contractPeriod",contract.getContractPeriod());
+
+                    put("leastDay",contract.getLeastDay());
+                    put("bankName",contract.getBankName());
+                    put("bankAccount",contract.getBankAccount());
+                    put("interestRate",contract.getInterestRate());
+                    put("serviceCost",contract.getServiceCost());
+                    put("collateralAddress",contract.getAddress());
+                    put("numberAndArea",contract.getCollateralNumber()+" "+contract.getCollateralArea());
+                    put("pages1",contract.getPages1());
+                    put("pages2",contract.getPages2());
+
+                    put("signature1",signaturePicture);
+                    put("signature2",signaturePicture);
+                    put("contactAddress1",contract.getContactAddress1());
+                    put("contactAddress2",contract.getContactAddress2());
+                    put("customerMobile",contract.getMobile());
+                    put("userMobile",contract.getUserMobile());
+                    put("signLocation1",contract.getSignLocation1());
+                    put("signLocation2",contract.getSignLocation2());
                 }});
+
         try {
             response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
             response.setHeader("Content-Disposition","attachment;filename=\""+downloadName+".docx"+"\"");
@@ -48,5 +100,27 @@ public class PoiWordUtil {
         } catch (IOException e) {
             e.printStackTrace();
         }
+//        try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())) {
+//            // 设置响应头
+//            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
+//            response.setHeader("Content-Disposition", "attachment;filename=\"" + downloadName + ".docx\"");
+//
+//            // 将模板写入输出流
+//            template.write(bos);
+//            bos.flush();
+//
+//            // 同时将生成的文档保存到缓存路径
+//            FileOutputStream fos = new FileOutputStream(cacheFilePath);
+//            template.write(fos);
+//            fos.close();
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        } finally {
+//            PoitlIOUtils.closeQuietlyMulti(template);
+//        }
+
     }
+
+
+
 }

+ 2 - 2
src/main/resources/application-dev.yaml

@@ -68,9 +68,9 @@ mybatis:
 
 upload:
   host: "http://tczbus.natappfree.cc/uploads"
-  location: "D:\\Java\\loan-backend\\src\\main\\resources\\file_store" #改
+  location: "classpath:file_store" #改
   extensions: "pdf,doc,docx,xls,xlsx,JPG,jpg,bmp,BMP,gif,GIF,BMP,png,PNG,bmp,jpeg,JPEG,svg,txt"
-  templatePath: "D:\\Java\\loan-backend\\src\\resources\\template.docx" #改
+  templatePath: "classpath:file_store\\template\\template1.docx" #改
 
 system:
   wechat:

TEMPAT SAMPAH
src/main/resources/file_store/template/template1.docx