Quellcode durchsuchen

Merge remote-tracking branch 'origin/dev' into dev

caozj vor 1 Jahr
Ursprung
Commit
967a12490e
100 geänderte Dateien mit 3457 neuen und 650 gelöschten Zeilen
  1. 3 3
      code/src/test/java/CommonDataSource.java
  2. 2 2
      code/src/test/java/SaleDataSource.java
  3. 12 3
      hx-account/src/main/java/com/fjhx/account/entity/account/po/AccountPayment.java
  4. 65 16
      hx-account/src/main/java/com/fjhx/account/flow/AccountRequestFundsFlow.java
  5. 1 1
      hx-account/src/main/java/com/fjhx/account/mapper/account/AccountRequestFundsMapper.java
  6. 11 0
      hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountDeptRunningWaterDetailServiceImpl.java
  7. 1 1
      hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountPaymentServiceImpl.java
  8. 1 1
      hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountRequestFundsServiceImpl.java
  9. 109 14
      hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountRunningWaterServiceImpl.java
  10. 7 7
      hx-account/src/main/resources/mapper/account/AccountDeptRunningWaterMapper.xml
  11. 1 0
      hx-account/src/main/resources/mapper/account/AccountRequestFundsMapper.xml
  12. 78 43
      hx-account/src/main/resources/mapper/account/AccountRunningWaterMapper.xml
  13. 5 0
      hx-admin/pom.xml
  14. 2 2
      hx-admin/src/main/resources/application-dev.yml
  15. 2 1
      hx-admin/src/main/resources/application-test.yml
  16. 2 2
      hx-admin/src/main/resources/application.yml
  17. 46 0
      hx-common/src/main/java/com/fjhx/common/controller/employee/EmployeeHandoverController.java
  18. 68 68
      hx-common/src/main/java/com/fjhx/common/controller/send/SendMegController.java
  19. 17 0
      hx-common/src/main/java/com/fjhx/common/entity/employee/dto/EmployeeHandoverDto.java
  20. 17 0
      hx-common/src/main/java/com/fjhx/common/entity/employee/dto/EmployeeHandoverSelectDto.java
  21. 46 0
      hx-common/src/main/java/com/fjhx/common/entity/employee/po/EmployeeHandover.java
  22. 27 0
      hx-common/src/main/java/com/fjhx/common/entity/employee/vo/EmployeeHandoverVo.java
  23. 2 2
      hx-common/src/main/java/com/fjhx/common/enums/FlowStatusEnum1.java
  24. 7 0
      hx-common/src/main/java/com/fjhx/common/enums/PushBusinessTypeEnum.java
  25. 26 0
      hx-common/src/main/java/com/fjhx/common/mapper/employee/EmployeeHandoverMapper.java
  26. 21 21
      hx-common/src/main/java/com/fjhx/common/mapper/send/SendMegMapper.java
  27. 10 0
      hx-common/src/main/java/com/fjhx/common/service/CommService.java
  28. 31 0
      hx-common/src/main/java/com/fjhx/common/service/employee/EmployeeHandoverService.java
  29. 90 0
      hx-common/src/main/java/com/fjhx/common/service/employee/impl/EmployeeHandoverServiceImpl.java
  30. 42 42
      hx-common/src/main/java/com/fjhx/common/service/send/SendMegService.java
  31. 166 166
      hx-common/src/main/java/com/fjhx/common/service/send/impl/SendMegServiceImpl.java
  32. 19 0
      hx-common/src/main/resources/mapper/employee/EmployeeHandoverMapper.xml
  33. 5 0
      hx-customer/src/main/java/com/fjhx/customer/entity/customer/po/Customer.java
  34. 5 0
      hx-customer/src/main/java/com/fjhx/customer/entity/customer/vo/CustomerFollowRecordsVo.java
  35. 21 0
      hx-customer/src/main/java/com/fjhx/customer/service/customer/CommServiceImpl.java
  36. 3 0
      hx-customer/src/main/resources/mapper/customer/CustomerFollowRecordsMapper.xml
  37. 5 1
      hx-customer/src/main/resources/mapper/customer/CustomerMapper.xml
  38. 30 0
      hx-form/pom.xml
  39. 32 0
      hx-form/src/main/java/com/fjhx/form/controller/employee/EmployeeAnalysisController.java
  40. 30 0
      hx-form/src/main/java/com/fjhx/form/entity/dto/EmployeeAnalysisDto.java
  41. 38 0
      hx-form/src/main/java/com/fjhx/form/mapper/employee/EmployeeAnalysisMapper.java
  42. 10 0
      hx-form/src/main/java/com/fjhx/form/service/employee/EmployeeAnalysisService.java
  43. 317 0
      hx-form/src/main/java/com/fjhx/form/service/employee/impl/EmployeeAnalysisServiceImpl.java
  44. 48 0
      hx-form/src/main/resources/mapper/EmployeeAnalysisMapper.xml
  45. 6 1
      hx-jxst/src/main/java/com/fjhx/jxst/flow/SalesContractFlow.java
  46. 1 1
      hx-mail/src/main/java/com/fjhx/mail/listener/LoginEventListeners.java
  47. 1 2
      hx-oa/src/main/java/com/fjhx/oa/service/daily/impl/DailyReportDetailsServiceImpl.java
  48. 2 5
      hx-oa/src/main/java/com/fjhx/oa/service/daily/impl/DailyReportServiceImpl.java
  49. 71 9
      hx-purchase/src/main/java/com/fjhx/purchase/flow/PayFlow.java
  50. 57 10
      hx-purchase/src/main/java/com/fjhx/purchase/flow/RefundFlow.java
  51. 51 7
      hx-purchase/src/main/java/com/fjhx/purchase/flow/SalesReturnFlow.java
  52. 51 9
      hx-purchase/src/main/java/com/fjhx/purchase/flow/SubscribeFlow.java
  53. 9 2
      hx-purchase/src/main/java/com/fjhx/purchase/flow/SubscribeFlowByWdly.java
  54. 9 2
      hx-purchase/src/main/java/com/fjhx/purchase/mapper/pay/PayMapper.java
  55. 13 5
      hx-purchase/src/main/java/com/fjhx/purchase/service/pay/PayService.java
  56. 7 0
      hx-purchase/src/main/java/com/fjhx/purchase/service/pay/impl/PayServiceImpl.java
  57. 9 2
      hx-purchase/src/main/resources/mapper/pay/PayMapper.xml
  58. 10 9
      hx-purchase/src/main/resources/mapper/purchase/PurchaseMapper.xml
  59. 35 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesController.java
  60. 70 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesDetailController.java
  61. 46 0
      hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesRecordsController.java
  62. 9 0
      hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractController.java
  63. 23 5
      hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractProductController.java
  64. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailDto.java
  65. 32 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailSelectDto.java
  66. 25 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDto.java
  67. 22 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordSelectDto.java
  68. 25 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsDto.java
  69. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesSelectDto.java
  70. 46 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSales.java
  71. 68 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesDetail.java
  72. 43 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesRecords.java
  73. 58 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesDetailVo.java
  74. 22 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesRecordsVo.java
  75. 17 0
      hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesVo.java
  76. 9 3
      hx-sale/src/main/java/com/fjhx/sale/entity/claim/po/ClaimContract.java
  77. 5 0
      hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractPdfInfoVo.java
  78. 12 1
      hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractVo.java
  79. 5 0
      hx-sale/src/main/java/com/fjhx/sale/entity/quotation/vo/QuotationProductVo.java
  80. 2 2
      hx-sale/src/main/java/com/fjhx/sale/entity/sale/vo/SaleQuotationVo.java
  81. 126 26
      hx-sale/src/main/java/com/fjhx/sale/flow/ContractFlow.java
  82. 115 31
      hx-sale/src/main/java/com/fjhx/sale/flow/ContractUpdateFlow.java
  83. 7 1
      hx-sale/src/main/java/com/fjhx/sale/flow/EhsdPurchaseFlow.java
  84. 84 38
      hx-sale/src/main/java/com/fjhx/sale/flow/PurchaseFlow.java
  85. 6 0
      hx-sale/src/main/java/com/fjhx/sale/flow/PurchaseFlowByWdly.java
  86. 75 27
      hx-sale/src/main/java/com/fjhx/sale/flow/SaleQuotationFlow.java
  87. 10 5
      hx-sale/src/main/java/com/fjhx/sale/flow/SampleFlow.java
  88. 85 31
      hx-sale/src/main/java/com/fjhx/sale/flow/ServiceContractFlow.java
  89. 26 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesDetailMapper.java
  90. 17 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesMapper.java
  91. 26 0
      hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesRecordsMapper.java
  92. 46 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesDetailService.java
  93. 31 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesRecordsService.java
  94. 23 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesService.java
  95. 195 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesDetailServiceImpl.java
  96. 53 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesRecordsServicesImpl.java
  97. 64 0
      hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesServiceImpl.java
  98. 8 7
      hx-sale/src/main/java/com/fjhx/sale/service/claim/impl/ClaimContractServiceImpl.java
  99. 11 4
      hx-sale/src/main/java/com/fjhx/sale/service/contract/ContractProductService.java
  100. 63 9
      hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractProductServiceImpl.java

+ 3 - 3
code/src/test/java/CommonDataSource.java

@@ -4,9 +4,9 @@ public class CommonDataSource {
 
     public static void main(String[] args) {
         GeneratorApplication.builder()
-                .url("jdbc:mysql://36.134.91.96:17330/bytesailing_common?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
-                .username("fjhx2012mysql")
-                .password("3PN-Mzn#vnP&q6d")
+                .url("jdbc:mysql://121.37.194.75:30102/bytesailing_common?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
+                .username("root")
+                .password("5fWD*oa^nso@kmKa")
                 .port(9989)
                 .module("hx-common")
                 .parent("com.fjhx.common")

+ 2 - 2
code/src/test/java/SaleDataSource.java

@@ -4,9 +4,9 @@ public class SaleDataSource {
 
     public static void main(String[] args) {
         GeneratorApplication.builder()
-                .url("jdbc:mysql://36.134.91.96:12333/bytesailing_sale?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
+                .url("jdbc:mysql://121.37.194.75:30102/bytesailing_sale?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
                 .username("root")
-                .password("Fjhx@pwd123")
+                .password("5fWD*oa^nso@kmKa")
                 .port(9989)
                 .module("hx-sale")
                 .parent("com.fjhx.sale")

+ 12 - 3
hx-account/src/main/java/com/fjhx/account/entity/account/po/AccountPayment.java

@@ -1,12 +1,13 @@
 package com.fjhx.account.entity.account.po;
 
-import com.ruoyi.common.core.domain.BasePo;
 import com.baomidou.mybatisplus.annotation.TableName;
-import java.math.BigDecimal;
-import java.util.Date;
+import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.math.BigDecimal;
+import java.util.Date;
+
 /**
  * <p>
  * 打款表
@@ -122,5 +123,13 @@ public class AccountPayment extends BasePo {
      */
     private BigDecimal incomeAmount;
 
+    /**
+     * 数据所属人
+     */
+    private Long dataUser;
 
+    /**
+     * 申请时间
+     */
+    private Date applyForTime;
 }

+ 65 - 16
hx-account/src/main/java/com/fjhx/account/flow/AccountRequestFundsFlow.java

@@ -14,14 +14,19 @@ import com.fjhx.account.service.account.AccountPaymentService;
 import com.fjhx.account.service.account.AccountRequestFundsDetailService;
 import com.fjhx.account.service.account.AccountRequestFundsService;
 import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.utils.Assert;
 import com.fjhx.file.utils.ObsFileUtil;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -58,23 +63,10 @@ public class AccountRequestFundsFlow extends FlowDelegate {
      */
     @Override
     public Long start(Long flowId, JSONObject submitData) {
-
         // 获取提交数据
         AccountRequestFundsDto accountRequestFundsDto = submitData.toJavaObject(AccountRequestFundsDto.class);
 
-        // 添加请款表的信息
-        accountRequestFundsDto.setStatus(AccountRequestFundsStatusEnum.UNDER_REVIEW.getKey());
-        accountRequestFundsService.save(accountRequestFundsDto);
-
-        // 添加请款详情表的信息
-        List<AccountRequestFundsDetail> accountRequestFundsDetailList = accountRequestFundsDto.getAccountRequestFundsDetailList();
-        if (CollectionUtils.isNotEmpty(accountRequestFundsDetailList)) {
-            accountRequestFundsDetailList.forEach(item -> item.setAccountRequestFundsId(accountRequestFundsDto.getId()));
-            accountRequestFundsDetailService.saveBatch(accountRequestFundsDetailList);
-        }
-
-        // 添加附件信息
-        ObsFileUtil.saveFile(accountRequestFundsDto.getFileList(), accountRequestFundsDto.getId());
+        accountRequestFundsDto = commStart(accountRequestFundsDto, 0);
 
         return accountRequestFundsDto.getId();
     }
@@ -114,6 +106,62 @@ public class AccountRequestFundsFlow extends FlowDelegate {
 
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            // 获取提交数据
+            AccountRequestFundsDto accountRequestFundsDto = submitData.toJavaObject(AccountRequestFundsDto.class);
+            commStart(accountRequestFundsDto, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            accountRequestFundsService.update(q -> q
+                    .eq(AccountRequestFunds::getId, businessId)
+                    .set(AccountRequestFunds::getStatus, FlowStatusEnum1.REJECT.getKey())//20为驳回
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private AccountRequestFundsDto commStart(AccountRequestFundsDto accountRequestFundsDto, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(accountRequestFundsDto.getId(), "请款id不能为空");
+        }
+
+        // 添加请款表的信息
+        accountRequestFundsDto.setStatus(AccountRequestFundsStatusEnum.UNDER_REVIEW.getKey());
+        accountRequestFundsService.saveOrUpdate(accountRequestFundsDto);
+
+        // 添加请款详情表的信息
+        List<AccountRequestFundsDetail> accountRequestFundsDetailList = accountRequestFundsDto.getAccountRequestFundsDetailList();
+        if (CollectionUtils.isNotEmpty(accountRequestFundsDetailList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                accountRequestFundsDetailService.editLinked(accountRequestFundsDetailList, AccountRequestFundsDetail::getContractId, accountRequestFundsDto.getId());
+            }
+
+            accountRequestFundsDetailList.forEach(item -> item.setAccountRequestFundsId(accountRequestFundsDto.getId()));
+            accountRequestFundsDetailService.saveOrUpdateBatch(accountRequestFundsDetailList);
+        }
+
+        if (opType == 1) {
+            // 编辑附件信息
+            ObsFileUtil.editFile(accountRequestFundsDto.getFileList(), accountRequestFundsDto.getId());
+        } else {
+            // 添加附件信息
+            ObsFileUtil.saveFile(accountRequestFundsDto.getFileList(), accountRequestFundsDto.getId());
+        }
+        return accountRequestFundsDto;
+    }
+
     /**
      * 添加打款表的数据
      */
@@ -135,13 +183,14 @@ public class AccountRequestFundsFlow extends FlowDelegate {
         accountPayment.setOpeningBank(accountRequestFunds.getOpeningBank());
         accountPayment.setAccountOpening(accountRequestFunds.getAccountOpening());
         accountPayment.setInterbankNumber(accountRequestFunds.getInterbankNumber());
-        accountPayment.setCreateUser(accountRequestFunds.getCreateUser());
+        accountPayment.setDataUser(accountRequestFunds.getCreateUser());
+        accountPayment.setApplyForTime(accountRequestFunds.getCreateTime());
 
         // 如果是核销 核销数据审批通过后,根据“核销总额 - 预支总额”生成“待打款”数据
         if ("3".equals(accountRequestFunds.getType())) {
             BigDecimal subtract = accountRequestFunds.getTotal().subtract(accountRequestFunds.getAdvanceAmounts());
             accountPayment.setAmount(subtract);
-            if(subtract.compareTo(BigDecimal.ZERO)==0){//不生成打款数据
+            if (subtract.compareTo(BigDecimal.ZERO) <= 0) {//不生成打款数据
                 return;
             }
         } else {

+ 1 - 1
hx-account/src/main/java/com/fjhx/account/mapper/account/AccountRequestFundsMapper.java

@@ -28,6 +28,6 @@ public interface AccountRequestFundsMapper extends BaseMapper<AccountRequestFund
     /**
      * 获取历史付款信息
      */
-    List<AccountRequestFundsVo> getPayHistoricalInfo();
+    List<AccountRequestFundsVo> getPayHistoricalInfo(@Param("userId") Long userId);
 
 }

+ 11 - 0
hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountDeptRunningWaterDetailServiceImpl.java

@@ -126,6 +126,17 @@ public class AccountDeptRunningWaterDetailServiceImpl extends ServiceImpl<Accoun
                //添加部门-资金流水关联表的信息
                accountDeptRunningWaterService.save(accountDeptRunningWater);
                accountDeptRunningWaterDetail.setDeptRunningWaterId(accountDeptRunningWater.getId());
+
+               //根据流水id获取流水金额
+               AccountRunningWater oldAccountRunningWater = accountRunningWaterService.getById(accountRunningWaterVo.getId());
+               accountDeptRunningWaterDetail.setAmount(oldAccountRunningWater.getAmount());
+
+               //调整部门删除历史调整数据
+               AccountDeptRunningWater one = accountDeptRunningWaterService.getOne(q -> q
+                       .eq(AccountDeptRunningWater::getRunningWaterId, accountRunningWaterVo.getId())
+               );
+               this.delete(one.getId());
+
                baseMapper.insert(accountDeptRunningWaterDetail);
            }
         }

+ 1 - 1
hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountPaymentServiceImpl.java

@@ -108,7 +108,7 @@ public class AccountPaymentServiceImpl extends ServiceImpl<AccountPaymentMapper,
         });
 
         // 赋值用户名称
-        UserUtil.assignmentNickName(records, BasePo::getCreateUser, AccountPaymentVo::setUserName);
+        UserUtil.assignmentNickName(records, AccountPayment::getDataUser, AccountPaymentVo::setUserName);
 
         // 赋值部门名称
         DynamicDataSourceContextHolder.push(SourceConstant.BASE);

+ 1 - 1
hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountRequestFundsServiceImpl.java

@@ -216,7 +216,7 @@ public class AccountRequestFundsServiceImpl extends ServiceImpl<AccountRequestFu
      */
     @Override
     public List<AccountRequestFundsVo> getPayHistoricalInfo() {
-        return baseMapper.getPayHistoricalInfo();
+        return baseMapper.getPayHistoricalInfo(SecurityUtils.getUserId());
     }
 
 }

+ 109 - 14
hx-account/src/main/java/com/fjhx/account/service/account/impl/AccountRunningWaterServiceImpl.java

@@ -39,7 +39,6 @@ import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import javax.servlet.http.HttpServletResponse;
 import java.math.BigDecimal;
@@ -219,6 +218,11 @@ public class AccountRunningWaterServiceImpl extends ServiceImpl<AccountRunningWa
         }
         accountRemainderService.updateById(accountRemainder);
 
+        //如果是合同到账 类型设置为到账认领
+        if ("10".equals(dto.getReceived())) {
+            dto.setType("30");
+        }
+
         this.save(dto);
 
         // 发送消息推送
@@ -255,7 +259,7 @@ public class AccountRunningWaterServiceImpl extends ServiceImpl<AccountRunningWa
         //         msg, corporation.getName(), accountManagement.getName(), dto.getCurrency(), dto.getAmount()));
 
         WebSocketPush.byTenant(
-                PushTypeEnum.PUSH_NOTIFICATION,
+                PushTypeEnum.MESSAGE,
                 StrUtil.format(msg, corporation.getName(), accountManagement.getName(), dto.getCurrency(), dto.getAmount()),
                 PushBusinessTypeEnum.TO_THE_ACCOUNT.getType()
         );
@@ -267,25 +271,116 @@ public class AccountRunningWaterServiceImpl extends ServiceImpl<AccountRunningWa
      * 账户资金流水表编辑
      */
     @Override
-    @Transactional(rollbackFor = {Exception.class})
+    @DSTransactional
     public void edit(AccountRunningWater accountRunningWaterDto) {
-        //        //查询资金流水表的数据
-        //        AccountRunningWater accountRunningWater = this.getById(accountRunningWaterDto.getId());
-        //
-        //        //修改账户余额表的余额
-        //        AccountRemainder accountRemainder = accountRemainderService.getOne(Wrappers.<AccountRemainder>lambdaQuery()
-        //                .eq(AccountRemainder::getAccountManagementId,accountRunningWater.getAccountManagementId())
-        //                .eq(AccountRemainder::getCurrency,accountRunningWater.getCurrency())
-        //        );
-        //        if (accountRemainder.getStatus().equals("10")){
-        //            if (accountRemainder.getRemainder().compareTo(accountRunningWater.getAmount())==1)
-        //        }
+        //先回滚历史数据
+        //获取历史的流水信息信息
+        AccountRunningWater oldAccountRunningWater = getById(accountRunningWaterDto.getId());
+        //获取余额
+        AccountRemainder accountRemainder = accountRemainderService.getOne(q -> q
+                .eq(AccountRemainder::getAccountManagementId, oldAccountRunningWater.getAccountManagementId())
+                .eq(AccountRemainder::getCurrency, oldAccountRunningWater.getCurrency())
+        );
+        if (ObjectUtil.isEmpty(accountRemainder)) {
+            throw new ServiceException("历史数据 该账户不存在此币种,请前往资金账户添加");
+        }
+        boolean update = false;
+        if ("10".equals(oldAccountRunningWater.getStatus())) {
+            BigDecimal subtract = accountRemainder.getRemainder().subtract(oldAccountRunningWater.getAmount());
+            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
+                throw new ServiceException("修改前数据 账户余额不足");
+            }
+            update = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder - " + oldAccountRunningWater.getAmount())
+                    .setSql("change_remainder = " + oldAccountRunningWater.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder.getId())
+                    .apply("remainder - {0} >= 0", oldAccountRunningWater.getAmount())
+            );
+        } else {
+            update = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder + " + oldAccountRunningWater.getAmount())
+                    .setSql("change_remainder = " + oldAccountRunningWater.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder.getId())
+            );
+        }
+        Assert.eqTrue(update, "余额回滚操作失败");
+        //再操作修改后数据
+        //获取余额
+        AccountRemainder accountRemainder1 = accountRemainderService.getOne(q -> q
+                .eq(AccountRemainder::getAccountManagementId, accountRunningWaterDto.getAccountManagementId())
+                .eq(AccountRemainder::getCurrency, accountRunningWaterDto.getCurrency())
+        );
+        if (ObjectUtil.isEmpty(accountRemainder)) {
+            throw new ServiceException("修改后数据 该账户不存在此币种,请前往资金账户添加");
+        }
+        boolean update1 = false;
+        if ("10".equals(accountRunningWaterDto.getStatus())) {
+            update1 = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder + " + accountRunningWaterDto.getAmount())
+                    .setSql("change_remainder = " + accountRunningWaterDto.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder1.getId())
+            );
+        } else {
+            BigDecimal subtract = accountRemainder1.getRemainder().subtract(accountRunningWaterDto.getAmount());
+            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
+                throw new ServiceException("修改后数据 账户余额不足");
+            }
+            update1 = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder - " + accountRunningWaterDto.getAmount())
+                    .setSql("change_remainder = " + accountRunningWaterDto.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder1.getId())
+                    .apply("remainder - {0} >= 0", accountRunningWaterDto.getAmount())
+            );
+        }
+        Assert.eqTrue(update1, "余额修改操作失败");
 
         this.updateById(accountRunningWaterDto);
     }
 
+    @DSTransactional
     @Override
     public void delete(Long id) {
+        AccountRunningWater accountRunningWater = getById(id);
+        Assert.notEmpty(accountRunningWater, "获取不到该流水信息");
+
+
+        // 修改账户余额表的余额
+        AccountRemainder accountRemainder = accountRemainderService.getOne(q -> q
+                .eq(AccountRemainder::getAccountManagementId, accountRunningWater.getAccountManagementId())
+                .eq(AccountRemainder::getCurrency, accountRunningWater.getCurrency())
+        );
+        if (ObjectUtil.isEmpty(accountRemainder)) {
+            throw new ServiceException("该账户不存在此币种,请前往资金账户添加");
+        }
+        BigDecimal amount = accountRunningWater.getAmount();
+        String status = accountRunningWater.getStatus();
+        BigDecimal remainder = accountRemainder.getRemainder();
+
+        accountRemainder.setStatus(status);
+        accountRemainder.setChangeRemainder(amount);
+
+        boolean update = false;
+        if ("10".equals(accountRunningWater.getStatus())) {
+            BigDecimal subtract = remainder.subtract(amount);
+            if (subtract.compareTo(BigDecimal.ZERO) < 0) {
+                throw new ServiceException("账户余额不足");
+            }
+
+            update = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder - " + accountRunningWater.getAmount())
+                    .setSql("change_remainder = " + accountRunningWater.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder.getId())
+                    .apply("remainder - {0} >= 0", accountRunningWater.getAmount())
+            );
+        } else {
+            update = accountRemainderService.update(q -> q
+                    .setSql("remainder = remainder + " + accountRunningWater.getAmount())
+                    .setSql("change_remainder = " + accountRunningWater.getAmount())
+                    .eq(AccountRemainder::getId, accountRemainder.getId())
+            );
+        }
+        Assert.eqTrue(update, "余额操作失败操作失败");
+
         this.removeById(id);
     }
 

+ 7 - 7
hx-account/src/main/resources/mapper/account/AccountDeptRunningWaterMapper.xml

@@ -28,15 +28,15 @@
     </select>
 
     <select id="DeptRunningWaterReport" resultType="com.fjhx.account.entity.account.vo.AccountRunningWaterVo">
-        SELECT
-            IF(ar.`status` = 10,SUM(wd.amount),0) incomeAmount,
-            IF(ar.`status` = 20,SUM(wd.amount),0) expenditureAmount,
-            wd.dept_id deptId,
-            DATE_FORMAT(ar.create_time,'%Y-%m') time,
-	        (IF(ar.`status` = 10,SUM(wd.amount),0) - IF(ar.`status` = 20,SUM(wd.amount),0)) balanceAmount
+        SELECT SUM(IF(ar.`status` = 10, wd.amount, 0)) incomeAmount,
+               SUM(IF(ar.`status` = 20, wd.amount, 0)) expenditureAmount,
+               wd.dept_id                              deptId,
+               DATE_FORMAT(ar.create_time, '%Y-%m') time,
+	        SUM(IF(ar.`status` = 10,wd.amount,0) - IF(ar.`status` = 20,wd.amount,0)) balanceAmount
         FROM
             account_dept_running_water rw
-            JOIN account_dept_running_water_detail wd  ON rw.id = wd.dept_running_water_id
+            JOIN account_dept_running_water_detail wd
+        ON rw.id = wd.dept_running_water_id
             LEFT JOIN account_running_water ar ON rw.running_water_id = ar.id
             ${ew.customSqlSegment}
     </select>

+ 1 - 0
hx-account/src/main/resources/mapper/account/AccountRequestFundsMapper.xml

@@ -46,6 +46,7 @@
                       COALESCE(arf.opening_bank, ''),
                       COALESCE(arf.interbank_number, '')
                   ) != ''
+        and arf.create_user = #{userId}
     </select>
 
 </mapper>

+ 78 - 43
hx-account/src/main/resources/mapper/account/AccountRunningWaterMapper.xml

@@ -3,50 +3,85 @@
 <mapper namespace="com.fjhx.account.mapper.account.AccountRunningWaterMapper">
     <!--这段代码正常是不需要跨库查询的。但是一开始封装包的时候分装的不合理,pom里面包是不能互相引用的。account包继承sale包会出现依赖冲突,目前不好改动,只能跨库查询-->
     <select id="getPage" resultType="com.fjhx.account.entity.account.vo.AccountRunningWaterVo">
-        SELECT arw.*
-             , if(arw.type = 40, (select GROUP_CONCAT(c.`code`)
-                                  from tax_refund_details trd
-                                           left join bytesailing_sale.contract c on c.id = trd.contract_id
-                                  where trd.account_running_water_id = arw.id),
-                  (SELECT IF
-                              (t1.type = 20, GROUP_CONCAT(c.`code`), GROUP_CONCAT(t4.`code`)) contractCodes
-                   FROM account_payment t1
-                            LEFT JOIN account_request_funds t2 ON t1.business_id = t2.id
-                            LEFT JOIN account_request_funds_detail t3 ON t2.id = t3.account_request_funds_id
-                            LEFT JOIN `bytesailing_sale`.contract t4 ON t3.contract_id = t4.id
-                       --采购付款来源
-                            LEFT JOIN bytesailing_purchase.pay pa ON t1.business_id = pa.id
-                            LEFT JOIN bytesailing_purchase.pay_detail pad
-                      ON pad.pay_id = pa.id
-                      LEFT JOIN bytesailing_purchase.purchase p ON pad.purchase_id = p.id
-                      LEFT JOIN bytesailing_sale.contract c ON p.data_resource_id = c.id
-                      WHERE
-                      t1.id = arw.business_id ) )AS contractCodes
-
-             , if(arw.type = 40, (select GROUP_CONCAT(trd.contract_id)
-                                  from tax_refund_details trd
-                                  where trd.account_running_water_id = arw.id), (SELECT IF
-                                                                                            (t1.type = 20,
-                                                                                             GROUP_CONCAT(c.id),
-                                                                                             GROUP_CONCAT(t4.id)) contractIds
-                                                                                 FROM account_payment t1
-                                                                                          LEFT JOIN account_request_funds t2
-                                                                                                    ON t1.business_id = t2.id
-                                                                                          LEFT JOIN account_request_funds_detail t3 ON t2.id = t3.account_request_funds_id
-                                                                                          LEFT JOIN `bytesailing_sale`.contract t4
-                                                                                                    ON t3.contract_id = t4.id
-                                                                                     --采购付款来源
-                                                                                          LEFT JOIN bytesailing_purchase.pay pa ON t1.business_id = pa.id
-                                                                                          LEFT JOIN bytesailing_purchase.pay_detail pad ON pad.pay_id = pa.id
-                      LEFT JOIN bytesailing_purchase.purchase p ON pad.purchase_id = p.id
-                      LEFT JOIN bytesailing_sale.contract c ON p.data_resource_id = c.id
-                      WHERE
-                      t1.id = arw.business_id )) AS contractIds
-             , am.alias                             accountManagementName
-             , am.corporation_id
+        SELECT arw.*,
+               IF
+                   (
+                           arw.type = 40,
+                           (SELECT GROUP_CONCAT(c.`code`)
+                            FROM tax_refund_details trd
+                                     LEFT JOIN bytesailing_sale.contract c ON c.id = trd.contract_id
+                            WHERE trd.account_running_water_id = arw.id),
+                           IF
+                               (
+                                       arw.type = 30, (SELECT GROUP_CONCAT(clc.contract_code)
+                                                       FROM bytesailing_sale.claim cl
+                                                                LEFT JOIN bytesailing_sale.claim_contract clc ON clc.claim_id = cl.id
+                                                       WHERE cl.business_id = arw.id),
+                                       (SELECT IF
+                                                   (
+                                                           t1.type = 20,
+                                                           (SELECT GROUP_CONCAT(c.`code`)
+                                                            FROM bytesailing_purchase.pay pa
+                                                                     LEFT JOIN bytesailing_purchase.pay_detail pad ON pad.pay_id = pa.id
+                                                               LEFT JOIN bytesailing_purchase.purchase p ON pad.purchase_id = p.id
+                                                               LEFT JOIN bytesailing_sale.contract c ON p.data_resource_id = c.id
+                                                               WHERE
+                                                               t1.business_id = pa.id ),(
+					SELECT
+						GROUP_CONCAT( t4.`code` )
+					FROM
+						account_request_funds t2
+						LEFT JOIN account_request_funds_detail t3 ON t2.id = t3.account_request_funds_id
+						LEFT JOIN `bytesailing_sale`.contract t4 ON t3.contract_id = t4.id
+					WHERE
+						t1.business_id = t2.id
+					)
+				) contractCodes
+                                        FROM account_payment t1
+                                        WHERE t1.id = arw.business_id)
+                               )
+                   ) AS contractCodes,
+               IF
+                   (
+                           arw.type = 40,
+                           (SELECT GROUP_CONCAT(c.`id`)
+                            FROM tax_refund_details trd
+                                     LEFT JOIN bytesailing_sale.contract c ON c.id = trd.contract_id
+                            WHERE trd.account_running_water_id = arw.id),
+                           IF
+                               (
+                                       arw.type = 30, (SELECT GROUP_CONCAT(clc.contract_id)
+                                                       FROM bytesailing_sale.claim cl
+                                                                LEFT JOIN bytesailing_sale.claim_contract clc ON clc.claim_id = cl.id
+                                                       WHERE cl.business_id = arw.id),
+                                       (SELECT IF
+                                                   (
+                                                           t1.type = 20,
+                                                           (SELECT GROUP_CONCAT(c.`id`)
+                                                            FROM bytesailing_purchase.pay pa
+                                                                     LEFT JOIN bytesailing_purchase.pay_detail pad ON pad.pay_id = pa.id
+                                                               LEFT JOIN bytesailing_purchase.purchase p ON pad.purchase_id = p.id
+                                                               LEFT JOIN bytesailing_sale.contract c ON p.data_resource_id = c.id
+                                                               WHERE
+                                                               t1.business_id = pa.id ),(
+					SELECT
+						GROUP_CONCAT( t4.`id` )
+					FROM
+						account_request_funds t2
+						LEFT JOIN account_request_funds_detail t3 ON t2.id = t3.account_request_funds_id
+						LEFT JOIN `bytesailing_sale`.contract t4 ON t3.contract_id = t4.id
+					WHERE
+						t1.business_id = t2.id
+					)
+				) contractCodes
+                                        FROM account_payment t1
+                                        WHERE t1.id = arw.business_id)
+                               )
+                   ) AS contractIds,
+               am.alias accountManagementName,
+               am.corporation_id
         FROM account_running_water arw
-                 LEFT JOIN account_management am
-                           ON arw.account_management_id = am.id
+                 LEFT JOIN account_management am ON arw.account_management_id = am.id
             ${ew.customSqlSegment}
     </select>
     <select id="getDetail" resultType="com.fjhx.account.entity.account.vo.AccountRunningWaterVo">

+ 5 - 0
hx-admin/pom.xml

@@ -95,6 +95,11 @@
         </dependency>
 
         <dependency>
+            <groupId>com.fjhx</groupId>
+            <artifactId>hx-form</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>

+ 2 - 2
hx-admin/src/main/resources/application-dev.yml

@@ -103,8 +103,8 @@ spring:
 
 mail:
     # 调用邮箱服务url前缀
-    urlPrefix: http://localhost:8088/mailService/
-    abroadUrlPrefix: http://localhost:8088/mailService/
+    urlPrefix:
+    abroadUrlPrefix:
 
 hx:
     httpUrl: http://localhost:9898/

+ 2 - 1
hx-admin/src/main/resources/application-test.yml

@@ -98,12 +98,13 @@ spring:
                 max-wait: -1ms
 
 server:
+    port: 20001
     servlet:
         context-path: /test-api
 
 mail:
     # 调用邮箱服务url前缀
-    urlPrefix: http://localhost:8088/mailService/
+    urlPrefix:
     abroadUrlPrefix:
 
 hx:

+ 2 - 2
hx-admin/src/main/resources/application.yml

@@ -1,7 +1,7 @@
 # 项目相关配置
 ruoyi:
   # 名称
-  name: RuoYi
+  name: byteSailing
   # 版本
   version: 3.8.5
   # 版权年份
@@ -18,7 +18,7 @@ ruoyi:
 # 开发环境配置
 server:
   # 服务器的HTTP端口,默认为8080
-  port: 20001
+  port: 9898
   tomcat:
     # tomcat的URI编码
     uri-encoding: UTF-8

+ 46 - 0
hx-common/src/main/java/com/fjhx/common/controller/employee/EmployeeHandoverController.java

@@ -0,0 +1,46 @@
+package com.fjhx.common.controller.employee;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverDto;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverSelectDto;
+import com.fjhx.common.entity.employee.vo.EmployeeHandoverVo;
+import com.fjhx.common.service.employee.EmployeeHandoverService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 员工交接 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@RestController
+@RequestMapping("/employeeHandover")
+public class EmployeeHandoverController {
+
+    @Autowired
+    private EmployeeHandoverService employeeHandoverService;
+
+    /**
+     * 员工交接分页
+     */
+    @PostMapping("/page")
+    public Page<EmployeeHandoverVo> page(@RequestBody EmployeeHandoverSelectDto dto) {
+        return employeeHandoverService.getPage(dto);
+    }
+
+    /**
+     * 员工交接新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody EmployeeHandoverDto employeeHandoverDto) {
+        employeeHandoverService.add(employeeHandoverDto);
+    }
+
+}

+ 68 - 68
hx-common/src/main/java/com/fjhx/common/controller/send/SendMegController.java

@@ -1,79 +1,79 @@
-// package com.fjhx.common.controller.send;
+//package com.fjhx.common.controller.send;
 //
-// import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-// import com.fjhx.common.entity.send.dto.SendMegDto;
-// import com.fjhx.common.entity.send.dto.SendMegSelectDto;
-// import com.fjhx.common.entity.send.vo.SendMegVo;
-// import com.fjhx.common.service.send.SendMegService;
-// import com.ruoyi.common.core.domain.BaseSelectDto;
-// import org.springframework.beans.factory.annotation.Autowired;
-// import org.springframework.scheduling.annotation.EnableScheduling;
-// import org.springframework.scheduling.annotation.Scheduled;
-// import org.springframework.web.bind.annotation.PostMapping;
-// import org.springframework.web.bind.annotation.RequestBody;
-// import org.springframework.web.bind.annotation.RequestMapping;
-// import org.springframework.web.bind.annotation.RestController;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import com.fjhx.common.entity.send.dto.SendMegDto;
+//import com.fjhx.common.entity.send.dto.SendMegSelectDto;
+//import com.fjhx.common.entity.send.vo.SendMegVo;
+//import com.fjhx.common.service.send.SendMegService;
+//import com.ruoyi.common.core.domain.BaseSelectDto;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.scheduling.annotation.EnableScheduling;
+//import org.springframework.scheduling.annotation.Scheduled;
+//import org.springframework.web.bind.annotation.PostMapping;
+//import org.springframework.web.bind.annotation.RequestBody;
+//import org.springframework.web.bind.annotation.RequestMapping;
+//import org.springframework.web.bind.annotation.RestController;
 //
 //
-// /**
-//  * <p>
-//  * 前端控制器
-//  * </p>
-//  *
-//  * @author
-//  * @since 2023-05-22
-//  */
-// @EnableScheduling
-// @RestController
-// @RequestMapping("/sendMeg")
-// public class SendMegController {
+///**
+// * <p>
+// * 前端控制器
+// * </p>
+// *
+// * @author
+// * @since 2023-05-22
+// */
+//@EnableScheduling
+//@RestController
+//@RequestMapping("/sendMeg")
+//public class SendMegController {
 //
-//     @Autowired
-//     private SendMegService sendMegService;
+//    @Autowired
+//    private SendMegService sendMegService;
 //
-//     /**
-//      * 分页
-//      */
-//     @PostMapping("/page")
-//     public Page<SendMegVo> page(@RequestBody SendMegSelectDto dto) {
-//         return sendMegService.getPage(dto);
-//     }
+//    /**
+//     * 分页
+//     */
+//    @PostMapping("/page")
+//    public Page<SendMegVo> page(@RequestBody SendMegSelectDto dto) {
+//        return sendMegService.getPage(dto);
+//    }
 //
-//     /**
-//      * 明细
-//      */
-//     @PostMapping("/detail")
-//     public SendMegVo detail(@RequestBody BaseSelectDto dto) {
-//         return sendMegService.detail(dto.getId());
-//     }
+//    /**
+//     * 明细
+//     */
+//    @PostMapping("/detail")
+//    public SendMegVo detail(@RequestBody BaseSelectDto dto) {
+//        return sendMegService.detail(dto.getId());
+//    }
 //
-//     /**
-//      * 新增
-//      */
-//     @PostMapping("/add")
-//     public void add(@RequestBody SendMegDto sendMegDto) {
-//         sendMegService.add(sendMegDto);
-//     }
+//    /**
+//     * 新增
+//     */
+//    @PostMapping("/add")
+//    public void add(@RequestBody SendMegDto sendMegDto) {
+//        sendMegService.add(sendMegDto);
+//    }
 //
-//     /**
-//      * 编辑
-//      */
-//     @PostMapping("/edit")
-//     public void edit(@RequestBody SendMegDto sendMegDto) {
-//         sendMegService.edit(sendMegDto);
-//     }
+//    /**
+//     * 编辑
+//     */
+//    @PostMapping("/edit")
+//    public void edit(@RequestBody SendMegDto sendMegDto) {
+//        sendMegService.edit(sendMegDto);
+//    }
 //
-//     /**
-//      * 删除
-//      */
-//     @PostMapping("/delete")
-//     public void delete(@RequestBody BaseSelectDto dto) {
-//         sendMegService.delete(dto.getId());
-//     }
+//    /**
+//     * 删除
+//     */
+//    @PostMapping("/delete")
+//    public void delete(@RequestBody BaseSelectDto dto) {
+//        sendMegService.delete(dto.getId());
+//    }
 //
-//     @Scheduled(cron = "0 0/1 *  * * ? ")   // 每1分钟执行一次
-//     public void execute() {
-//         sendMegService.executeSend();
-//     }
+//    @Scheduled(cron = "0 0/1 *  * * ? ")   // 每1分钟执行一次
+//    public void execute() {
+//        sendMegService.executeSend();
+//    }
 //
-// }
+//}

+ 17 - 0
hx-common/src/main/java/com/fjhx/common/entity/employee/dto/EmployeeHandoverDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.common.entity.employee.dto;
+
+import com.fjhx.common.entity.employee.po.EmployeeHandover;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 员工交接新增编辑入参实体
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@Getter
+@Setter
+public class EmployeeHandoverDto extends EmployeeHandover {
+
+}

+ 17 - 0
hx-common/src/main/java/com/fjhx/common/entity/employee/dto/EmployeeHandoverSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.common.entity.employee.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 员工交接列表查询入参实体
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@Getter
+@Setter
+public class EmployeeHandoverSelectDto extends BaseSelectDto {
+
+}

+ 46 - 0
hx-common/src/main/java/com/fjhx/common/entity/employee/po/EmployeeHandover.java

@@ -0,0 +1,46 @@
+package com.fjhx.common.entity.employee.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 员工交接
+ * </p>
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@Getter
+@Setter
+@TableName("employee_handover")
+public class EmployeeHandover extends BasePo {
+
+    /**
+     * 交接人id
+     */
+    private Long handoverPersonId;
+
+    /**
+     * 接收人id
+     */
+    private Long recipientId;
+
+    /**
+     * 交接原因
+     */
+    private String reason;
+
+    /**
+     * 交接内容(逗号分隔)
+     */
+    private String content;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+}

+ 27 - 0
hx-common/src/main/java/com/fjhx/common/entity/employee/vo/EmployeeHandoverVo.java

@@ -0,0 +1,27 @@
+package com.fjhx.common.entity.employee.vo;
+
+import com.fjhx.common.entity.employee.po.EmployeeHandover;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 员工交接列表查询返回值实体
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@Getter
+@Setter
+public class EmployeeHandoverVo extends EmployeeHandover {
+
+    /**
+     * 交接人名称
+     */
+    private String handoverPersonName;
+
+    /**
+     * 接收人名称
+     */
+    private String recipientName;
+
+}

+ 2 - 2
hx-common/src/main/java/com/fjhx/common/enums/FlowStatusEnum.java → hx-common/src/main/java/com/fjhx/common/enums/FlowStatusEnum1.java

@@ -11,7 +11,7 @@ import java.util.Map;
  */
 @Getter
 @AllArgsConstructor
-public enum FlowStatusEnum {
+public enum FlowStatusEnum1 {
 
     DRAFT(0, "草稿"),
     UNDER_REVIEW(10, "审批中"),
@@ -25,7 +25,7 @@ public enum FlowStatusEnum {
     private static final Map<Integer, String> map = new LinkedHashMap<>();
 
     static {
-        for (FlowStatusEnum ms : values()) {
+        for (FlowStatusEnum1 ms : values()) {
             map.put(ms.key, ms.value);
         }
     }

+ 7 - 0
hx-common/src/main/java/com/fjhx/common/enums/PushBusinessTypeEnum.java

@@ -3,10 +3,17 @@ package com.fjhx.common.enums;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+/**
+ * 推送业务类型
+ */
 @Getter
 @AllArgsConstructor
 public enum PushBusinessTypeEnum {
     /**
+     * 流程专用
+     */
+    FLOW(0),
+    /**
      * 未读日报
      */
     UNREAD_DAILY(1),

+ 26 - 0
hx-common/src/main/java/com/fjhx/common/mapper/employee/EmployeeHandoverMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.common.mapper.employee;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.employee.po.EmployeeHandover;
+import com.fjhx.common.entity.employee.vo.EmployeeHandoverVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 员工交接 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-07-17
+ */
+public interface EmployeeHandoverMapper extends BaseMapper<EmployeeHandover> {
+
+    /**
+     * 员工交接分页
+     */
+    Page<EmployeeHandoverVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<EmployeeHandover> wrapper);
+
+}

+ 21 - 21
hx-common/src/main/java/com/fjhx/common/mapper/send/SendMegMapper.java

@@ -1,26 +1,26 @@
-// package com.fjhx.common.mapper.send;
+//package com.fjhx.common.mapper.send;
 //
-// import com.fjhx.common.entity.send.po.SendMeg;
-// import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-// import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-// import com.fjhx.common.entity.send.vo.SendMegVo;
-// import com.ruoyi.common.utils.wrapper.IWrapper;
-// import org.apache.ibatis.annotations.Param;
+//import com.fjhx.common.entity.send.po.SendMeg;
+//import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import com.fjhx.common.entity.send.vo.SendMegVo;
+//import com.ruoyi.common.utils.wrapper.IWrapper;
+//import org.apache.ibatis.annotations.Param;
 //
 //
-// /**
-//  * <p>
-//  *  Mapper 接口
-//  * </p>
-//  *
-//  * @author
-//  * @since 2023-05-22
-//  */
-// public interface SendMegMapper extends BaseMapper<SendMeg> {
+///**
+// * <p>
+// *  Mapper 接口
+// * </p>
+// *
+// * @author
+// * @since 2023-05-22
+// */
+//public interface SendMegMapper extends BaseMapper<SendMeg> {
 //
-//     /**
-//      * 分页
-//      */
-//     Page<SendMegVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<SendMeg> wrapper);
+//    /**
+//     * 分页
+//     */
+//    Page<SendMegVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<SendMeg> wrapper);
 //
-// }
+//}

+ 10 - 0
hx-common/src/main/java/com/fjhx/common/service/CommService.java

@@ -0,0 +1,10 @@
+package com.fjhx.common.service;
+
+public interface CommService {
+
+    /**
+     * 更新客户业务员
+     */
+    void updateCustomerSalesperson(Long handoverPersonId, Long recipientId);
+
+}

+ 31 - 0
hx-common/src/main/java/com/fjhx/common/service/employee/EmployeeHandoverService.java

@@ -0,0 +1,31 @@
+package com.fjhx.common.service.employee;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverDto;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverSelectDto;
+import com.fjhx.common.entity.employee.po.EmployeeHandover;
+import com.fjhx.common.entity.employee.vo.EmployeeHandoverVo;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 员工交接 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-17
+ */
+public interface EmployeeHandoverService extends BaseService<EmployeeHandover> {
+
+    /**
+     * 员工交接分页
+     */
+    Page<EmployeeHandoverVo> getPage(EmployeeHandoverSelectDto dto);
+
+    /**
+     * 员工交接新增
+     */
+    void add(EmployeeHandoverDto employeeHandoverDto);
+
+}

+ 90 - 0
hx-common/src/main/java/com/fjhx/common/service/employee/impl/EmployeeHandoverServiceImpl.java

@@ -0,0 +1,90 @@
+package com.fjhx.common.service.employee.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverDto;
+import com.fjhx.common.entity.employee.dto.EmployeeHandoverSelectDto;
+import com.fjhx.common.entity.employee.po.EmployeeHandover;
+import com.fjhx.common.entity.employee.vo.EmployeeHandoverVo;
+import com.fjhx.common.mapper.employee.EmployeeHandoverMapper;
+import com.fjhx.common.service.CommService;
+import com.fjhx.common.service.employee.EmployeeHandoverService;
+import com.fjhx.common.utils.Assert;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.utils.UserUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * 员工交接 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-17
+ */
+@Service
+public class EmployeeHandoverServiceImpl extends ServiceImpl<EmployeeHandoverMapper, EmployeeHandover> implements EmployeeHandoverService {
+
+    @Autowired
+    private CommService commService;
+    @Autowired
+    private ISysUserService userService;
+
+    @Override
+    public Page<EmployeeHandoverVo> getPage(EmployeeHandoverSelectDto dto) {
+        IWrapper<EmployeeHandover> wrapper = getWrapper();
+        //关键字搜索
+        if (ObjectUtil.isNotEmpty(dto.getKeyword())) {
+            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+            List<SysUser> userList = userService.list(Wrappers.<SysUser>lambdaQuery().like(SysUser::getNickName, dto.getKeyword()));
+            List<Long> userIds = userList.stream().map(SysUser::getUserId).collect(Collectors.toList());
+            DynamicDataSourceContextHolder.poll();
+            wrapper.and(q -> q
+                    .like(EmployeeHandoverVo::getReason, dto.getKeyword())
+                    .or().like(EmployeeHandoverVo::getRemark, dto.getKeyword())
+                    .or().in(EmployeeHandoverVo::getHandoverPersonId, userIds)
+                    .or().in(EmployeeHandoverVo::getRecipientId, userIds)
+            );
+        }
+        wrapper.orderByDesc("eh", EmployeeHandover::getId);
+        Page<EmployeeHandoverVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        List<EmployeeHandoverVo> records = page.getRecords();
+        //赋值交接人
+        UserUtil.assignmentNickName(records, EmployeeHandoverVo::getHandoverPersonId, EmployeeHandoverVo::setHandoverPersonName);
+        //赋值接收人
+        UserUtil.assignmentNickName(records, EmployeeHandoverVo::getRecipientId, EmployeeHandoverVo::setRecipientName);
+        return page;
+    }
+
+    @Override
+    @DSTransactional
+    public void add(EmployeeHandoverDto employeeHandoverDto) {
+        String content = employeeHandoverDto.getContent();
+        Assert.notEmpty(content, "交接内容不能为空");
+        String[] split = content.split(",");
+        for (String s : split) {
+            //1客户信息
+            if ("1".equals(s)) {
+                //把交接人的客户信息全部修改至接收人
+                commService.updateCustomerSalesperson(employeeHandoverDto.getHandoverPersonId(), employeeHandoverDto.getRecipientId());
+            } else {
+                throw new ServiceException("未知交接内容:" + s);
+            }
+        }
+        this.save(employeeHandoverDto);
+    }
+
+}

+ 42 - 42
hx-common/src/main/java/com/fjhx/common/service/send/SendMegService.java

@@ -1,55 +1,55 @@
-// package com.fjhx.common.service.send;
+//package com.fjhx.common.service.send;
 //
-// import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-// import com.fjhx.common.entity.send.dto.SendMegDto;
-// import com.fjhx.common.entity.send.dto.SendMegSelectDto;
-// import com.fjhx.common.entity.send.po.SendMeg;
-// import com.fjhx.common.entity.send.vo.SendMegVo;
-// import com.ruoyi.common.core.service.BaseService;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import com.fjhx.common.entity.send.dto.SendMegDto;
+//import com.fjhx.common.entity.send.dto.SendMegSelectDto;
+//import com.fjhx.common.entity.send.po.SendMeg;
+//import com.fjhx.common.entity.send.vo.SendMegVo;
+//import com.ruoyi.common.core.service.BaseService;
 //
 //
-// /**
-//  * <p>
-//  * 服务类
-//  * </p>
-//  *
-//  * @author
-//  * @since 2023-05-22
-//  */
-// public interface SendMegService extends BaseService<SendMeg> {
+///**
+// * <p>
+// * 服务类
+// * </p>
+// *
+// * @author
+// * @since 2023-05-22
+// */
+//public interface SendMegService extends BaseService<SendMeg> {
 //
-//     /**
-//      * 分页
-//      */
-//     Page<SendMegVo> getPage(SendMegSelectDto dto);
+//    /**
+//     * 分页
+//     */
+//    Page<SendMegVo> getPage(SendMegSelectDto dto);
 //
-//     /**
-//      * 明细
-//      */
-//     SendMegVo detail(Long id);
+//    /**
+//     * 明细
+//     */
+//    SendMegVo detail(Long id);
 //
-//     /**
-//      * 新增
-//      */
-//     void add(SendMegDto sendMegDto);
+//    /**
+//     * 新增
+//     */
+//    void add(SendMegDto sendMegDto);
 //
-//     /**
-//      * 编辑
-//      */
-//     void edit(SendMegDto sendMegDto);
+//    /**
+//     * 编辑
+//     */
+//    void edit(SendMegDto sendMegDto);
 //
-//     /**
-//      * 删除
-//      */
-//     void delete(Long id);
+//    /**
+//     * 删除
+//     */
+//    void delete(Long id);
 //
-//     /**
-//      * 推送数据
-//      */
-//     void send(SendMeg sendMeg);
+//    /**
+//     * 推送数据
+//     */
+//    void send(SendMeg sendMeg);
 //
 //
-//     void executeSend();
+//    void executeSend();
 //
 //
-// }
+//}

+ 166 - 166
hx-common/src/main/java/com/fjhx/common/service/send/impl/SendMegServiceImpl.java

@@ -1,166 +1,166 @@
-// package com.fjhx.common.service.send.impl;
-//
-// import cn.hutool.core.bean.BeanUtil;
-// import cn.hutool.core.convert.Convert;
-// import cn.hutool.core.date.DateUtil;
-// import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
-// import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-// import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-// import com.fjhx.common.constant.SourceConstant;
-// import com.fjhx.common.entity.send.dto.SendMegDto;
-// import com.fjhx.common.entity.send.dto.SendMegSelectDto;
-// import com.fjhx.common.entity.send.po.SendMeg;
-// import com.fjhx.common.entity.send.vo.SendMegVo;
-// import com.fjhx.common.mapper.send.SendMegMapper;
-// import com.fjhx.common.service.send.SendMegService;
-// import com.fjhx.socket.entity.MessageEntity;
-// import com.fjhx.socket.event.WebSocketUserOfflineEvent;
-// import com.fjhx.socket.service.WebSocketServer;
-// import com.ruoyi.common.constant.StatusConstant;
-// import com.ruoyi.common.core.domain.entity.SysUser;
-// import com.ruoyi.common.core.redis.RedisCache;
-// import com.ruoyi.common.utils.wrapper.IWrapper;
-// import com.ruoyi.framework.mybatis.holder.TenantHolder;
-// import com.ruoyi.system.service.ISysUserService;
-// import lombok.extern.slf4j.Slf4j;
-// import org.springframework.beans.factory.annotation.Autowired;
-// import org.springframework.context.event.EventListener;
-// import org.springframework.stereotype.Service;
-//
-// import java.util.Date;
-// import java.util.List;
-// import java.util.Set;
-//
-//
-// /**
-//  * <p>
-//  * 服务实现类
-//  * </p>
-//  *
-//  * @author
-//  * @since 2023-05-22
-//  */
-// @Slf4j
-// @Service
-// public class SendMegServiceImpl extends ServiceImpl<SendMegMapper, SendMeg> implements SendMegService {
-//
-//     @Autowired
-//     private ISysUserService sysUserService;
-//
-//     @Autowired
-//     private RedisCache redisCache;
-//
-//     private static final String sendMessageKey = "sendMessage:";
-//
-//     @Override
-//     public Page<SendMegVo> getPage(SendMegSelectDto dto) {
-//         IWrapper<SendMeg> wrapper = getWrapper();
-//         wrapper.eq("sm", SendMeg::getType, dto.getType());
-//         wrapper.eq("sm", SendMeg::getStatus, dto.getStatus());
-//         wrapper.orderByAsc("sm", SendMeg::getStatus);
-//         wrapper.orderByDesc("sm", SendMeg::getId);
-//         Page<SendMegVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
-//         return page;
-//     }
-//
-//     @Override
-//     public SendMegVo detail(Long id) {
-//         SendMeg SendMeg = this.getById(id);
-//         SendMegVo result = BeanUtil.toBean(SendMeg, SendMegVo.class);
-//         return result;
-//     }
-//
-//     @Override
-//     public void add(SendMegDto sendMegDto) {
-//         Date sendTime = sendMegDto.getSendTime();
-//         if (sendTime.before(DateUtil.endOfMinute(new Date()))) {
-//             sendMegDto.setStatus(StatusConstant.YES);
-//             new Thread(() -> send(sendMegDto)).start();
-//         } else {
-//             sendMegDto.setStatus(StatusConstant.NO);
-//         }
-//
-//         this.save(sendMegDto);
-//     }
-//
-//     @Override
-//     public void edit(SendMegDto sendMegDto) {
-//         sendMegDto.setStatus(StatusConstant.YES);
-//         this.updateById(sendMegDto);
-//     }
-//
-//     @Override
-//     public void delete(Long id) {
-//         this.removeById(id);
-//     }
-//
-//     @Override
-//     public synchronized void send(SendMeg sendMeg) {
-//         DynamicDataSourceContextHolder.push(SourceConstant.BASE);
-//         TenantHolder.setIgnore(true);
-//         List<SysUser> list = sysUserService.list();
-//         DynamicDataSourceContextHolder.poll();
-//
-//         for (SysUser sysUser : list) {
-//             WebSocketServer.sendInfo(sysUser.getUserId(), 0, sendMeg);
-//         }
-//
-//     }
-//
-//     @Override
-//     public void executeSend() {
-//
-//         Set<String> scan = redisCache.scan(sendMessageKey + "**");
-//         for (String key : scan) {
-//             String[] split = key.split(":");
-//             if (split.length != 3) {
-//                 return;
-//             }
-//             String userIdStr = split[2];
-//             Long userId = Convert.toLong(userIdStr);
-//             if (userId == null) {
-//                 return;
-//             }
-//
-//             try {
-//                 SendMeg cacheObject = redisCache.getCacheObject(key);
-//                 redisCache.deleteObject(key);
-//                 WebSocketServer.sendInfo(userId, 0, cacheObject);
-//             } catch (Exception e) {
-//                 log.error("推送异常", e);
-//             }
-//
-//         }
-//
-//
-//         List<SendMeg> list = list(q -> q
-//                 .eq(SendMeg::getStatus, StatusConstant.NO)
-//                 .le(SendMeg::getSendTime, DateUtil.endOfMinute(new Date())));
-//
-//         for (SendMeg sendMeg : list) {
-//             send(sendMeg);
-//             sendMeg.setStatus(StatusConstant.YES);
-//         }
-//         updateBatchById(list);
-//
-//     }
-//
-//     @EventListener
-//     public void userOfflineEvent(WebSocketUserOfflineEvent webSocketUserOfflineEvent) {
-//         MessageEntity messageEntity = webSocketUserOfflineEvent.getMessageEntity();
-//
-//         Object data = messageEntity.getData();
-//
-//         if (messageEntity.getType() != 0 || !(data instanceof SendMeg)) {
-//             return;
-//         }
-//
-//         String key = sendMessageKey + ((SendMeg) data).getId() + ":" + messageEntity.getUserId();
-//         if (((SendMeg) data).getEndTime().after(new Date())) {
-//             redisCache.setCacheObject(key, data);
-//         }
-//
-//     }
-//
-//
-// }
+//package com.fjhx.common.service.send.impl;
+//
+//import cn.hutool.core.bean.BeanUtil;
+//import cn.hutool.core.convert.Convert;
+//import cn.hutool.core.date.DateUtil;
+//import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+//import com.fjhx.common.constant.SourceConstant;
+//import com.fjhx.common.entity.send.dto.SendMegDto;
+//import com.fjhx.common.entity.send.dto.SendMegSelectDto;
+//import com.fjhx.common.entity.send.po.SendMeg;
+//import com.fjhx.common.entity.send.vo.SendMegVo;
+//import com.fjhx.common.mapper.send.SendMegMapper;
+//import com.fjhx.common.service.send.SendMegService;
+//import com.fjhx.socket.entity.MessageEntity;
+//import com.fjhx.socket.event.WebSocketUserOfflineEvent;
+//import com.fjhx.socket.service.WebSocketServer;
+//import com.ruoyi.common.constant.StatusConstant;
+//import com.ruoyi.common.core.domain.entity.SysUser;
+//import com.ruoyi.common.core.redis.RedisCache;
+//import com.ruoyi.common.utils.wrapper.IWrapper;
+//import com.ruoyi.framework.mybatis.holder.TenantHolder;
+//import com.ruoyi.system.service.ISysUserService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.event.EventListener;
+//import org.springframework.stereotype.Service;
+//
+//import java.util.Date;
+//import java.util.List;
+//import java.util.Set;
+//
+//
+///**
+// * <p>
+// * 服务实现类
+// * </p>
+// *
+// * @author
+// * @since 2023-05-22
+// */
+//@Slf4j
+//@Service
+//public class SendMegServiceImpl extends ServiceImpl<SendMegMapper, SendMeg> implements SendMegService {
+//
+//    @Autowired
+//    private ISysUserService sysUserService;
+//
+//    @Autowired
+//    private RedisCache redisCache;
+//
+//    private static final String sendMessageKey = "sendMessage:";
+//
+//    @Override
+//    public Page<SendMegVo> getPage(SendMegSelectDto dto) {
+//        IWrapper<SendMeg> wrapper = getWrapper();
+//        wrapper.eq("sm", SendMeg::getType, dto.getType());
+//        wrapper.eq("sm", SendMeg::getStatus, dto.getStatus());
+//        wrapper.orderByAsc("sm", SendMeg::getStatus);
+//        wrapper.orderByDesc("sm", SendMeg::getId);
+//        Page<SendMegVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+//        return page;
+//    }
+//
+//    @Override
+//    public SendMegVo detail(Long id) {
+//        SendMeg SendMeg = this.getById(id);
+//        SendMegVo result = BeanUtil.toBean(SendMeg, SendMegVo.class);
+//        return result;
+//    }
+//
+//    @Override
+//    public void add(SendMegDto sendMegDto) {
+//        Date sendTime = sendMegDto.getSendTime();
+//        if (sendTime.before(DateUtil.endOfMinute(new Date()))) {
+//            sendMegDto.setStatus(StatusConstant.YES);
+//            new Thread(() -> send(sendMegDto)).start();
+//        } else {
+//            sendMegDto.setStatus(StatusConstant.NO);
+//        }
+//
+//        this.save(sendMegDto);
+//    }
+//
+//    @Override
+//    public void edit(SendMegDto sendMegDto) {
+//        sendMegDto.setStatus(StatusConstant.YES);
+//        this.updateById(sendMegDto);
+//    }
+//
+//    @Override
+//    public void delete(Long id) {
+//        this.removeById(id);
+//    }
+//
+//    @Override
+//    public synchronized void send(SendMeg sendMeg) {
+//        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+//        TenantHolder.setIgnore(true);
+//        List<SysUser> list = sysUserService.list();
+//        DynamicDataSourceContextHolder.poll();
+//
+//        for (SysUser sysUser : list) {
+//            WebSocketServer.sendInfo(sysUser.getUserId(), 0, sendMeg);
+//        }
+//
+//    }
+//
+//    @Override
+//    public void executeSend() {
+//
+//        Set<String> scan = redisCache.scan(sendMessageKey + "**");
+//        for (String key : scan) {
+//            String[] split = key.split(":");
+//            if (split.length != 3) {
+//                return;
+//            }
+//            String userIdStr = split[2];
+//            Long userId = Convert.toLong(userIdStr);
+//            if (userId == null) {
+//                return;
+//            }
+//
+//            try {
+//                SendMeg cacheObject = redisCache.getCacheObject(key);
+//                redisCache.deleteObject(key);
+//                WebSocketServer.sendInfo(userId, 0, cacheObject);
+//            } catch (Exception e) {
+//                log.error("推送异常", e);
+//            }
+//
+//        }
+//
+//
+//        List<SendMeg> list = list(q -> q
+//                .eq(SendMeg::getStatus, StatusConstant.NO)
+//                .le(SendMeg::getSendTime, DateUtil.endOfMinute(new Date())));
+//
+//        for (SendMeg sendMeg : list) {
+//            send(sendMeg);
+//            sendMeg.setStatus(StatusConstant.YES);
+//        }
+//        updateBatchById(list);
+//
+//    }
+//
+//    @EventListener
+//    public void userOfflineEvent(WebSocketUserOfflineEvent webSocketUserOfflineEvent) {
+//        MessageEntity messageEntity = webSocketUserOfflineEvent.getMessageEntity();
+//
+//        Object data = messageEntity.getData();
+//
+//        if (messageEntity.getType() != 0 || !(data instanceof SendMeg)) {
+//            return;
+//        }
+//
+//        String key = sendMessageKey + ((SendMeg) data).getId() + ":" + messageEntity.getUserId();
+//        if (((SendMeg) data).getEndTime().after(new Date())) {
+//            redisCache.setCacheObject(key, data);
+//        }
+//
+//    }
+//
+//
+//}

+ 19 - 0
hx-common/src/main/resources/mapper/employee/EmployeeHandoverMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.common.mapper.employee.EmployeeHandoverMapper">
+    <select id="getPage" resultType="com.fjhx.common.entity.employee.vo.EmployeeHandoverVo">
+        select eh.id,
+               eh.handover_person_id,
+               eh.recipient_id,
+               eh.reason,
+               eh.content,
+               eh.remark,
+               eh.create_user,
+               eh.create_time,
+               eh.update_user,
+               eh.update_time
+        from employee_handover eh
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 5 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/customer/po/Customer.java

@@ -90,6 +90,11 @@ public class Customer extends BasePo {
     private String tag;
 
     /**
+     * 税号
+     */
+    private String dutyParagraph;
+
+    /**
      * 用户名称
      */
     @TableField(exist = false)

+ 5 - 0
hx-customer/src/main/java/com/fjhx/customer/entity/customer/vo/CustomerFollowRecordsVo.java

@@ -44,4 +44,9 @@ public class CustomerFollowRecordsVo extends CustomerFollowRecords {
      * 跟进人名称
      */
     private String followUpUserName;
+
+    /**
+     * 报价单code
+     */
+    private String code;
 }

+ 21 - 0
hx-customer/src/main/java/com/fjhx/customer/service/customer/CommServiceImpl.java

@@ -0,0 +1,21 @@
+package com.fjhx.customer.service.customer;
+
+import com.fjhx.common.service.CommService;
+import com.fjhx.customer.entity.customer.po.Customer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class CommServiceImpl implements CommService {
+
+    @Autowired
+    private CustomerService customerService;
+
+    /**
+     * 更新客户业务员
+     */
+    @Override
+    public void updateCustomerSalesperson(Long handoverPersonId, Long recipientId) {
+        customerService.update(q -> q.eq(Customer::getUserId, handoverPersonId).set(Customer::getUserId, recipientId));
+    }
+}

+ 3 - 0
hx-customer/src/main/resources/mapper/customer/CustomerFollowRecordsMapper.xml

@@ -7,6 +7,7 @@
                       amount,
                       create_time `date`,
                       NULL AS     contractCode,
+                      code,
                       10   AS     type,
                       NULL AS     content,
                       create_user
@@ -19,6 +20,7 @@
                       amount,
                       create_time `date`,
                       CODE AS     contractCode,
+                      null as     code,
                       20   AS     type,
                       NULL AS     content,
                       create_user
@@ -31,6 +33,7 @@
                       NULL AS amount,
                       `date`,
                       NULL AS contractCode,
+                      null as code,
                       30   AS type,
                       content,
                       create_user

+ 5 - 1
hx-customer/src/main/resources/mapper/customer/CustomerMapper.xml

@@ -76,6 +76,7 @@
                       amount,
                       create_time `date`,
                       NULL AS     contractCode,
+                      code,
                       10   AS     type,
                       NULL AS     content,
                       create_user
@@ -88,11 +89,13 @@
                       amount,
                       create_time `date`,
                       CODE AS     contractCode,
+                      null as     code,
                       20   AS     type,
                       NULL AS     content,
                       create_user
                FROM bytesailing_sale.contract c
-               WHERE c.buy_corporation_id = #{id}
+               WHERE c.status = 30
+                 and c.buy_corporation_id = #{id}
                  and c.tenant_id = #{tenantId}
                  and c.del_flag = 0)
               UNION
@@ -100,6 +103,7 @@
                       NULL AS amount,
                       `date`,
                       NULL AS contractCode,
+                      null as code,
                       30   AS type,
                       content,
                       create_user

+ 30 - 0
hx-form/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.fjhx</groupId>
+        <artifactId>bytesailing</artifactId>
+        <version>1.0</version>
+    </parent>
+
+    <artifactId>hx-form</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.fjhx</groupId>
+            <artifactId>hx-base</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fjhx</groupId>
+            <artifactId>hx-customer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fjhx</groupId>
+            <artifactId>hx-sale</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 32 - 0
hx-form/src/main/java/com/fjhx/form/controller/employee/EmployeeAnalysisController.java

@@ -0,0 +1,32 @@
+package com.fjhx.form.controller.employee;
+
+import com.fjhx.form.entity.dto.EmployeeAnalysisDto;
+import com.fjhx.form.service.employee.EmployeeAnalysisService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 员工分析 前端控制器
+ */
+@RestController
+@RequestMapping("/employeeAnalysis")
+public class EmployeeAnalysisController {
+
+    @Autowired
+    private EmployeeAnalysisService employeeAnalysisService;
+
+    /**
+     * 员工分析
+     *
+     * @return
+     */
+    @PostMapping("/info")
+    public Map<String, Object> info(@RequestBody EmployeeAnalysisDto dto) {
+        return employeeAnalysisService.info(dto);
+    }
+}

+ 30 - 0
hx-form/src/main/java/com/fjhx/form/entity/dto/EmployeeAnalysisDto.java

@@ -0,0 +1,30 @@
+package com.fjhx.form.entity.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 客户分析dto
+ */
+@Getter
+@Setter
+public class EmployeeAnalysisDto {
+
+    /**
+     * 用户id列表
+     */
+    private List<Long> userIds;
+
+    /**
+     * 开始时间
+     */
+    private String beginTime;
+
+    /**
+     * 结束时间
+     */
+    private String endTime;
+
+}

+ 38 - 0
hx-form/src/main/java/com/fjhx/form/mapper/employee/EmployeeAnalysisMapper.java

@@ -0,0 +1,38 @@
+package com.fjhx.form.mapper.employee;
+
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.math.BigDecimal;
+import java.util.Map;
+
+@Mapper
+public interface EmployeeAnalysisMapper {
+
+    /**
+     * 获取邮件信息
+     */
+    BigDecimal getMail(@Param("ew") IWrapper<Object> wrapper);
+
+    /**
+     * 获取报价单统计
+     */
+    Map<String, Object> getQuotationStatistics(@Param("ew") IWrapper<Object> wrapper);
+
+    /**
+     * 获取销售合同统计
+     */
+    Map<String, Object> getContractStatistics(@Param("ew") IWrapper<Object> wrapper);
+
+    /**
+     * 获取到账认领统计
+     */
+    Map<String, Object> getClaimStatistics(@Param("ew") IWrapper<Object> wrapper);
+
+    /**
+     * 获取采购金额
+     */
+    BigDecimal getPurchaseAmount(@Param("ew") IWrapper<Object> wrapper);
+
+}

+ 10 - 0
hx-form/src/main/java/com/fjhx/form/service/employee/EmployeeAnalysisService.java

@@ -0,0 +1,10 @@
+package com.fjhx.form.service.employee;
+
+import com.fjhx.form.entity.dto.EmployeeAnalysisDto;
+
+import java.util.Map;
+
+public interface EmployeeAnalysisService {
+
+    Map<String, Object> info(EmployeeAnalysisDto dto);
+}

+ 317 - 0
hx-form/src/main/java/com/fjhx/form/service/employee/impl/EmployeeAnalysisServiceImpl.java

@@ -0,0 +1,317 @@
+package com.fjhx.form.service.employee.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.customer.entity.customer.po.Customer;
+import com.fjhx.customer.service.customer.CustomerService;
+import com.fjhx.flow.entity.flow.po.FlowExample;
+import com.fjhx.flow.service.flow.FlowExampleService;
+import com.fjhx.form.entity.dto.EmployeeAnalysisDto;
+import com.fjhx.form.mapper.employee.EmployeeAnalysisMapper;
+import com.fjhx.form.service.employee.EmployeeAnalysisService;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.purchase.entity.pay.po.Pay;
+import com.fjhx.purchase.entity.purchase.po.Purchase;
+import com.fjhx.purchase.entity.subscribe.po.SubscribeDetail;
+import com.fjhx.purchase.service.pay.PayService;
+import com.fjhx.purchase.service.purchase.PurchaseService;
+import com.fjhx.purchase.service.subscribe.SubscribeDetailService;
+import com.fjhx.sale.entity.contract.po.Contract;
+import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.entity.documents.po.Documents;
+import com.fjhx.sale.entity.sale.po.SaleQuotation;
+import com.fjhx.sale.service.contract.ContractProductService;
+import com.fjhx.sale.service.contract.ContractService;
+import com.fjhx.sale.service.documents.DocumentsService;
+import com.fjhx.sale.service.sale.SaleQuotationService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class EmployeeAnalysisServiceImpl implements EmployeeAnalysisService {
+
+    @Autowired
+    private CustomerService customerService;
+    @Autowired
+    private SaleQuotationService saleQuotationService;
+    @Autowired
+    private ContractService contractService;
+    @Autowired
+    private ProductInfoService productInfoService;
+    @Autowired
+    private EmployeeAnalysisMapper employeeAnalysisMapper;
+    @Autowired
+    private FlowExampleService flowExampleService;
+    @Autowired
+    private DocumentsService documentsService;
+    @Autowired
+    private PurchaseService purchaseService;
+    @Autowired
+    private PayService payService;
+    @Autowired
+    private ContractProductService contractProductService;
+    @Autowired
+    private SubscribeDetailService subscribeDetailService;
+
+    /**
+     * 员工分析
+     *
+     * @return
+     */
+    @Override
+    public Map<String, Object> info(EmployeeAnalysisDto dto) {
+        //客户情况
+        Map<String, Object> customerSituation = getCustomerSituation(dto);
+        //产品情况
+        Map<String, Object> productSituation = getProductSituation(dto);
+        //往来邮件
+        Map<String, Object> commEmail = getCommEmail(dto);
+        //流程统计
+        Map<String, Object> flowStatistics = getFlowStatistics(dto);
+        //销售行为(存量客户)
+        Map<String, Object> saleSituation = getSaleSituation(dto);
+        //销售行为(增量客户)
+        Map<String, Object> saleAddSituation = getSaleAddSituation(dto);
+        //采购行为
+        Map<String, Object> purchaseStatistics = getPurchaseStatistics(dto);
+
+        //返回数据
+        Map<String, Object> data = new HashMap<>();
+        data.put("customerSituation", customerSituation);//客户情况
+        data.put("productSituation", productSituation);//产品情况
+        data.put("commMail", commEmail);//往来邮件
+        data.put("flowStatistics", flowStatistics);//流程统计
+        data.put("saleSituation", saleSituation);//销售行为新增统计
+        data.put("saleAddSituation", saleAddSituation);//销售行为新增统计
+        data.put("purchaseStatistics", purchaseStatistics);//采购行为统计
+        return data;
+    }
+
+    /**
+     * 客户情况
+     */
+    private Map<String, Object> getCustomerSituation(EmployeeAnalysisDto dto) {
+        Map<String, Object> customerSituation = new HashMap<>();
+        //客户存量
+        long customerCount = customerService.count(q -> q
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), Customer::getCreateTime, dto.getBeginTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Customer::getUserId, dto.getUserIds())
+        );
+        //客户新增
+        long customerAddCount = customerService.count(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Customer::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Customer::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Customer::getCreateUser, dto.getUserIds())
+        );
+        //报价单(客户数量)
+        List<SaleQuotation> saleQuotationList = saleQuotationService.list(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), SaleQuotation::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), SaleQuotation::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), SaleQuotation::getCreateUser, dto.getUserIds())
+                .groupBy(SaleQuotation::getBuyCorporationId)
+        );
+        int saleQuotationCustomerCount = saleQuotationList.size();
+        //成交合同(客户数量)
+        List<Contract> contractList = contractService.list(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Contract::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Contract::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Contract::getCreateUser, dto.getUserIds())
+                .groupBy(Contract::getBuyCorporationId)
+        );
+        int contractCustomerCount = contractList.size();
+        customerSituation.put("customerCount", customerCount);
+        customerSituation.put("customerAddCount", customerAddCount);
+        customerSituation.put("saleQuotationCustomerCount", saleQuotationCustomerCount);
+        customerSituation.put("contractCustomerCount", contractCustomerCount);
+        return customerSituation;
+    }
+
+    /**
+     * 产品情况
+     */
+    private Map<String, Object> getProductSituation(EmployeeAnalysisDto dto) {
+        Map<String, Object> productSituation = new HashMap<>();
+        //产品存量
+        long productCount = productInfoService.count(q -> q
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), ProductInfo::getCreateTime, dto.getBeginTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), ProductInfo::getCreateUser, dto.getUserIds())
+        );
+        //产品添加
+        long productAddCount = productInfoService.count(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), ProductInfo::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), ProductInfo::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), ProductInfo::getCreateUser, dto.getUserIds())
+        );
+        productSituation.put("productCount", productCount);
+        productSituation.put("productAddCount", productAddCount);
+        return productSituation;
+    }
+
+    /**
+     * 往来邮件
+     */
+    private Map<String, Object> getCommEmail(EmployeeAnalysisDto dto) {
+        Map<String, Object> commEmail = new HashMap<>();
+        DynamicDataSourceContextHolder.push(SourceConstant.MAIL);
+        //获取发件数
+        BigDecimal sentMailCount = employeeAnalysisMapper.getMail(IWrapper.getWrapper()
+                .eq("t1.folder_name", "Sent Messages")
+                .in("t2.user_id", dto.getUserIds())
+        );
+        //获取收件数
+        BigDecimal receiveMailCount = employeeAnalysisMapper.getMail(IWrapper.getWrapper()
+                .ne("t1.folder_name", "Sent Messages")
+                .in("t2.user_id", dto.getUserIds())
+        );
+        DynamicDataSourceContextHolder.poll();
+        commEmail.put("sentMailCount", sentMailCount);
+        commEmail.put("receiveMailCount", receiveMailCount);
+        return commEmail;
+    }
+
+    /**
+     * 流程统计
+     */
+    private Map<String, Object> getFlowStatistics(EmployeeAnalysisDto dto) {
+        Map<String, Object> flowStatistics = new HashMap<>();
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        long flowExampleCount = flowExampleService.count(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), FlowExample::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), FlowExample::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), FlowExample::getCreateUser, dto.getUserIds())
+        );
+        long waitFlowExampleCount = flowExampleService.count(q -> q
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), FlowExample::getHandleUserId, dto.getUserIds())
+                .eq(FlowExample::getStatus, 1)
+        );
+        DynamicDataSourceContextHolder.poll();
+        flowStatistics.put("flowExampleCount", flowExampleCount);
+        flowStatistics.put("waitFlowExampleCount", waitFlowExampleCount);
+        return flowStatistics;
+    }
+
+    /**
+     * 销售行为(存量客户)
+     */
+    private Map<String, Object> getSaleSituation(EmployeeAnalysisDto dto) {
+        Map<String, Object> saleAddSituation = new HashMap<>();
+        //报价统计(报价单)
+        DynamicDataSourceContextHolder.push(SourceConstant.SALE);
+        Map<String, Object> quotationAddStatistics = employeeAnalysisMapper.getQuotationStatistics(IWrapper.getWrapper()
+                .eq("status", 30)
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "sq.create_time", dto.getBeginTime())
+        );
+        //成交统计(销售合同)
+        Map<String, Object> contractAddStatistics = employeeAnalysisMapper.getContractStatistics(IWrapper.getWrapper()
+                .eq("status", 30)
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
+        );
+        //到账统计(到账认领)
+        Map<String, Object> claimAddStatistics = employeeAnalysisMapper.getClaimStatistics(IWrapper.getWrapper()
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "c2.user_id", dto.getUserIds())
+        );
+        DynamicDataSourceContextHolder.poll();
+        //单证数统计
+        long documentsCount = documentsService.count(q -> q
+                .lt(ObjectUtil.isNotEmpty(dto.getBeginTime()), Documents::getCreateTime, dto.getBeginTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Documents::getCreateUser, dto.getUserIds()));
+
+        saleAddSituation.put("quotationAddStatistics", quotationAddStatistics);
+        saleAddSituation.put("contractAddStatistics", contractAddStatistics);
+        saleAddSituation.put("claimAddStatistics", claimAddStatistics);
+        saleAddSituation.put("documentsCount", documentsCount);
+
+        return saleAddSituation;
+    }
+
+    /**
+     * 销售行为(增量客户)
+     */
+    private Map<String, Object> getSaleAddSituation(EmployeeAnalysisDto dto) {
+        Map<String, Object> saleAddSituation = new HashMap<>();
+        //报价统计(报价单)
+        DynamicDataSourceContextHolder.push(SourceConstant.SALE);
+        Map<String, Object> quotationAddStatistics = employeeAnalysisMapper.getQuotationStatistics(IWrapper.getWrapper()
+                .eq("status", 30)
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "sq.create_time", dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "sq.create_time", dto.getEndTime())
+        );
+        //成交统计(销售合同)
+        Map<String, Object> contractAddStatistics = employeeAnalysisMapper.getContractStatistics(IWrapper.getWrapper()
+                .eq("status", 30)
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "c.create_time", dto.getEndTime())
+        );
+        //到账统计(到账认领)
+        Map<String, Object> claimAddStatistics = employeeAnalysisMapper.getClaimStatistics(IWrapper.getWrapper()
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "c.create_time", dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "c.create_time", dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "c2.user_id", dto.getUserIds())
+        );
+        DynamicDataSourceContextHolder.poll();
+        //单证数统计
+        long documentsCount = documentsService.count(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Documents::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Documents::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Documents::getCreateUser, dto.getUserIds()));
+
+        saleAddSituation.put("quotationAddStatistics", quotationAddStatistics);
+        saleAddSituation.put("contractAddStatistics", contractAddStatistics);
+        saleAddSituation.put("claimAddStatistics", claimAddStatistics);
+        saleAddSituation.put("documentsCount", documentsCount);
+
+        return saleAddSituation;
+    }
+
+    /**
+     * 采购行为统计
+     */
+    private Map<String, Object> getPurchaseStatistics(EmployeeAnalysisDto dto) {
+        //待采购
+        Map<String, Object> waitPurchaseStatistics = new HashMap<>();
+        long contractProductCount = contractProductService.count(q -> q.gt(ContractProduct::getExpendQuantity, 0));
+        long subscribeDetailCount = subscribeDetailService.count(q -> q.eq(SubscribeDetail::getStatus, 15));
+        waitPurchaseStatistics.put("contractProductCount", contractProductCount);
+        waitPurchaseStatistics.put("subscribeDetailCount", subscribeDetailCount);
+        //采购订单
+        Map<String, Object> purchaseOrder = new HashMap<>();
+        //采购订单数
+        long purchaseCount = purchaseService.count(q -> q
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), Purchase::getCreateTime, dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), Purchase::getCreateTime, dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), Purchase::getCreateUser, dto.getUserIds())
+        );
+
+        DynamicDataSourceContextHolder.push(SourceConstant.PURCHASE);
+        //采购金额
+        BigDecimal purchaseAmount = employeeAnalysisMapper.getPurchaseAmount(IWrapper.getWrapper()
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "p.create_time", dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "p.create_time", dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "p.create_user", dto.getUserIds())
+        );
+        DynamicDataSourceContextHolder.poll();
+        //采购付款金额
+        BigDecimal purchasePayAmount = payService.getPurchasePayAmount(IWrapper.<Pay>getWrapper()
+                .ge(ObjectUtil.isNotEmpty(dto.getBeginTime()), "pay.create_time", dto.getBeginTime())
+                .le(ObjectUtil.isNotEmpty(dto.getEndTime()), "pay.create_time", dto.getEndTime())
+                .in(ObjectUtil.isNotEmpty(dto.getUserIds()), "pay.create_user", dto.getUserIds()));
+        purchaseOrder.put("purchaseCount", purchaseCount);
+        purchaseOrder.put("purchaseAmount", purchaseAmount);
+        purchaseOrder.put("purchasePayAmount", purchasePayAmount);
+        //返回数据
+        Map<String, Object> purchaseStatistics = new HashMap<>();
+        purchaseStatistics.put("purchaseOrder", purchaseOrder);
+        purchaseStatistics.put("waitPurchaseStatistics", waitPurchaseStatistics);
+        return purchaseStatistics;
+    }
+
+}

+ 48 - 0
hx-form/src/main/resources/mapper/EmployeeAnalysisMapper.xml

@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.form.mapper.employee.EmployeeAnalysisMapper">
+
+    <select id="getMail" resultType="java.math.BigDecimal">
+        SELECT sum(a.count)
+        FROM (SELECT count(1) AS `count`
+              FROM enterprise_message t1
+                       JOIN enterprise_mailbox t2
+                            ON t1.mailbox_id = t2.id
+                  ${ew.customSqlSegment}
+              UNION
+              SELECT
+                  count ( 1 ) AS `count`
+              FROM
+                  personal_message t1
+                  JOIN personal_mailbox t2
+              ON t1.mailbox_id = t2.id
+                  ${ew.customSqlSegment}) AS a
+    </select>
+    <select id="getQuotationStatistics" resultType="java.util.Map">
+        SELECT if(count(1) is null, 0, count(1))                                 AS `count`,
+               if(sum(sq.amount * sq.rate) is null, 0, sum(sq.amount * sq.rate)) AS sumAmount
+        FROM sale_quotation sq
+            ${ew.customSqlSegment}
+    </select>
+    <select id="getContractStatistics" resultType="java.util.Map">
+        SELECT if(count(1) is null, 0, count(1))                             AS `count`,
+               if(sum(c.amount * c.rate) is null, 0, sum(c.amount * c.rate)) AS sumAmount
+        FROM contract c
+            ${ew.customSqlSegment}
+    </select>
+    <select id="getClaimStatistics" resultType="java.util.Map">
+        SELECT if(count(1) is null, 0, count(1))                                 AS `count`,
+               if(sum(c.amount * arw.rate) is null, 0, sum(c.amount * arw.rate)) AS sumAmount
+        FROM claim c
+                 left join claim_contract cc on cc.claim_id = c.id
+                 LEFT JOIN contract c1 on cc.contract_id = c1.id
+                 left join bytesailing_account.account_running_water arw on c.business_id = arw.id
+                 left join bytesailing_customer.customer c2 on c1.buy_corporation_id = c2.id
+            ${ew.customSqlSegment}
+    </select>
+    <select id="getPurchaseAmount" resultType="java.math.BigDecimal">
+        SELECT SUM(p.amount)
+        FROM purchase p
+            ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 6 - 1
hx-jxst/src/main/java/com/fjhx/jxst/flow/SalesContractFlow.java

@@ -2,12 +2,12 @@ package com.fjhx.jxst.flow;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.jxst.entity.sales.dto.SalesContractDto;
 import com.fjhx.jxst.entity.sales.po.SalesContractDetails;
 import com.fjhx.jxst.service.sales.SalesContractDetailsService;
 import com.fjhx.jxst.service.sales.SalesContractService;
 import com.fjhx.mes.entity.work.dto.WorkOrderDto;
-import com.fjhx.mes.entity.work.po.WorkOrder;
 import com.fjhx.mes.service.work.WorkOrderService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -52,4 +52,9 @@ public class SalesContractFlow extends FlowDelegate {
             workOrderService.add(workOrder);
         }
     }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+
+    }
 }

+ 1 - 1
hx-mail/src/main/java/com/fjhx/mail/listener/LoginEventListeners.java

@@ -43,7 +43,7 @@ public class LoginEventListeners {
                     MailHttpUtil.abroadUserLogin(userId);
                     num = 3;
                 } catch (Exception e) {
-                    log.error("同步邮件服务用户登录失败", e);
+                    log.error("同步海外邮件服务用户登录失败", e);
                     num++;
                 }
             }

+ 1 - 2
hx-oa/src/main/java/com/fjhx/oa/service/daily/impl/DailyReportDetailsServiceImpl.java

@@ -46,8 +46,7 @@ public class DailyReportDetailsServiceImpl extends ServiceImpl<DailyReportDetail
         msgMap.put("businessId", id);
         msgMap.put("msg", "您有未读的日报");
         for (DailyReportDetails dailyReportDetails : list) {
-            // WebSocketServer.sendInfo(dailyReportDetails.getRecipientId(), 1, msgMap);
-
+//            WebSocketServer.sendInfo(dailyReportDetails.getRecipientId(), 1, msgMap);
             WebSocketPush.byUser(
                     PushTypeEnum.MESSAGE,
                     dailyReportDetails.getRecipientId(),

+ 2 - 5
hx-oa/src/main/java/com/fjhx/oa/service/daily/impl/DailyReportServiceImpl.java

@@ -122,8 +122,7 @@ public class DailyReportServiceImpl extends ServiceImpl<DailyReportMapper, Daily
         msgMap.put("businessId", dailyReportDto.getId());
         msgMap.put("msg", String.format("%s发布了新日志", userName));
         for (DailyReportDetails dailyReportDetails : dailyReportDetailsList) {
-            // WebSocketServer.sendInfo(dailyReportDetails.getRecipientId(), 1, msgMap);
-
+//            WebSocketServer.sendInfo(dailyReportDetails.getRecipientId(), 1, msgMap);
             WebSocketPush.byUser(
                     PushTypeEnum.MESSAGE,
                     dailyReportDetails.getRecipientId(),
@@ -183,8 +182,7 @@ public class DailyReportServiceImpl extends ServiceImpl<DailyReportMapper, Daily
         msgMap.put("businessId", id);
         msgMap.put("msg", String.format("%s给你分享了日报", username));
         for (Long toUserId : toUserIdList) {
-            // WebSocketServer.sendInfo(toUserId, 1, msgMap);
-
+//            WebSocketServer.sendInfo(toUserId, 1, msgMap);
             WebSocketPush.byUser(
                     PushTypeEnum.MESSAGE,
                     toUserId,
@@ -192,7 +190,6 @@ public class DailyReportServiceImpl extends ServiceImpl<DailyReportMapper, Daily
                     PushBusinessTypeEnum.SHARE_DAILY.getType(),
                     msgMap
             );
-
         }
     }
 

+ 71 - 9
hx-purchase/src/main/java/com/fjhx/purchase/flow/PayFlow.java

@@ -2,6 +2,7 @@ package com.fjhx.purchase.flow;
 
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.account.entity.account.enums.PaymentStatusEnum;
@@ -9,8 +10,11 @@ import com.fjhx.account.entity.account.enums.PaymentTypeEnum;
 import com.fjhx.account.entity.account.po.AccountPayment;
 import com.fjhx.account.service.account.AccountPaymentService;
 import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.enums.FlowStatusEnum1;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.file.utils.ObsFileUtil;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.pay.enums.PayStatusEnum;
 import com.fjhx.purchase.entity.pay.po.Pay;
 import com.fjhx.purchase.entity.pay.po.PayDetail;
@@ -18,8 +22,12 @@ import com.fjhx.purchase.entity.purchase.po.Purchase;
 import com.fjhx.purchase.service.pay.PayDetailService;
 import com.fjhx.purchase.service.pay.PayService;
 import com.fjhx.purchase.service.purchase.PurchaseService;
+import com.ruoyi.common.core.domain.BasePo;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -51,6 +59,8 @@ public class PayFlow extends FlowDelegate {
 
     @Autowired
     private PurchaseService purchaseService;
+    @Autowired
+    private ISysUserService userService;
 
     @Override
     public String getFlowKey() {
@@ -59,7 +69,8 @@ public class PayFlow extends FlowDelegate {
 
     /**
      * 发起流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param submitData 采购付款数据
      * @return
      */
@@ -67,23 +78,49 @@ public class PayFlow extends FlowDelegate {
     public Long start(Long flowId, JSONObject submitData) {
         Pay pay = submitData.toJavaObject(Pay.class);
 
+        //调用公共代码
+        pay = commStart(pay, 0);
+
+        return pay.getId();
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private Pay commStart(Pay pay, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(pay.getId(), "采购付款id不能为空");
+        }
+
         pay.setStatus(PayStatusEnum.UNDER_REVIEW.getKey());
-        payService.save(pay);
+        pay.setCurrency("CNY");//默认币种人民币
+        payService.saveOrUpdate(pay);
 
         List<PayDetail> payDetailList = pay.getPayDetailList();
         if (CollectionUtils.isNotEmpty(payDetailList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                payDetailService.editLinked(payDetailList, PayDetail::getPayId, pay.getId());
+            }
+
             payDetailList.forEach(item -> item.setPayId(pay.getId()));
-            payDetailService.saveBatch(payDetailList);
+            payDetailService.saveOrUpdateBatch(payDetailList);
         }
 
-        ObsFileUtil.saveFile(pay.getFileList(), pay.getId());
-
-        return pay.getId();
+        if (opType == 1) {
+            ObsFileUtil.editFile(pay.getFileList(), pay.getId());
+        } else {
+            ObsFileUtil.saveFile(pay.getFileList(), pay.getId());
+        }
+        return pay;
     }
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
@@ -105,7 +142,13 @@ public class PayFlow extends FlowDelegate {
         payment.setAccountManagementId(pay.getAccountManagementId());
         payment.setBusinessId(pay.getId());
         payment.setCurrency(pay.getCurrency());
-        payment.setDepartmentId(SecurityUtils.getDeptId());
+
+        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
+        SysUser sysUser = userService.getOne(IWrapper.<SysUser>getWrapper().eq(SysUser::getUserId, pay.getCreateUser()));
+        DynamicDataSourceContextHolder.poll();
+        if (ObjectUtils.isNotEmpty(sysUser)) {
+            payment.setDepartmentId(sysUser.getDeptId());
+        }
         // todo 暂时写死人民币
         payment.setPaymentRemark(pay.getRemark());
         payment.setType(PaymentTypeEnum.REJECT.getKey());
@@ -114,13 +157,14 @@ public class PayFlow extends FlowDelegate {
         payment.setAmount(pay.getAmount());
         payment.setIncomeAmount(pay.getAmount());
         payment.setName(pay.getName());
-        payment.setCreateUser(pay.getCreateUser());
+        payment.setDataUser(pay.getCreateUser());
         payment.setBusinessManagementId(pay.getAccountManagementId());
         payment.setOpeningBank(pay.getOpeningBank());
         payment.setBusinessCurrency(pay.getCurrency());
         payment.setAccountOpening(pay.getAccountOpening());
         payment.setInterbankNumber(pay.getInterbankNumber());
         payment.setPaymentMethod(pay.getPayType());
+        payment.setApplyForTime(pay.getCreateTime());//申请时间
         accountPaymentService.save(payment);
 
         // 修改合同付款状态
@@ -128,6 +172,24 @@ public class PayFlow extends FlowDelegate {
 
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            Pay pay = submitData.toJavaObject(Pay.class);
+            commStart(pay, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            payService.update(q -> q
+                    .eq(Pay::getId, businessId)
+                    .set(Pay::getStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
 
     /**
      * 修改合同付款状态

+ 57 - 10
hx-purchase/src/main/java/com/fjhx/purchase/flow/RefundFlow.java

@@ -6,13 +6,19 @@ import com.baomidou.dynamic.datasource.annotation.DS;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.common.constant.SourceConstant;
+import com.fjhx.common.enums.FlowStatusEnum1;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.pay.enums.PayStatusEnum;
 import com.fjhx.purchase.entity.refund.po.Refund;
 import com.fjhx.purchase.entity.refund.po.RefundDetail;
 import com.fjhx.purchase.service.refund.RefundDetailService;
 import com.fjhx.purchase.service.refund.RefundService;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -20,6 +26,7 @@ import java.util.List;
 
 /**
  * 退货流程
+ *
  * @Author:caozj
  * @DATE:2023/4/3 17:38
  */
@@ -27,6 +34,11 @@ import java.util.List;
 @Component
 public class RefundFlow extends FlowDelegate {
 
+    @Autowired
+    private RefundService refundService;
+    @Autowired
+    private RefundDetailService refundDetailService;
+
     @Override
     public String getFlowKey() {
         return "refund_flow";
@@ -35,30 +47,47 @@ public class RefundFlow extends FlowDelegate {
 
     /**
      * 发起流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param submitData 数据
      * @return
      */
     @Override
     public Long start(Long flowId, JSONObject submitData) {
-        RefundService refundService = SpringUtil.getBean(RefundService.class);
-        RefundDetailService refundDetailService = SpringUtil.getBean(RefundDetailService.class);
         Refund refund = submitData.toJavaObject(Refund.class);
+        refund = commStart(refund, 0);
+        return refund.getId();
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private Refund commStart(Refund refund, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(refund.getId(), "退款id不能为空");
+        }
         refund.setStatus(PayStatusEnum.UNDER_REVIEW.getKey());
-        refundService.save(refund);
+        refundService.saveOrUpdate(refund);
         List<RefundDetail> refundDetailList = refund.getRefundDetailList();
-        if(CollectionUtils.isNotEmpty(refundDetailList)){
-            for(RefundDetail s : refundDetailList){
+        if (CollectionUtils.isNotEmpty(refundDetailList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                refundDetailService.editLinked(refundDetailList, RefundDetail::getRefundId, refund.getId());
+            }
+            for (RefundDetail s : refundDetailList) {
                 s.setRefundId(refund.getId());
             }
-            refundDetailService.saveBatch(refundDetailList);
+            refundDetailService.saveOrUpdateBatch(refundDetailList);
         }
-        return refund.getId();
+        return refund;
     }
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
@@ -67,7 +96,7 @@ public class RefundFlow extends FlowDelegate {
         RefundService refundService = SpringUtil.getBean(RefundService.class);
         //通过业务ID查询申购数据
         Refund refund = refundService.getById(businessId);
-        if(ObjectUtils.isEmpty(refund)){
+        if (ObjectUtils.isEmpty(refund)) {
             throw new ServiceException("退款单不存在");
         }
         //修改采购状态为审批通过
@@ -75,4 +104,22 @@ public class RefundFlow extends FlowDelegate {
         refund.setApprovedDate(new Date());
         refundService.updateById(refund);
     }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            Refund refund = submitData.toJavaObject(Refund.class);
+            commStart(refund, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            refundService.update(q -> q
+                    .eq(Refund::getId, businessId)
+                    .set(Refund::getStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
 }

+ 51 - 7
hx-purchase/src/main/java/com/fjhx/purchase/flow/SalesReturnFlow.java

@@ -8,8 +8,11 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.sales.enums.SalesReturnDetailStatusEnum;
 import com.fjhx.purchase.entity.sales.enums.SalesReturnStatusEnum;
 import com.fjhx.purchase.entity.sales.po.SalesReturn;
@@ -21,7 +24,9 @@ import com.fjhx.wms.entity.stock.po.StockWait;
 import com.fjhx.wms.entity.stock.po.StockWaitDetails;
 import com.fjhx.wms.service.stock.StockWaitDetailsService;
 import com.fjhx.wms.service.stock.StockWaitService;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
@@ -45,6 +50,11 @@ public class SalesReturnFlow extends FlowDelegate {
     @Autowired
     private CodingRuleService codingRuleService;
 
+    @Autowired
+    private SalesReturnService salesReturnService;
+    @Autowired
+    private SalesReturnDetailService salesReturnDetailService;
+
     @Override
     public String getFlowKey() {
         return "sales_return_flow";
@@ -60,20 +70,36 @@ public class SalesReturnFlow extends FlowDelegate {
      */
     @Override
     public Long start(Long flowId, JSONObject submitData) {
-        SalesReturnService salesReturnService = SpringUtil.getBean(SalesReturnService.class);
-        SalesReturnDetailService salesReturnDetailService = SpringUtil.getBean(SalesReturnDetailService.class);
+
         SalesReturn salesReturn = submitData.toJavaObject(SalesReturn.class);
-//        salesReturn.setCode(CodeEnum.SALES_RETURN.getCode());
-        salesReturn.setCode(codingRuleService.createCode(CodingRuleEnum.SALES_RETURN.getKey(),null));
-        salesReturnService.save(salesReturn);
+        salesReturn.setCode(codingRuleService.createCode(CodingRuleEnum.SALES_RETURN.getKey(), null));
+        salesReturn = commStart(salesReturn, 0);
+
+        return salesReturn.getId();
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private SalesReturn commStart(SalesReturn salesReturn, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(salesReturn.getId(), "退货id不能为空");
+        }
+        salesReturnService.saveOrUpdate(salesReturn);
         List<SalesReturnDetail> salesReturnDetailList = salesReturn.getSalesReturnDetailList();
         if (CollectionUtils.isNotEmpty(salesReturnDetailList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                salesReturnDetailService.editLinked(salesReturnDetailList, SalesReturnDetail::getSalesReturnId, salesReturn.getId());
+            }
             for (SalesReturnDetail s : salesReturnDetailList) {
                 s.setSalesReturnId(salesReturn.getId());
             }
-            salesReturnDetailService.saveBatch(salesReturnDetailList);
+            salesReturnDetailService.saveOrUpdateBatch(salesReturnDetailList);
         }
-        return salesReturn.getId();
+        return salesReturn;
     }
 
     /**
@@ -123,4 +149,22 @@ public class SalesReturnFlow extends FlowDelegate {
         stockWaitDetailsService.saveBatch(stockWaitDetailsList);
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            SalesReturn salesReturn = submitData.toJavaObject(SalesReturn.class);
+            commStart(salesReturn, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            salesReturnService.update(q -> q
+                    .eq(SalesReturn::getId, businessId)
+                    .set(SalesReturn::getStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
 }

+ 51 - 9
hx-purchase/src/main/java/com/fjhx/purchase/flow/SubscribeFlow.java

@@ -6,8 +6,11 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.subscribe.enums.SubscribeDetailStatusEnum;
 import com.fjhx.purchase.entity.subscribe.enums.SubscribeStatusEnum;
 import com.fjhx.purchase.entity.subscribe.po.Subscribe;
@@ -56,23 +59,19 @@ public class SubscribeFlow extends FlowDelegate {
     public Long start(Long flowId, JSONObject submitData) {
 
         Subscribe subscribe = submitData.toJavaObject(Subscribe.class);
-        subscribe.setCode(codingRuleService.createCode(CodingRuleEnum.SUBSCRIBE.getKey(),null));
-        subscribe.setSubcribeStatus(SubscribeStatusEnum.UNDER_REVIEW.getKey());
+        subscribe.setCode(codingRuleService.createCode(CodingRuleEnum.SUBSCRIBE.getKey(), null));
         subscribe.setFlowId(flowId);
-        subscribeService.save(subscribe);
 
-        List<SubscribeDetail> SubscribeDetails = subscribe.getSubscribeDetailList();
-        if(CollectionUtils.isNotEmpty(SubscribeDetails)){
-            SubscribeDetails.forEach(item -> item.setSubscribeId(subscribe.getId()));
-            subscribeDetailService.saveBatch(SubscribeDetails);
-        }
+        //调用公共代码
+        subscribe = commStart(subscribe, 0);
 
         return subscribe.getId();
     }
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
@@ -100,4 +99,47 @@ public class SubscribeFlow extends FlowDelegate {
 
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            // 获取提交数据
+            Subscribe subscribe = submitData.toJavaObject(Subscribe.class);
+            commStart(subscribe, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            subscribeService.update(q -> q
+                    .eq(Subscribe::getId, businessId)
+                    .set(Subscribe::getSubcribeStatus, FlowStatusEnum1.REJECT.getKey())//20为驳回
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private Subscribe commStart(Subscribe subscribe, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(subscribe.getId(), "申购id不能为空");
+        }
+        subscribe.setSubcribeStatus(SubscribeStatusEnum.UNDER_REVIEW.getKey());
+        subscribeService.saveOrUpdate(subscribe);
+
+        List<SubscribeDetail> SubscribeDetails = subscribe.getSubscribeDetailList();
+        if (CollectionUtils.isNotEmpty(SubscribeDetails)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                subscribeDetailService.editLinked(SubscribeDetails, SubscribeDetail::getSubscribeId, subscribe.getId());
+            }
+            SubscribeDetails.forEach(item -> item.setSubscribeId(subscribe.getId()));
+            subscribeDetailService.saveOrUpdateBatch(SubscribeDetails);
+        }
+        return subscribe;
+    }
 }

+ 9 - 2
hx-purchase/src/main/java/com/fjhx/purchase/flow/SubscribeFlowByWdly.java

@@ -8,6 +8,7 @@ import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
 import com.fjhx.common.service.coding.CodingRuleService;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.subscribe.enums.SubscribeStatusEnum;
 import com.fjhx.purchase.entity.subscribe.po.Subscribe;
 import com.fjhx.purchase.entity.subscribe.po.SubscribeDetail;
@@ -67,12 +68,18 @@ public class SubscribeFlowByWdly extends FlowDelegate {
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
     @Override
     public void end(Long flowId, Long businessId, JSONObject submitData) {
-       subscribeFlow.end(flowId,businessId,submitData);
+        subscribeFlow.end(flowId, businessId, submitData);
+    }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+
     }
 }

+ 9 - 2
hx-purchase/src/main/java/com/fjhx/purchase/mapper/pay/PayMapper.java

@@ -1,19 +1,21 @@
 package com.fjhx.purchase.mapper.pay;
 
-import com.fjhx.purchase.entity.pay.po.Pay;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.purchase.entity.pay.po.Pay;
 import com.fjhx.purchase.entity.pay.vo.PayVo;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.math.BigDecimal;
+
 
 /**
  * <p>
  * 采购付款 Mapper 接口
  * </p>
  *
- * @author 
+ * @author
  * @since 2023-04-13
  */
 public interface PayMapper extends BaseMapper<Pay> {
@@ -23,4 +25,9 @@ public interface PayMapper extends BaseMapper<Pay> {
      */
     Page<PayVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<Pay> wrapper);
 
+    /**
+     * 获取采购付款金额
+     */
+    BigDecimal getPurchasePayAmount(@Param("ew") IWrapper<Pay> wrapper);
+
 }

+ 13 - 5
hx-purchase/src/main/java/com/fjhx/purchase/service/pay/PayService.java

@@ -1,12 +1,14 @@
 package com.fjhx.purchase.service.pay;
 
-import com.fjhx.purchase.entity.pay.po.Pay;
-import com.ruoyi.common.core.service.BaseService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fjhx.purchase.entity.pay.vo.PayVo;
-import com.fjhx.purchase.entity.pay.dto.PaySelectDto;
 import com.fjhx.purchase.entity.pay.dto.PayDto;
+import com.fjhx.purchase.entity.pay.dto.PaySelectDto;
+import com.fjhx.purchase.entity.pay.po.Pay;
+import com.fjhx.purchase.entity.pay.vo.PayVo;
+import com.ruoyi.common.core.service.BaseService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
 
+import java.math.BigDecimal;
 import java.util.Map;
 
 
@@ -47,8 +49,14 @@ public interface PayService extends BaseService<Pay> {
 
     /**
      * 采购付款统计
+     *
      * @param dto
      * @return
      */
-    Map<String,Object> payStatistics(PaySelectDto dto);
+    Map<String, Object> payStatistics(PaySelectDto dto);
+
+    /**
+     * 获取采购付款金额
+     */
+    BigDecimal getPurchasePayAmount(IWrapper<Pay> wrapper);
 }

+ 7 - 0
hx-purchase/src/main/java/com/fjhx/purchase/service/pay/impl/PayServiceImpl.java

@@ -256,5 +256,12 @@ public class PayServiceImpl extends ServiceImpl<PayMapper, Pay> implements PaySe
         return map;
     }
 
+    /**
+     * 获取采购付款金额
+     */
+    @Override
+    public BigDecimal getPurchasePayAmount(IWrapper<Pay> wrapper) {
+        return baseMapper.getPurchasePayAmount(wrapper);
+    }
 
 }

+ 9 - 2
hx-purchase/src/main/resources/mapper/pay/PayMapper.xml

@@ -2,10 +2,17 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fjhx.purchase.mapper.pay.PayMapper">
     <select id="getPage" resultType="com.fjhx.purchase.entity.pay.vo.PayVo">
-        select
-           *
+        select *
         from pay p
             ${ew.customSqlSegment}
     </select>
 
+    <select id="getPurchasePayAmount" resultType="java.math.BigDecimal">
+        SELECT sum(arw.amount * arw.rate)
+        FROM pay pay
+                 JOIN bytesailing_account.account_payment ap ON ap.business_id = pay.id
+                 JOIN bytesailing_account.account_running_water arw ON arw.business_id = ap.id
+            ${ew.customSqlSegment}
+    </select>
+
 </mapper>

+ 10 - 9
hx-purchase/src/main/resources/mapper/purchase/PurchaseMapper.xml

@@ -2,15 +2,16 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.fjhx.purchase.mapper.purchase.PurchaseMapper">
     <select id="getPage" resultType="com.fjhx.purchase.entity.purchase.vo.PurchaseVo">
-        select
-            p.*,
-            (
-                select IFNULL(SUM(IFNULL(money,0)*IFNULL(rate,0)),0) from pay_detail t1
-                LEFT JOIN pay t2 ON t1.pay_id = t2.id
-                WHERE t2.`status`  &gt;= 30 AND t2.`status` &lt; 88
-                  AND t1.purchase_id = p.id
-            )AS paySumAmount,
-            ( SELECT `code` FROM `bytesailing_sale`.contract WHERE id = p.data_resource_id ) AS contractCode
+        select p.*,
+               (SELECT IFNULL(SUM(IFNULL(money, 0) * IFNULL(arw.rate, 0)), 0)
+                FROM pay_detail t1
+                         LEFT JOIN pay t2 ON t1.pay_id = t2.id
+                         JOIN bytesailing_account.account_payment ap ON ap.business_id = t2.id
+                         JOIN bytesailing_account.account_running_water arw ON arw.business_id = ap.id
+                WHERE t2.`status` &gt;= 30
+                  AND t2.`status` &lt; 88
+                  AND t1.purchase_id = p.id)                                                  AS paySumAmount,
+               (SELECT `code` FROM `bytesailing_sale`.contract WHERE id = p.data_resource_id) AS contractCode
         from purchase p
             ${ew.customSqlSegment}
     </select>

+ 35 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesController.java

@@ -0,0 +1,35 @@
+package com.fjhx.sale.controller.after;
+
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.fjhx.sale.service.after.AfterSalesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 售后管理 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@RestController
+@RequestMapping("/afterSales")
+public class AfterSalesController {
+
+    @Autowired
+    private AfterSalesService afterSalesService;
+
+    /**
+     * 售后管理新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody AfterSalesDto afterSalesDto) {
+        afterSalesService.add(afterSalesDto);
+    }
+
+}

+ 70 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesDetailController.java

@@ -0,0 +1,70 @@
+package com.fjhx.sale.controller.after;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 售后明细 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@RestController
+@RequestMapping("/afterSalesDetail")
+public class AfterSalesDetailController {
+
+    @Autowired
+    private AfterSalesDetailService afterSalesDetailService;
+
+    /**
+     * 售后明细分页
+     */
+    @PostMapping("/page")
+    public Page<AfterSalesDetailVo> page(@RequestBody AfterSalesDetailSelectDto dto) {
+        return afterSalesDetailService.getPage(dto);
+    }
+
+    /**
+     * 售后管理编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody AfterSalesDetailDto afterSalesDetailDto) {
+        afterSalesDetailService.edit(afterSalesDetailDto);
+    }
+
+    /**
+     * 售后退货
+     */
+    @PostMapping("/salesReturn")
+    public void salesReturn(@RequestBody AfterSalesDetailDto afterSalesDetailDto) {
+        afterSalesDetailService.salesReturn(afterSalesDetailDto);
+    }
+
+    /**
+     * 售后换货
+     */
+    @PostMapping("/salesReplace")
+    public void salesReplace(@RequestBody AfterSalesDetailDto afterSalesDetailDto) {
+        afterSalesDetailService.salesReplace(afterSalesDetailDto);
+    }
+
+    /**
+     * 发起采购
+     */
+    @PostMapping("/initPurchase")
+    public void initPurchase(@RequestBody AfterSalesDetailDto afterSalesDetailDto) {
+        afterSalesDetailService.initPurchase(afterSalesDetailDto);
+    }
+
+}

+ 46 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/after/AfterSalesRecordsController.java

@@ -0,0 +1,46 @@
+package com.fjhx.sale.controller.after;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordSelectDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.fjhx.sale.service.after.AfterSalesRecordsService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 售后跟进记录 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@RestController
+@RequestMapping("/afterSalesRecords")
+public class AfterSalesRecordsController {
+
+    @Autowired
+    private AfterSalesRecordsService afterSalesRecordsService;
+
+    /**
+     * 售后跟进记录分页
+     */
+    @PostMapping("/page")
+    public Page<AfterSalesRecordsVo> page(@RequestBody AfterSalesRecordSelectDto dto) {
+        return afterSalesRecordsService.getPage(dto);
+    }
+
+    /**
+     * 售后跟进记录新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody AfterSalesRecordsDto afterSalesRecordDto) {
+        afterSalesRecordsService.add(afterSalesRecordDto);
+    }
+
+}

+ 9 - 0
hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractController.java

@@ -255,4 +255,13 @@ public class ContractController {
         return contractService.getAccountRunningWaterByContractId(dto.getId());
     }
 
+    /**
+     * 根据合同id获取合同的资金流水信息
+     */
+    @PostMapping("/111")
+    public void tt111(@RequestBody ContractDto dto) {
+        dto.setCreateUser(133333333333333L);
+        contractService.save(dto);
+    }
+
 }

+ 23 - 5
hx-sale/src/main/java/com/fjhx/sale/controller/contract/ContractProductController.java

@@ -1,13 +1,13 @@
 package com.fjhx.sale.controller.contract;
 
-import org.springframework.web.bind.annotation.*;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fjhx.sale.entity.contract.vo.ContractProductVo;
-import com.fjhx.sale.entity.contract.dto.ContractProductSelectDto;
 import com.fjhx.sale.entity.contract.dto.ContractProductDto;
-import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.fjhx.sale.entity.contract.dto.ContractProductSelectDto;
+import com.fjhx.sale.entity.contract.vo.ContractProductVo;
 import com.fjhx.sale.service.contract.ContractProductService;
+import com.ruoyi.common.core.domain.BaseSelectDto;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -34,13 +34,23 @@ public class ContractProductController {
     public Page<ContractProductVo> page(@RequestBody ContractProductSelectDto dto) {
         return contractProductService.getPage(dto);
     }
+
+    /**
+     * 采购交接单-产品分页
+     */
+    @PostMapping("/page1")
+    public Page<ContractProductVo> page1(@RequestBody ContractProductSelectDto dto) {
+        return contractProductService.getPage1(dto);
+    }
+
     /**
      * 根据合同ID和客户ID查询未包装的产品
      */
     @GetMapping("/getNoPackContractProductById")
-    public List<ContractProductVo> getNoPackContractProductById(@RequestParam("customerId")String customerId, @RequestParam("contractIds")String contractIds) {
+    public List<ContractProductVo> getNoPackContractProductById(@RequestParam("customerId") String customerId, @RequestParam("contractIds") String contractIds) {
         return contractProductService.getNoPackContractProductById(customerId, contractIds);
     }
+
     /**
      * 外销合同-产品ID集合查询产品
      */
@@ -50,6 +60,14 @@ public class ContractProductController {
     }
 
     /**
+     * 外销合同-合同id集合查询产品
+     */
+    @PostMapping("/getListDetailByContractId")
+    public List<ContractProductVo> getListDetailByContractId(@RequestBody List<Long> contractIds) {
+        return contractProductService.getListDetailByContractId(contractIds);
+    }
+
+    /**
      * 外销合同-产品明细
      */
     @PostMapping("/detail")

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后明细新增编辑入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesDetailDto extends AfterSalesDetail {
+
+}

+ 32 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDetailSelectDto.java

@@ -0,0 +1,32 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后明细列表查询入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesDetailSelectDto extends BaseSelectDto {
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 售后类型
+     */
+    private String type;
+
+    /**
+     * 售后状态
+     */
+    private String status;
+
+}

+ 25 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesDto.java

@@ -0,0 +1,25 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 售后管理新增编辑入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesDto extends AfterSales {
+
+    /**
+     * 售后明细列表
+     */
+    List<AfterSalesDetail> afterSalesDetailList;
+
+}

+ 22 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordSelectDto.java

@@ -0,0 +1,22 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后跟进记录列表查询入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesRecordSelectDto extends BaseSelectDto {
+
+    /**
+     * 售后明细id
+     */
+    private Long afterSalesDetailId;
+
+}

+ 25 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesRecordsDto.java

@@ -0,0 +1,25 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.fjhx.file.entity.ObsFile;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 售后跟进记录新增编辑入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesRecordsDto extends AfterSalesRecords {
+
+    /**
+     * 附件列表
+     */
+    private List<ObsFile> fileList;
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/dto/AfterSalesSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后管理列表查询入参实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesSelectDto extends BaseSelectDto {
+
+}

+ 46 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSales.java

@@ -0,0 +1,46 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 售后管理
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+@TableName("after_sales")
+public class AfterSales extends BasePo {
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+
+    /**
+     * 销售合同id
+     */
+    private String contractIds;
+
+    /**
+     * 售后类型 字典
+     */
+    private String type;
+
+    /**
+     * 说明
+     */
+    private String remark;
+
+    /**
+     * 售后状态 0进行中1关闭
+     */
+    private Integer status;
+
+}

+ 68 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesDetail.java

@@ -0,0 +1,68 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * <p>
+ * 售后明细
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+@TableName("after_sales_detail")
+public class AfterSalesDetail extends BasePo {
+
+    /**
+     * 售后id
+     */
+    private Long afterSalesId;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 售后数量
+     */
+    private BigDecimal quantity;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 销售合同明细id
+     */
+    private Long contractProductId;
+
+    /**
+     * 商品单价
+     */
+    private BigDecimal price;
+
+    /**
+     * 商品金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 售后状态
+     */
+    private Integer status;
+
+    /**
+     * 合同id
+     */
+    private Long contractId;
+
+}

+ 43 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/po/AfterSalesRecords.java

@@ -0,0 +1,43 @@
+package com.fjhx.sale.entity.after.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 售后跟进记录
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+@TableName("after_sales_records")
+public class AfterSalesRecords extends BasePo {
+
+    /**
+     * 售后明细id
+     */
+    private Long afterSalesDetailId;
+
+    /**
+     * 销售合同id
+     */
+    private Date followUpTime;
+
+    /**
+     * 跟进用户id
+     */
+    private Long followUpUserId;
+
+    /**
+     * 说明
+     */
+    private String remark;
+
+}

+ 58 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesDetailVo.java

@@ -0,0 +1,58 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后明细列表查询返回值实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesDetailVo extends AfterSalesDetail {
+
+    /**
+     * 客户id
+     */
+    private Long customerId;
+    /**
+     * 客户名称
+     */
+    private String customerName;
+    /**
+     * 合同id
+     */
+    private Long contractId;
+    /**
+     * 合同编号
+     */
+    private String contractCode;
+    /**
+     * 售后类型
+     */
+    private String type;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 产品名称
+     */
+    private String productName;
+
+    /**
+     * 产品规格
+     */
+    private String productSpec;
+
+    /**
+     * 产品规格
+     */
+    private String productUnit;
+
+}

+ 22 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesRecordsVo.java

@@ -0,0 +1,22 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后跟进记录列表查询返回值实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesRecordsVo extends AfterSalesRecords {
+
+    /**
+     * 跟进用户名称
+     */
+    private String followUpUserName;
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/after/vo/AfterSalesVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.entity.after.vo;
+
+import com.fjhx.sale.entity.after.po.AfterSales;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 售后管理列表查询返回值实体
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Getter
+@Setter
+public class AfterSalesVo extends AfterSales {
+
+}

+ 9 - 3
hx-sale/src/main/java/com/fjhx/sale/entity/claim/po/ClaimContract.java

@@ -1,13 +1,13 @@
 package com.fjhx.sale.entity.claim.po;
 
 import com.baomidou.mybatisplus.annotation.TableField;
-import com.ruoyi.common.core.domain.BasePo;
 import com.baomidou.mybatisplus.annotation.TableName;
-import java.math.BigDecimal;
-
+import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.math.BigDecimal;
+
 /**
  * <p>
  * 到账认领-合同关联表
@@ -50,4 +50,10 @@ public class ClaimContract extends BasePo {
      */
     @TableField(exist = false)
     private Long businessId;
+
+    /**
+     * 汇率
+     */
+    @TableField(exist = false)
+    private BigDecimal rate;
 }

+ 5 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractPdfInfoVo.java

@@ -175,6 +175,11 @@ public class ContractPdfInfoVo {
      */
     private String beneficiaryAddress;
 
+    /**
+     * 税号 预留字段
+     */
+    private String taxNumber;
+
     @Getter
     @Setter
     public static class ProductInfo {

+ 12 - 1
hx-sale/src/main/java/com/fjhx/sale/entity/contract/vo/ContractVo.java

@@ -1,6 +1,7 @@
 package com.fjhx.sale.entity.contract.vo;
 
 import com.fjhx.file.entity.FileInfoVo;
+import com.fjhx.sale.entity.claim.po.ClaimContract;
 import com.fjhx.sale.entity.contract.po.Contract;
 import com.fjhx.sale.entity.contract.po.ContractProduct;
 import com.fjhx.sale.entity.contract.po.ContractProject;
@@ -104,7 +105,7 @@ public class ContractVo extends Contract {
     /**
      * 客户标签(存在多个用逗号隔开)
      */
-    private String  tag;
+    private String tag;
 
     /**
      * 客户名称
@@ -144,5 +145,15 @@ public class ContractVo extends Contract {
      */
     private String contractTypeVal;
 
+    /**
+     * 税号 预留字段
+     */
+    private String taxNumber;
+
+    /**
+     * 到账信息列表
+     */
+    private List<ClaimContract> claimContractList;
+
 }
 

+ 5 - 0
hx-sale/src/main/java/com/fjhx/sale/entity/quotation/vo/QuotationProductVo.java

@@ -14,4 +14,9 @@ import lombok.Setter;
 @Setter
 public class QuotationProductVo extends QuotationProduct {
 
+    /**
+     * 产品单位
+     */
+    private String productUnit;
+
 }

+ 2 - 2
hx-sale/src/main/java/com/fjhx/sale/entity/sale/vo/SaleQuotationVo.java

@@ -1,7 +1,7 @@
 package com.fjhx.sale.entity.sale.vo;
 
 import com.fjhx.sale.entity.quotation.po.QuotationPay;
-import com.fjhx.sale.entity.quotation.po.QuotationProduct;
+import com.fjhx.sale.entity.quotation.vo.QuotationProductVo;
 import com.fjhx.sale.entity.sale.po.SaleQuotation;
 import lombok.Getter;
 import lombok.Setter;
@@ -32,7 +32,7 @@ public class SaleQuotationVo extends SaleQuotation {
     /**
      * 商品-报价单关联表信息
      */
-    private List<QuotationProduct> quotationProductList;
+    private List<QuotationProductVo> quotationProductList;
 
     /**
      *报价 -收费项目表

+ 126 - 26
hx-sale/src/main/java/com/fjhx/sale/flow/ContractFlow.java

@@ -1,16 +1,21 @@
 package com.fjhx.sale.flow;
 
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.area.utils.CustomizeAreaUtil;
+import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
-import com.fjhx.common.enums.FlowStatusEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.common.utils.ExchangeRateUtil;
 import com.fjhx.file.utils.ObsFileUtil;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.core.FlowThreadLocalUtil;
+import com.fjhx.flow.enums.FlowStatusEnum;
+import com.fjhx.flow.enums.HandleTypeEnum;
 import com.fjhx.sale.entity.contract.dto.ContractDto;
 import com.fjhx.sale.entity.contract.po.Contract;
 import com.fjhx.sale.entity.contract.po.ContractProduct;
@@ -20,6 +25,7 @@ import com.fjhx.sale.service.contract.ContractProductService;
 import com.fjhx.sale.service.contract.ContractProjectService;
 import com.fjhx.sale.service.contract.ContractService;
 import com.fjhx.sale.service.contract.ContractShipmentService;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -68,9 +74,13 @@ public class ContractFlow extends FlowDelegate {
     @Override
     public Long start(Long flowId, JSONObject submitData) {
         ContractDto contract = submitData.toJavaObject(ContractDto.class);
-        if(StringUtils.isEmpty(contract.getCurrency())){
+        if (StringUtils.isEmpty(contract.getCurrency())) {
             throw new ServiceException("币种不能为空");
         }
+
+        //赋值合同号
+        contract.setCode(codingRuleService.createCode(CodingRuleEnum.CONTRACT.getKey(), contract.getBuyCorporationId()));
+
         // 保存合同产品
         List<ContractProduct> contractProductList = contract.getContractProductList();
 
@@ -79,7 +89,8 @@ public class ContractFlow extends FlowDelegate {
             contractProductList.forEach(item -> item.setExpendQuantity(item.getQuantity()));
         }
 
-        return start(contract);
+        contract = commStart(contract, 0);
+        return contract.getId();
     }
 
     /**
@@ -100,66 +111,155 @@ public class ContractFlow extends FlowDelegate {
         }
 
         // 修改采购状态为审批通过
-        contract.setStatus(FlowStatusEnum.PASS.getKey());
+        contract.setStatus(FlowStatusEnum1.PASS.getKey());
         contract.setApprovedDate(new Date());
         contractService.updateById(contract);
     }
 
-    public Long start(ContractDto contract) {
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            reStart();
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            reject();
+        }
+
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    public ContractDto commStart(ContractDto contract, Integer opType) {
+        DynamicDataSourceContextHolder.push(SourceConstant.SALE);
 
-        long contractId = IdWorker.getId();
+//        long contractId = IdWorker.getId();
 
         // 赋值城市省份信息
         CustomizeAreaUtil.setAreaId(contract);
 
-        contract.setId(contractId);
-        contract.setCode(codingRuleService.createCode(CodingRuleEnum.CONTRACT.getKey(), contract.getBuyCorporationId()));
+//        contract.setId(contractId);
+
         contract.setUserName(SecurityUtils.getUsername());
-        contract.setStatus(FlowStatusEnum.UNDER_REVIEW.getKey());
+        contract.setStatus(FlowStatusEnum1.UNDER_REVIEW.getKey());
         contract.setBuyCityId(contract.getCityId());
         contract.setBuyCountryId(contract.getCountryId());
         contract.setBuyProvinceId(contract.getProvinceId());
         contract.setRate(ExchangeRateUtil.getCnyToCodeRate(contract.getCurrency()));
-        contractService.save(contract);
+        contractService.saveOrUpdate(contract);
 
         // 保存合同产品
         List<ContractProduct> contractProductList = contract.getContractProductList();
         if (CollectionUtils.isNotEmpty(contractProductList)) {
+
+            if (opType == 1) {
+                //先删除被删除的产品
+                contractProductService.editLinked(contractProductList, ContractProduct::getContractId, contract.getId());
+            }
             for (ContractProduct c : contractProductList) {
-                c.setId(IdWorker.getId());
-                c.setContractId(contractId);
-                ObsFileUtil.saveFile(c.getFileList(), c.getId());
+//                c.setId(IdWorker.getId());
+                c.setContractId(contract.getId());
+//                ObsFileUtil.saveFile(c.getFileList(), c.getId());
             }
-            contractProductService.saveBatch(contractProductList);
+            contractProductService.saveOrUpdateBatch(contractProductList);
         }
 
         // 保存收费项目
         List<ContractProject> contractProjectList = contract.getContractProjectList();
         if (CollectionUtils.isNotEmpty(contractProjectList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                contractProjectService.editLinked(contractProjectList, ContractProject::getContractId, contract.getId());
+            }
+
             for (ContractProject c : contractProjectList) {
-                c.setId(IdWorker.getId());
-                c.setContractId(contractId);
+//                c.setId(IdWorker.getId());
+                c.setContractId(contract.getId());
             }
-            contractProjectService.saveBatch(contractProjectList);
+            contractProjectService.saveOrUpdateBatch(contractProjectList);
         }
 
         // 保存自定义出货
         List<ContractShipment> contractShipmentList = contract.getContractShipmentList();
         if (CollectionUtils.isNotEmpty(contractShipmentList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                contractShipmentService.editLinked(contractShipmentList, ContractShipment::getContractId, contract.getId());
+            }
             for (ContractShipment c : contractShipmentList) {
-                c.setId(IdWorker.getId());
-                c.setContractId(contractId);
+//                c.setId(IdWorker.getId());
+                c.setContractId(contract.getId());
             }
-            contractShipmentService.saveBatch(contractShipmentList);
+            contractShipmentService.saveOrUpdateBatch(contractShipmentList);
         }
 
-        // 交接单附件列表
-        ObsFileUtil.saveFile(contract.getFileList(), contractId, 1);
+        if (opType == 1) {
+            //重新发起编辑
+
+            // 交接单附件列表
+            ObsFileUtil.editFile(contract.getFileList(), contract.getId(), 1);
+
+            // 包装指示附件列表
+            ObsFileUtil.editFile(contract.getPackageFileList(), contract.getId(), 2);
+        } else {
+            //普通提交新增
+
+            // 交接单附件列表
+            ObsFileUtil.saveFile(contract.getFileList(), contract.getId(), 1);
+
+            // 包装指示附件列表
+            ObsFileUtil.saveFile(contract.getPackageFileList(), contract.getId(), 2);
+        }
+        DynamicDataSourceContextHolder.poll();
 
-        // 包装指示附件列表
-        ObsFileUtil.saveFile(contract.getPackageFileList(), contractId, 2);
 
-        return contractId;
+        return contract;
+    }
+
+    /**
+     * 重新发起
+     */
+    public void reStart() {
+        JSONObject submitData = FlowThreadLocalUtil.getCurrentData();
+        ContractDto contract = submitData.toJavaObject(ContractDto.class);
+        reStart1(contract);
+    }
+
+    public void reStart1(ContractDto contract) {
+        Long contractId = contract.getId();
+        Assert.notEmpty(contractId, "合同id不能为空");
+
+        if (StringUtils.isEmpty(contract.getCurrency())) {
+            throw new ServiceException("币种不能为空");
+        }
+        // 保存合同产品
+        List<ContractProduct> contractProductList = contract.getContractProductList();
+
+        // 赋值待处理数量
+        if (CollectionUtils.isNotEmpty(contractProductList)) {
+            contractProductList.forEach(item -> item.setExpendQuantity(item.getQuantity()));
+        }
+
+        //调用公共代码
+        commStart(contract, 1);
+    }
+
+    /**
+     * 驳回方法
+     */
+    public void reject() {
+        if (HandleTypeEnum.REJECT.equals(FlowThreadLocalUtil.getHandleTypeEnum())) {
+            contractService.update(q -> q
+                    .eq(Contract::getId, FlowThreadLocalUtil.getBusinessId())
+                    .set(Contract::getStatus, FlowStatusEnum1.REJECT.getKey())//20为驳回
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
     }
 
 }

+ 115 - 31
hx-sale/src/main/java/com/fjhx/sale/flow/ContractUpdateFlow.java

@@ -3,22 +3,31 @@ package com.fjhx.sale.flow;
 import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
-import com.fjhx.common.enums.FlowStatusEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.sale.entity.contract.dto.ContractDto;
 import com.fjhx.sale.entity.contract.po.Contract;
 import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.entity.contract.po.ContractProject;
+import com.fjhx.sale.entity.contract.po.ContractShipment;
 import com.fjhx.sale.service.contract.ContractProductService;
 import com.fjhx.sale.service.contract.ContractService;
 import com.ruoyi.common.core.domain.BaseIdPo;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -53,6 +62,87 @@ public class ContractUpdateFlow extends FlowDelegate {
 
         ContractDto contract = submitData.toJavaObject(ContractDto.class);
 
+        Assert.notEmpty(contract.getOldContractId(), "原合同id不能为空");
+
+        //变更 用原来合同号加后缀
+        Contract oldContract = contractService.getById(contract.getOldContractId());
+        Assert.notEmpty(oldContract, "查询不到原合同信息");
+        String code = oldContract.getCode();
+        Matcher matcher = Pattern.compile(".*\\((.*?)\\)$").matcher(code);
+        int index = 2;
+        if (matcher.find()) {
+            index = (Integer.parseInt(matcher.group(1)) + 1);
+            code = code.substring(0, code.lastIndexOf("("));
+        }
+        contract.setCode(code + "(" + index + ")");
+
+        //变更合同提前操作数据
+        contract = opDate(contract);
+
+        //清空id 方便后面生成新合同
+        contract.setId(null);
+        // 清空合同产品id
+        List<ContractProduct> contractProductList = contract.getContractProductList();
+        if (CollectionUtils.isNotEmpty(contractProductList)) {
+            contractProductList.forEach(item -> item.setId(null));
+        }
+        // 清空收费项目id
+        List<ContractProject> contractProjectList = contract.getContractProjectList();
+        if (CollectionUtils.isNotEmpty(contractProjectList)) {
+            contractProjectList.forEach(item -> item.setId(null));
+        }
+        // 清空自定义出货id
+        List<ContractShipment> contractShipmentList = contract.getContractShipmentList();
+        if (CollectionUtils.isNotEmpty(contractShipmentList)) {
+            contractShipmentList.forEach(item -> item.setId(null));
+        }
+
+        contract = contractFlow.commStart(contract, 0);
+        return contract.getId();
+    }
+
+    /**
+     * 结束流程
+     *
+     * @param flowId     流程ID
+     * @param businessId 业务ID
+     * @param submitData 数据
+     */
+    @Override
+    public void end(Long flowId, Long businessId, JSONObject submitData) {
+
+        contractFlow.end(flowId, businessId, submitData);
+
+        // 通过业务id查询合同数据
+        Contract contract = contractService.getById(businessId);
+
+        // 原合同改为作废状态
+        Long oldContractId = contract.getOldContractId();
+        Contract oldContract = contractService.getById(oldContractId);
+        if (oldContract == null) {
+            throw new ServiceException("原合同不存在");
+        }
+        oldContract.setStatus(FlowStatusEnum1.UPDATE.getKey());
+        oldContract.setIsChange("1");
+        contractService.updateById(oldContract);
+    }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            reStart(submitData);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            reject(businessId);
+        }
+    }
+
+    /**
+     * 变更合同时执行的数据操作公共代码
+     */
+    private ContractDto opDate(ContractDto contract) {
         // 原合同id不能为空
         Long oldContractId = contract.getOldContractId();
         if (oldContractId == null) {
@@ -72,52 +162,46 @@ public class ContractUpdateFlow extends FlowDelegate {
 
             Map<Long, ContractProduct> contractProductMap = contractProductList
                     .stream()
-                    .peek(item -> {
-                        if (item.getId() == null) {
-                            throw new ServiceException("合同产品id不能为空");
-                        }
-                    })
+                    .filter(item -> ObjectUtil.isNotEmpty(item.getId()))
                     .collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
 
 
             for (ContractProduct item : list) {
                 ContractProduct contractProduct = contractProductMap.get(item.getId());
-                if (contractProduct == null) {
-                    throw new ServiceException("产品id为" + item.getId() + "未上传");
+                if (ObjectUtil.isNotEmpty(contractProduct)) {
+                    BigDecimal expendQuantity = item.getExpendQuantity().subtract(item.getQuantity().subtract(contractProduct.getQuantity()));
+                    contractProduct.setExpendQuantity(expendQuantity);
                 }
-                BigDecimal expendQuantity = item.getExpendQuantity().subtract(item.getQuantity().subtract(contractProduct.getQuantity()));
-                contractProduct.setExpendQuantity(expendQuantity);
             }
 
         }
-
-        return contractFlow.start(contract);
+        return contract;
     }
 
     /**
-     * 结束流程
-     *
-     * @param flowId     流程ID
-     * @param businessId 业务ID
-     * @param submitData 数据
+     * 重新发起
      */
-    @Override
-    public void end(Long flowId, Long businessId, JSONObject submitData) {
+    private void reStart(JSONObject submitData) {
+        ContractDto contract = submitData.toJavaObject(ContractDto.class);
 
-        contractFlow.end(flowId, businessId, submitData);
+        Assert.notEmpty(contract.getId(), "合同id不能为空");
 
-        // 通过业务id查询合同数据
-        Contract contract = contractService.getById(businessId);
+        //变更合同需要提前操作数据
+        contract = opDate(contract);
 
-        // 原合同改为作废状态
-        Long oldContractId = contract.getOldContractId();
-        Contract oldContract = contractService.getById(oldContractId);
-        if (oldContract == null) {
-            throw new ServiceException("原合同不存在");
-        }
-        oldContract.setStatus(FlowStatusEnum.UPDATE.getKey());
-        oldContract.setIsChange("1");
-        contractService.updateById(oldContract);
+        contractFlow.reStart1(contract);
+    }
+
+    /**
+     * 驳回
+     */
+    private void reject(Long businessId) {
+        contractService.update(q -> q
+                .eq(Contract::getId, businessId)
+                .set(Contract::getStatus, FlowStatusEnum1.REJECT.getKey())//20为驳回
+                .set(BasePo::getUpdateTime, new Date())
+                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+        );
     }
 
 }

+ 7 - 1
hx-sale/src/main/java/com/fjhx/sale/flow/EhsdPurchaseFlow.java

@@ -13,6 +13,7 @@ import com.fjhx.common.enums.CodingRuleEnum;
 import com.fjhx.common.service.coding.CodingRuleService;
 import com.fjhx.file.utils.ObsFileUtil;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseDataResourceEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseStatusEnum;
 import com.fjhx.sale.entity.contract.po.ContractProduct;
@@ -168,7 +169,7 @@ public class EhsdPurchaseFlow extends FlowDelegate {
         if(CollectionUtils.isNotEmpty(upContractProduct)){//扣减销售合同数量
             contractProductService.updateBatchById(upContractProduct);
         }
-        if(CollectionUtils.isNotEmpty(upSampleProduct)){//扣减样品单数量
+        if (CollectionUtils.isNotEmpty(upSampleProduct)) {//扣减样品单数量
             sampleProductService.updateBatchById(upSampleProduct);
         }
         //修改采购状态为审批通过
@@ -177,4 +178,9 @@ public class EhsdPurchaseFlow extends FlowDelegate {
         purchaseService.updateById(purchase);
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+
+    }
+
 }

+ 84 - 38
hx-sale/src/main/java/com/fjhx/sale/flow/PurchaseFlow.java

@@ -8,9 +8,12 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
 import com.fjhx.flow.core.FlowThreadLocalUtil;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.flow.enums.HandleTypeEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseDataResourceEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseDetailStatusEnum;
@@ -85,45 +88,13 @@ public class PurchaseFlow extends FlowDelegate {
     public Long start(Long flowId, JSONObject submitData) {
         DynamicDataSourceContextHolder.push(SourceConstant.PURCHASE);
         PurchaseVo purchase = submitData.toJavaObject(PurchaseVo.class);
-//        purchase.setCode(CodeEnum.PURCHASE.getCode());
         purchase.setCode(codingRuleService.createCode(CodingRuleEnum.PURCHASE.getKey(), null));
-        purchase.setPurchaseStatus(PurchaseStatusEnum.UNDER_REVIEW.getKey());
         purchase.setFlowId(flowId);
-        purchaseService.save(purchase);
-        List<PurchaseDetail> purchaseDetailList = purchase.getPurchaseDetailList();
-        if (CollectionUtils.isNotEmpty(purchaseDetailList)) {
-            for (PurchaseDetail s : purchaseDetailList) {
-                s.setPurchaseId(purchase.getId());
-            }
-            purchaseDetailService.saveBatch(purchaseDetailList);
-            //修改申购明细的采购状态
-            for (PurchaseDetail purchaseDetail : purchaseDetailList) {
-                //如果来源是申购
-                if (ObjectUtils.isEmpty(purchaseDetail.getDataResource())) {
-                    //计算已经采购的数量
-                    List<PurchaseDetail> purchaseDetails = purchaseDetailService.list(q -> q
-                            .eq(PurchaseDetail::getSubscribeDetailId, purchaseDetail.getSubscribeDetailId())
-                    );
-                    BigDecimal pdCount = purchaseDetails.stream().map(PurchaseDetail::getCount).reduce(BigDecimal.ZERO, BigDecimal::add);
-                    SubscribeDetail subscribeDetail = subscribeDetailService.getById(purchaseDetail.getSubscribeDetailId());
-                    if (pdCount.compareTo(subscribeDetail.getCount()) >= 0) {
-                        //修改为已采购
-                        subscribeDetail.setStatus(SubscribeDetailStatusEnum.PURCHASED.getKey());
-                    } else {
-                        //修改为部分采购
-                        subscribeDetail.setStatus(SubscribeDetailStatusEnum.LITT_PAID_AMOUNT.getKey());
-                    }
-                    subscribeDetailService.updateById(subscribeDetail);
-                }
-            }
 
-        }
-        //保存其他费用信息
-        List<PurchaseOtherFee> otherFeeList = purchase.getOtherFeeList();
-        if (ObjectUtils.isNotEmpty(otherFeeList)) {
-            otherFeeList.forEach(item -> item.setPurchaseId(purchase.getId()));
-            purchaseOtherFeeService.saveBatch(otherFeeList);
-        }
+        //调用公共代码
+        purchase = commStart(purchase, 0);
+
+
         DynamicDataSourceContextHolder.poll();
         return purchase.getId();
     }
@@ -187,6 +158,81 @@ public class PurchaseFlow extends FlowDelegate {
                 .lambda().eq(PurchaseDetail::getPurchaseId, purchase.getId()));
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            // 获取提交数据
+            DynamicDataSourceContextHolder.push(SourceConstant.PURCHASE);
+            PurchaseVo purchase = submitData.toJavaObject(PurchaseVo.class);
+            commStart(purchase, 1);
+            DynamicDataSourceContextHolder.poll();
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            reject();
+        }
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private PurchaseVo commStart(PurchaseVo purchase, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(purchase.getId(), "采购id不能为空");
+        }
+        purchase.setPurchaseStatus(PurchaseStatusEnum.UNDER_REVIEW.getKey());
+        purchaseService.saveOrUpdate(purchase);
+        List<PurchaseDetail> purchaseDetailList = purchase.getPurchaseDetailList();
+        if (CollectionUtils.isNotEmpty(purchaseDetailList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                purchaseDetailService.editLinked(purchaseDetailList, PurchaseDetail::getPurchaseId, purchase.getId());
+            }
+            for (PurchaseDetail s : purchaseDetailList) {
+                s.setPurchaseId(purchase.getId());
+            }
+            purchaseDetailService.saveOrUpdateBatch(purchaseDetailList);
+
+            //修改申购明细的采购状态
+            for (PurchaseDetail purchaseDetail : purchaseDetailList) {
+                //如果来源是申购
+                if (ObjectUtils.isEmpty(purchaseDetail.getDataResource())) {
+                    //计算已经采购的数量
+                    List<PurchaseDetail> purchaseDetails = purchaseDetailService.list(q -> q
+                            .eq(PurchaseDetail::getSubscribeDetailId, purchaseDetail.getSubscribeDetailId())
+                    );
+                    BigDecimal pdCount = purchaseDetails.stream().map(PurchaseDetail::getCount).reduce(BigDecimal.ZERO, BigDecimal::add);
+                    SubscribeDetail subscribeDetail = subscribeDetailService.getById(purchaseDetail.getSubscribeDetailId());
+                    if (pdCount.compareTo(subscribeDetail.getCount()) >= 0) {
+                        //修改为已采购
+                        subscribeDetail.setStatus(SubscribeDetailStatusEnum.PURCHASED.getKey());
+                    } else {
+                        //修改为部分采购
+                        subscribeDetail.setStatus(SubscribeDetailStatusEnum.LITT_PAID_AMOUNT.getKey());
+                    }
+                    subscribeDetailService.updateById(subscribeDetail);
+                }
+            }
+
+        }
+
+        //保存其他费用信息
+        List<PurchaseOtherFee> otherFeeList = purchase.getOtherFeeList();
+        if (ObjectUtils.isNotEmpty(otherFeeList)) {
+            if (opType == 1) {
+                //先删除被删除的产品
+                purchaseOtherFeeService.editLinked(otherFeeList, PurchaseOtherFee::getPurchaseId, purchase.getId());
+            }
+            otherFeeList.forEach(item -> item.setPurchaseId(purchase.getId()));
+            purchaseOtherFeeService.saveOrUpdateBatch(otherFeeList);
+        }
+
+        return purchase;
+    }
+
     /**
      * 驳回方法
      */
@@ -194,8 +240,8 @@ public class PurchaseFlow extends FlowDelegate {
         if (HandleTypeEnum.REJECT.equals(FlowThreadLocalUtil.getHandleTypeEnum())) {
             purchaseService.update(q -> q
                     .eq(Purchase::getId, FlowThreadLocalUtil.getBusinessId())
-                    .set(Purchase::getPurchaseStatus, 20)
-                    .set(Purchase::getUpdateTime, new Date())
+                    .set(Purchase::getPurchaseStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
                     .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
             );
         }

+ 6 - 0
hx-sale/src/main/java/com/fjhx/sale/flow/PurchaseFlowByWdly.java

@@ -10,6 +10,7 @@ import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
 import com.fjhx.common.service.coding.CodingRuleService;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseDataResourceEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseDetailStatusEnum;
 import com.fjhx.purchase.entity.purchase.enums.PurchaseStatusEnum;
@@ -199,4 +200,9 @@ public class PurchaseFlowByWdly extends FlowDelegate {
                 .lambda().eq(PurchaseDetail::getPurchaseId, purchase.getId()));
     }
 
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+
+    }
+
 }

+ 75 - 27
hx-sale/src/main/java/com/fjhx/sale/flow/SaleQuotationFlow.java

@@ -8,8 +8,11 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.area.utils.CustomizeAreaUtil;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.sale.entity.quotation.po.QuotationPay;
 import com.fjhx.sale.entity.quotation.po.QuotationProduct;
 import com.fjhx.sale.entity.sale.dto.SaleQuotationDto;
@@ -18,10 +21,13 @@ import com.fjhx.sale.enums.SaleQuotationEnum;
 import com.fjhx.sale.service.quotation.QuotationPayService;
 import com.fjhx.sale.service.quotation.QuotationProductService;
 import com.fjhx.sale.service.sale.SaleQuotationService;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -32,6 +38,12 @@ import java.util.List;
 public class SaleQuotationFlow extends FlowDelegate {
     @Autowired
     private CodingRuleService codingRuleService;
+    @Autowired
+    private SaleQuotationService saleQuotationService;
+    @Autowired
+    private QuotationPayService quotationPayService;
+    @Autowired
+    private QuotationProductService quotationProductService;
 
     @Override
     public String getFlowKey() {
@@ -40,45 +52,25 @@ public class SaleQuotationFlow extends FlowDelegate {
 
     /**
      * 发起流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param submitData 采购付款数据
      * @return
      */
     @Override
     public Long start(Long flowId, JSONObject submitData) {
-        SaleQuotationService saleQuotationService = SpringUtil.getBean(SaleQuotationService.class);
-        QuotationPayService quotationPayService = SpringUtil.getBean(QuotationPayService.class);
-        QuotationProductService quotationProductService = SpringUtil.getBean(QuotationProductService.class);
         SaleQuotationDto saleQuotation = submitData.toJavaObject(SaleQuotationDto.class);
-        //赋值城市省份信息
-        CustomizeAreaUtil.setAreaId(saleQuotation);
-        saleQuotation.setBuyCityId(saleQuotation.getCityId());
-        saleQuotation.setBuyCountryId(saleQuotation.getCountryId());
-        saleQuotation.setBuyProvinceId(saleQuotation.getProvinceId());
         //添加报价编码
-        saleQuotation.setCode(codingRuleService.createCode(CodingRuleEnum.SALE_QUOTATION.getKey(),saleQuotation.getBuyCorporationId()));
-//        saleQuotation.setCode(CodeEnum.SALE_QUOTATION.getCode());
-        //添加报价状态
-        saleQuotation.setStatus(SaleQuotationEnum.UNDER_REVIEW.getKey());
-        //添加报价单信息
-        saleQuotationService.save(saleQuotation);
-        List<QuotationProduct> quotationProductList = saleQuotation.getQuotationProductList();
-        if(CollectionUtils.isNotEmpty(quotationProductList)){//保存报价产品信息
-            quotationProductList.forEach(quotationProduct -> quotationProduct.setSaleQuotationId(saleQuotation.getId()));
-            quotationProductService.saveBatch(quotationProductList);
-        }
-        List<QuotationPay> quotationPayList = saleQuotation.getQuotationPayList();
-        if(CollectionUtils.isNotEmpty(quotationPayList)){//保存报价项目信息
-           quotationPayList.forEach(quotationPay -> quotationPay.setSaleQuotationId(saleQuotation.getId()));
-            quotationPayService.saveBatch(quotationPayList);
-        }
+        saleQuotation.setCode(codingRuleService.createCode(CodingRuleEnum.SALE_QUOTATION.getKey(), saleQuotation.getBuyCorporationId()));
+        saleQuotation = commStart(saleQuotation, 0);
 
         return saleQuotation.getId();
     }
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
@@ -87,11 +79,67 @@ public class SaleQuotationFlow extends FlowDelegate {
         SaleQuotationService saleQuotationService = SpringUtil.getBean(SaleQuotationService.class);
         //通过业务ID查询合同数据
         SaleQuotation contract = saleQuotationService.getById(businessId);
-        if(ObjectUtils.isEmpty(contract)){
+        if (ObjectUtils.isEmpty(contract)) {
             throw new ServiceException("报价单不存在");
         }
         //修改采购状态为审批通过
         contract.setStatus(SaleQuotationEnum.PASS.getKey());
         saleQuotationService.updateById(contract);
     }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            SaleQuotationDto saleQuotation = submitData.toJavaObject(SaleQuotationDto.class);
+            Assert.notEmpty(saleQuotation.getId(), "报价单id不能为空");
+            commStart(saleQuotation, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            saleQuotationService.update(q -> q
+                    .eq(SaleQuotation::getId, businessId)
+                    .set(SaleQuotation::getStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private SaleQuotationDto commStart(SaleQuotationDto saleQuotation, Integer opType) {
+        //赋值城市省份信息
+        CustomizeAreaUtil.setAreaId(saleQuotation);
+        saleQuotation.setBuyCityId(saleQuotation.getCityId());
+        saleQuotation.setBuyCountryId(saleQuotation.getCountryId());
+        saleQuotation.setBuyProvinceId(saleQuotation.getProvinceId());
+
+        //添加报价状态
+        saleQuotation.setStatus(SaleQuotationEnum.UNDER_REVIEW.getKey());
+        //添加报价单信息
+        saleQuotationService.saveOrUpdate(saleQuotation);
+        List<QuotationProduct> quotationProductList = saleQuotation.getQuotationProductList();
+        if (CollectionUtils.isNotEmpty(quotationProductList)) {//保存报价产品信息
+            if (opType == 1) {
+                //先删除被删除的产品
+                quotationProductService.editLinked(quotationProductList, QuotationProduct::getSaleQuotationId, saleQuotation.getId());
+            }
+            quotationProductList.forEach(quotationProduct -> quotationProduct.setSaleQuotationId(saleQuotation.getId()));
+            quotationProductService.saveOrUpdateBatch(quotationProductList);
+        }
+        List<QuotationPay> quotationPayList = saleQuotation.getQuotationPayList();
+        if (CollectionUtils.isNotEmpty(quotationPayList)) {//保存报价项目信息
+            if (opType == 1) {
+                //先删除被删除的产品
+                quotationPayService.editLinked(quotationPayList, QuotationPay::getSaleQuotationId, saleQuotation.getId());
+            }
+            quotationPayList.forEach(quotationPay -> quotationPay.setSaleQuotationId(saleQuotation.getId()));
+            quotationPayService.saveOrUpdateBatch(quotationPayList);
+        }
+        return saleQuotation;
+    }
 }

+ 10 - 5
hx-sale/src/main/java/com/fjhx/sale/flow/SampleFlow.java

@@ -10,7 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.area.utils.CustomizeAreaUtil;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
-import com.fjhx.common.enums.FlowStatusEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
 import com.fjhx.file.utils.ObsFileUtil;
 import com.fjhx.flow.core.FlowDelegate;
@@ -72,8 +72,8 @@ public class SampleFlow extends FlowDelegate {
         sample.setBuyCountryId(sample.getCountryId());
         sample.setBuyProvinceId(sample.getProvinceId());
 //        sample.setCode(CodeEnum.SAMPLE_CODE.getCode());
-        sample.setCode(codingRuleService.createCode(CodingRuleEnum.SAMPLE.getKey(),sample.getBuyCorporationId()));
-        sample.setStatus(FlowStatusEnum.UNDER_REVIEW.getKey());
+        sample.setCode(codingRuleService.createCode(CodingRuleEnum.SAMPLE.getKey(), sample.getBuyCorporationId()));
+        sample.setStatus(FlowStatusEnum1.UNDER_REVIEW.getKey());
         sample.setUserName(SecurityUtils.getUsername());
 
         sampleService.save(sample);
@@ -120,12 +120,17 @@ public class SampleFlow extends FlowDelegate {
         SampleService sampleService = SpringUtil.getBean(SampleService.class);
         //通过业务ID查询样品单数据
         Sample sample = sampleService.getById(businessId);
-        if(ObjectUtils.isEmpty(sample)){
+        if (ObjectUtils.isEmpty(sample)) {
             throw new ServiceException("样品单不存在");
         }
         //修改样品单状态为审批通过
-        sample.setStatus(FlowStatusEnum.PASS.getKey());
+        sample.setStatus(FlowStatusEnum1.PASS.getKey());
         sample.setApprovedDate(new Date());
         sampleService.updateById(sample);
     }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, com.fjhx.flow.enums.FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+
+    }
 }

+ 85 - 31
hx-sale/src/main/java/com/fjhx/sale/flow/ServiceContractFlow.java

@@ -8,8 +8,11 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.fjhx.area.utils.CustomizeAreaUtil;
 import com.fjhx.common.constant.SourceConstant;
 import com.fjhx.common.enums.CodingRuleEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.coding.CodingRuleService;
+import com.fjhx.common.utils.Assert;
 import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.enums.FlowStatusEnum;
 import com.fjhx.sale.entity.serviceContract.dto.ServiceContractDto;
 import com.fjhx.sale.entity.serviceContract.po.ServiceContract;
 import com.fjhx.sale.entity.serviceContract.po.ServiceContractPay;
@@ -18,10 +21,13 @@ import com.fjhx.sale.enums.ServiceContractEnum;
 import com.fjhx.sale.service.serviceContract.ServiceContractPayService;
 import com.fjhx.sale.service.serviceContract.ServiceContractProductService;
 import com.fjhx.sale.service.serviceContract.ServiceContractService;
+import com.ruoyi.common.core.domain.BasePo;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -34,6 +40,13 @@ public class ServiceContractFlow extends FlowDelegate {
     @Autowired
     private CodingRuleService codingRuleService;
 
+    @Autowired
+    private ServiceContractService serviceContractService = SpringUtil.getBean(ServiceContractService.class);
+    @Autowired
+    private ServiceContractPayService serviceContractPayService = SpringUtil.getBean(ServiceContractPayService.class);
+    @Autowired
+    private ServiceContractProductService serviceContractProductService = SpringUtil.getBean(ServiceContractProductService.class);
+
     @Override
     public String getFlowKey() {
         return "service_contract_flow";
@@ -41,50 +54,27 @@ public class ServiceContractFlow extends FlowDelegate {
 
     /**
      * 发起流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param submitData 采购付款数据
      * @return
      */
     @Override
     public Long start(Long flowId, JSONObject submitData) {
-
-
-        ServiceContractService serviceContractService = SpringUtil.getBean(ServiceContractService.class);
-        ServiceContractPayService serviceContractPayService = SpringUtil.getBean(ServiceContractPayService.class);
-        ServiceContractProductService serviceContractProductService = SpringUtil.getBean(ServiceContractProductService.class);
         ServiceContractDto contract = submitData.toJavaObject(ServiceContractDto.class);
 
-        //赋值城市省份信息
-        CustomizeAreaUtil.setAreaId(contract);
-
-        contract.setBuyCityId(contract.getCityId());
-        contract.setBuyCountryId(contract.getCountryId());
-        contract.setBuyProvinceId(contract.getProvinceId());
-
         //添加服务合同编码
-        contract.setCode(codingRuleService.createCode(CodingRuleEnum.SERVICE_CONTRACT.getKey(),contract.getBuyCorporationId()));
-//        contract.setCode(CodeEnum.SALE_QUOTATION.getCode());
-        //添加服务合同状态
-        contract.setStatus(ServiceContractEnum.UNDER_REVIEW.getKey());
-        //添加服务合同信息
-        serviceContractService.save(contract);
-        List<ServiceContractProduct> serviceContractProductList = contract.getServiceContractProductList();
-        if(CollectionUtils.isNotEmpty(serviceContractProductList)){//保存报价产品信息
-            serviceContractProductList.forEach(serviceContractProduct -> serviceContractProduct.setServiceContractId(contract.getId()));
-            serviceContractProductService.saveBatch(serviceContractProductList);
-        }
-        List<ServiceContractPay> serviceContractPayList = contract.getServiceContractPayList();
-        if(CollectionUtils.isNotEmpty(serviceContractPayList)){//保存报价项目信息
-            serviceContractPayList.forEach(contractPay -> contractPay.setServiceContractId(contract.getId()));
-            serviceContractPayService.saveBatch(serviceContractPayList);
-        }
+        contract.setCode(codingRuleService.createCode(CodingRuleEnum.SERVICE_CONTRACT.getKey(), contract.getBuyCorporationId()));
+        //调用公共代码
+        contract = commStart(contract, 0);
 
         return contract.getId();
     }
 
     /**
      * 结束流程
-     * @param flowId 流程ID
+     *
+     * @param flowId     流程ID
      * @param businessId 业务ID
      * @param submitData 数据
      */
@@ -93,11 +83,75 @@ public class ServiceContractFlow extends FlowDelegate {
         ServiceContractService contractService = SpringUtil.getBean(ServiceContractService.class);
         //通过业务ID查询合同数据
         ServiceContract contract = contractService.getById(businessId);
-        if(ObjectUtils.isEmpty(contract)){
+        if (ObjectUtils.isEmpty(contract)) {
             throw new ServiceException("服务合同不存在");
         }
         //修改采购状态为审批通过
         contract.setStatus(ServiceContractEnum.PASS.getKey());
         contractService.updateById(contract);
     }
+
+    @Override
+    public void defaultMethod(Long flowId, Long businessId, FlowStatusEnum flowStatusEnum, JSONObject submitData) {
+        //重新发起
+        if (FlowStatusEnum.READY_START.equals(flowStatusEnum)) {
+            ServiceContractDto contract = submitData.toJavaObject(ServiceContractDto.class);
+
+            commStart(contract, 1);
+        }
+        //驳回
+        if (FlowStatusEnum.REJECT.equals(flowStatusEnum)) {
+            serviceContractService.update(q -> q
+                    .eq(ServiceContract::getId, businessId)
+                    .set(ServiceContract::getStatus, FlowStatusEnum1.REJECT.getKey())
+                    .set(BasePo::getUpdateTime, new Date())
+                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
+            );
+        }
+    }
+
+    /**
+     * 开始公共代码抽取
+     *
+     * @param opType 操作类型 0直接发起 1重新发起
+     */
+    private ServiceContractDto commStart(ServiceContractDto contract, Integer opType) {
+        if (opType == 1) {
+            Assert.notEmpty(contract.getId(), "服务合同id不能为空");
+        }
+        //赋值城市省份信息
+        CustomizeAreaUtil.setAreaId(contract);
+
+        contract.setBuyCityId(contract.getCityId());
+        contract.setBuyCountryId(contract.getCountryId());
+        contract.setBuyProvinceId(contract.getProvinceId());
+
+        //添加服务合同状态
+        contract.setStatus(ServiceContractEnum.UNDER_REVIEW.getKey());
+        //添加服务合同信息
+        serviceContractService.saveOrUpdate(contract);
+        List<ServiceContractProduct> serviceContractProductList = contract.getServiceContractProductList();
+        if (CollectionUtils.isNotEmpty(serviceContractProductList)) {//保存报价产品信息
+            if (opType == 1) {
+                //先处理被删除的数据
+                serviceContractProductService.editLinked(serviceContractProductList, ServiceContractProduct::getServiceContractId, contract.getId());
+            }
+
+            serviceContractProductList.forEach(serviceContractProduct -> serviceContractProduct.setServiceContractId(contract.getId()));
+            serviceContractProductService.saveOrUpdateBatch(serviceContractProductList);
+        }
+        List<ServiceContractPay> serviceContractPayList = contract.getServiceContractPayList();
+        if (CollectionUtils.isNotEmpty(serviceContractPayList)) {//保存报价项目信息
+            if (opType == 1) {
+                //先处理被删除的数据
+                serviceContractPayService.editLinked(serviceContractPayList, ServiceContractPay::getServiceContractId, contract.getId());
+            }
+
+            serviceContractPayList.forEach(contractPay -> contractPay.setServiceContractId(contract.getId()));
+            serviceContractPayService.saveOrUpdateBatch(serviceContractPayList);
+        }
+
+        return contract;
+    }
+
 }

+ 26 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesDetailMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.sale.mapper.after;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 售后明细 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesDetailMapper extends BaseMapper<AfterSalesDetail> {
+
+    /**
+     * 售后明细分页
+     */
+    Page<AfterSalesDetailVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<AfterSalesDetail> wrapper);
+
+}

+ 17 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.sale.mapper.after;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fjhx.sale.entity.after.po.AfterSales;
+
+
+/**
+ * <p>
+ * 售后管理 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesMapper extends BaseMapper<AfterSales> {
+
+}

+ 26 - 0
hx-sale/src/main/java/com/fjhx/sale/mapper/after/AfterSalesRecordsMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.sale.mapper.after;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 售后跟进记录 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesRecordsMapper extends BaseMapper<AfterSalesRecords> {
+
+    /**
+     * 售后跟进记录分页
+     */
+    Page<AfterSalesRecordsVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<AfterSalesRecords> wrapper);
+
+}

+ 46 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesDetailService.java

@@ -0,0 +1,46 @@
+package com.fjhx.sale.service.after;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 售后明细 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesDetailService extends BaseService<AfterSalesDetail> {
+
+    /**
+     * 售后明细分页
+     */
+    Page<AfterSalesDetailVo> getPage(AfterSalesDetailSelectDto dto);
+
+    /**
+     * 售后管理编辑
+     */
+    void edit(AfterSalesDetailDto afterSalesDetailDto);
+
+    /**
+     * 售后退货
+     */
+    void salesReturn(AfterSalesDetailDto afterSalesDetailDto);
+
+    /**
+     * 售后换货
+     */
+    void salesReplace(AfterSalesDetailDto afterSalesDetailDto);
+
+    /**
+     * 销售发起采购
+     */
+    void initPurchase(AfterSalesDetailDto afterSalesDetailDto);
+
+}

+ 31 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesRecordsService.java

@@ -0,0 +1,31 @@
+package com.fjhx.sale.service.after;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordSelectDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 售后跟进记录 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesRecordsService extends BaseService<AfterSalesRecords> {
+
+    /**
+     * 售后跟进记录分页
+     */
+    Page<AfterSalesRecordsVo> getPage(AfterSalesRecordSelectDto dto);
+
+    /**
+     * 售后跟进记录新增
+     */
+    void add(AfterSalesRecordsDto afterSalesRecordDto);
+
+}

+ 23 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/AfterSalesService.java

@@ -0,0 +1,23 @@
+package com.fjhx.sale.service.after;
+
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 售后管理 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+public interface AfterSalesService extends BaseService<AfterSales> {
+
+    /**
+     * 售后管理新增
+     */
+    void add(AfterSalesDto afterSalesDto);
+
+}

+ 195 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesDetailServiceImpl.java

@@ -0,0 +1,195 @@
+package com.fjhx.sale.service.after.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.utils.Assert;
+import com.fjhx.customer.service.customer.CustomerService;
+import com.fjhx.item.entity.product.po.ProductInfo;
+import com.fjhx.item.service.product.ProductInfoService;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesDetailSelectDto;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.after.vo.AfterSalesDetailVo;
+import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.mapper.after.AfterSalesDetailMapper;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import com.fjhx.sale.service.after.AfterSalesService;
+import com.fjhx.sale.service.contract.ContractProductService;
+import com.fjhx.sale.service.contract.ContractService;
+import com.fjhx.wms.entity.stock.emums.StockWaitType;
+import com.fjhx.wms.entity.stock.po.StockWait;
+import com.fjhx.wms.entity.stock.po.StockWaitDetails;
+import com.fjhx.wms.service.stock.StockWaitDetailsService;
+import com.fjhx.wms.service.stock.StockWaitService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 售后明细 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Service
+public class AfterSalesDetailServiceImpl extends ServiceImpl<AfterSalesDetailMapper, AfterSalesDetail> implements AfterSalesDetailService {
+
+    @Autowired
+    private CustomerService customerService;
+    @Autowired
+    private ContractService contractService;
+    @Autowired
+    private ProductInfoService productInfoService;
+    @Autowired
+    private StockWaitService stockWaitService;
+    @Autowired
+    private StockWaitDetailsService stockWaitDetailsService;
+    @Autowired
+    private ContractProductService contractProductService;
+    @Autowired
+    private AfterSalesService afterSalesService;
+
+    @Override
+    public Page<AfterSalesDetailVo> getPage(AfterSalesDetailSelectDto dto) {
+        IWrapper<AfterSalesDetail> wrapper = getWrapper();
+        //客户id过滤
+        wrapper.eq("as1", AfterSalesDetailVo::getCustomerId, dto.getCustomerId());
+        //售后类型过滤
+        wrapper.eq("as1", AfterSalesDetailVo::getType, dto.getType());
+        //售后状态过滤
+        wrapper.eq("asd", AfterSalesDetailVo::getStatus, dto.getStatus());
+        //关键字搜索
+        if (ObjectUtils.isNotEmpty(dto.getKeyword())) {
+            List<Long> pIds = productInfoService.listObject(ProductInfo::getId, q -> q
+                    .like(ProductInfo::getCode, dto.getKeyword())
+                    .like(ProductInfo::getName, dto.getKeyword())
+                    .like(ProductInfo::getSpec, dto.getKeyword())
+            );
+            pIds.add(null);
+            wrapper.in("asd", AfterSalesDetail::getProductId, pIds);
+        }
+        //根据创建时间倒序
+        wrapper.orderByDesc("as1", AfterSalesDetail::getCreateTime);
+        Page<AfterSalesDetailVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        List<AfterSalesDetailVo> records = page.getRecords();
+        //赋值客户名称
+        customerService.attributeAssign(records, AfterSalesDetailVo::getCustomerId, (item, customer) -> {
+            item.setCustomerName(customer.getName());
+        });
+        //赋值合同编号
+        contractService.attributeAssign(records, AfterSalesDetailVo::getContractId, (item, contract) -> {
+            item.setContractCode(contract.getCode());
+        });
+        //赋值产品信息
+        productInfoService.attributeAssign(records, AfterSalesDetailVo::getProductId, (item, productInfo) -> {
+            item.setProductCode(productInfo.getCode());
+            item.setProductName(productInfo.getName());
+            item.setProductSpec(productInfo.getSpec());
+            item.setProductUnit(productInfo.getUnit());
+        });
+        return page;
+    }
+
+    @Override
+    public void edit(AfterSalesDetailDto afterSalesDetailSelectDto) {
+        this.updateById(afterSalesDetailSelectDto);
+    }
+
+    /**
+     * 退货
+     */
+    @DSTransactional
+    @Override
+    public void salesReturn(AfterSalesDetailDto afterSalesDetailDto) {
+        Assert.notEmpty(afterSalesDetailDto.getId(), "售后id不能为空");
+        AfterSalesDetail afterSalesDetail = this.getById(afterSalesDetailDto.getId());
+        Assert.notEmpty(afterSalesDetail, "查询不到售后信息");
+
+        //生成售后退货待入库信息
+        StockWait stockWait = new StockWait();
+        stockWait.setType(1);//入库
+        stockWait.setStatus(0);//待入库
+        stockWait.setBusinessType(StockWaitType.SALES_RETURN_IN.getDetailType());
+        stockWait.setBusinessId(afterSalesDetail.getId());
+        stockWaitService.save(stockWait);
+
+        //生成售后退货待入库明细
+        StockWaitDetails stockWaitDetails = new StockWaitDetails();
+        stockWaitDetails.setStockWaitId(stockWait.getId());
+        stockWaitDetails.setProductId(afterSalesDetail.getProductId());
+        stockWaitDetails.setQuantity(afterSalesDetail.getQuantity());
+        stockWaitDetailsService.save(stockWaitDetails);
+    }
+
+    /**
+     * 销售换货
+     */
+    @DSTransactional
+    @Override
+    public void salesReplace(AfterSalesDetailDto afterSalesDetailDto) {
+        Assert.notEmpty(afterSalesDetailDto.getId(), "售后id不能为空");
+        AfterSalesDetail afterSalesDetail = this.getById(afterSalesDetailDto.getId());
+        Assert.notEmpty(afterSalesDetail, "查询不到售后信息");
+
+        //生成售后换货待入库信息
+        StockWait stockWait = new StockWait();
+        stockWait.setType(1);//入库
+        stockWait.setStatus(0);//待入库
+        stockWait.setBusinessType(StockWaitType.SALES_REPLACE_IN.getDetailType());
+        stockWait.setBusinessId(afterSalesDetailDto.getId());
+        stockWaitService.save(stockWait);
+        //生成售后换货待出库信息
+        StockWait stockWait1 = new StockWait();
+        stockWait1.setType(2);//出库
+        stockWait1.setStatus(0);//待出库
+        stockWait1.setBusinessType(StockWaitType.SALES_REPLACE_OUT.getDetailType());
+        stockWait1.setBusinessId(afterSalesDetailDto.getId());
+        stockWaitService.save(stockWait1);
+
+        //生成售后换货待出入库明细
+        //生成入库明细
+        StockWaitDetails stockWaitDetails = new StockWaitDetails();
+        stockWaitDetails.setStockWaitId(stockWait.getId());
+        stockWaitDetails.setProductId(afterSalesDetail.getProductId());
+        stockWaitDetails.setQuantity(afterSalesDetail.getQuantity());
+        stockWaitDetailsService.save(stockWaitDetails);
+        //生成出库明细
+        StockWaitDetails stockWaitDetails1 = new StockWaitDetails();
+        stockWaitDetails1.setStockWaitId(stockWait1.getId());
+        stockWaitDetails1.setProductId(afterSalesDetail.getProductId());
+        stockWaitDetails1.setQuantity(afterSalesDetail.getQuantity());
+        stockWaitDetailsService.save(stockWaitDetails1);
+    }
+
+    /**
+     * 发起采购
+     */
+    @Override
+    @Transactional
+    public void initPurchase(AfterSalesDetailDto afterSalesDetailDto) {
+        Assert.notEmpty(afterSalesDetailDto.getId(), "售后id不能为空");
+        AfterSalesDetail afterSalesDetail = this.getById(afterSalesDetailDto.getId());
+        Assert.notEmpty(afterSalesDetail, "查询不到售后信息");
+//        AfterSales afterSales = afterSalesService.getById(afterSalesDetail.getAfterSalesId());
+
+        //创建交接单
+        ContractProduct contractProduct = new ContractProduct();
+        contractProduct.setProductId(afterSalesDetail.getProductId());
+        contractProduct.setQuantity(afterSalesDetail.getQuantity());
+        contractProduct.setExpendQuantity(afterSalesDetail.getQuantity());
+        contractProduct.setContractId(afterSalesDetailDto.getContractId());
+        contractProduct.setPrice(afterSalesDetail.getPrice());
+        contractProduct.setAmount(afterSalesDetail.getAmount());
+        contractProduct.setRemark(afterSalesDetail.getRemark());
+        contractProductService.save(contractProduct);
+    }
+
+}

+ 53 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesRecordsServicesImpl.java

@@ -0,0 +1,53 @@
+package com.fjhx.sale.service.after.impl;
+
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.common.utils.Assert;
+import com.fjhx.file.utils.ObsFileUtil;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordSelectDto;
+import com.fjhx.sale.entity.after.dto.AfterSalesRecordsDto;
+import com.fjhx.sale.entity.after.po.AfterSalesRecords;
+import com.fjhx.sale.entity.after.vo.AfterSalesRecordsVo;
+import com.fjhx.sale.mapper.after.AfterSalesRecordsMapper;
+import com.fjhx.sale.service.after.AfterSalesRecordsService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import com.ruoyi.system.utils.UserUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 售后跟进记录 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Service
+public class AfterSalesRecordsServicesImpl extends ServiceImpl<AfterSalesRecordsMapper, AfterSalesRecords> implements AfterSalesRecordsService {
+
+    @Override
+    public Page<AfterSalesRecordsVo> getPage(AfterSalesRecordSelectDto dto) {
+        IWrapper<AfterSalesRecords> wrapper = getWrapper();
+        Long afterSalesDetailId = dto.getAfterSalesDetailId();
+        Assert.notEmpty(afterSalesDetailId, "售后明细id不能为空");
+        wrapper.eq(AfterSalesRecordsVo::getAfterSalesDetailId, afterSalesDetailId);
+        wrapper.orderByDesc("asr", AfterSalesRecords::getFollowUpTime);
+        Page<AfterSalesRecordsVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        List<AfterSalesRecordsVo> records = page.getRecords();
+        //赋值跟进人名称
+        UserUtil.assignmentNickName(records, AfterSalesRecordsVo::getFollowUpUserId, AfterSalesRecordsVo::setFollowUpUserName);
+        return page;
+    }
+
+    @DSTransactional
+    @Override
+    public void add(AfterSalesRecordsDto afterSalesRecordDto) {
+        this.save(afterSalesRecordDto);
+        ObsFileUtil.saveFile(afterSalesRecordDto.getFileList(), afterSalesRecordDto.getId());
+    }
+
+}

+ 64 - 0
hx-sale/src/main/java/com/fjhx/sale/service/after/impl/AfterSalesServiceImpl.java

@@ -0,0 +1,64 @@
+package com.fjhx.sale.service.after.impl;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.sale.entity.after.dto.AfterSalesDto;
+import com.fjhx.sale.entity.after.po.AfterSales;
+import com.fjhx.sale.entity.after.po.AfterSalesDetail;
+import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.mapper.after.AfterSalesMapper;
+import com.fjhx.sale.service.after.AfterSalesDetailService;
+import com.fjhx.sale.service.after.AfterSalesService;
+import com.fjhx.sale.service.contract.ContractProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * 售后管理 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-07-20
+ */
+@Service
+public class AfterSalesServiceImpl extends ServiceImpl<AfterSalesMapper, AfterSales> implements AfterSalesService {
+    @Autowired
+    private AfterSalesDetailService afterSalesDetailService;
+
+    @Autowired
+    private ContractProductService contractProductService;
+
+    @DSTransactional
+    @Override
+    public void add(AfterSalesDto afterSalesDto) {
+        this.save(afterSalesDto);
+        List<AfterSalesDetail> afterSalesDetailList = afterSalesDto.getAfterSalesDetailList();
+        afterSalesDetailList.forEach(item -> item.setAfterSalesId(afterSalesDto.getId()));
+        //赋值单价信息
+        List<Long> contractProductIds = afterSalesDetailList.stream().distinct().map(AfterSalesDetail::getContractProductId).collect(Collectors.toList());
+        Map<Long, ContractProduct> longContractProductMap = new HashMap<>();
+        if (ObjectUtil.isNotEmpty(contractProductIds)) {
+            longContractProductMap = contractProductService.mapKEntity(ContractProduct::getId, q -> q.in(ContractProduct::getId, contractProductIds));
+        }
+        for (AfterSalesDetail afterSalesDetail : afterSalesDetailList) {
+            //赋值单价信息
+            ContractProduct oldContractProduct = longContractProductMap.get(afterSalesDetail.getContractProductId());
+            afterSalesDetail.setPrice(BigDecimal.ZERO);
+            if (ObjectUtil.isNotEmpty(oldContractProduct)) {
+                afterSalesDetail.setPrice(oldContractProduct.getPrice());
+            }
+            afterSalesDetail.setAmount(afterSalesDetail.getQuantity().multiply(afterSalesDetail.getPrice()));
+        }
+        afterSalesDetailService.saveBatch(afterSalesDetailList);
+    }
+
+}

+ 8 - 7
hx-sale/src/main/java/com/fjhx/sale/service/claim/impl/ClaimContractServiceImpl.java

@@ -1,16 +1,16 @@
 package com.fjhx.sale.service.claim.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.sale.entity.claim.dto.ClaimContractDto;
+import com.fjhx.sale.entity.claim.dto.ClaimContractSelectDto;
 import com.fjhx.sale.entity.claim.po.ClaimContract;
+import com.fjhx.sale.entity.claim.vo.ClaimContractVo;
 import com.fjhx.sale.mapper.claim.ClaimContractMapper;
 import com.fjhx.sale.service.claim.ClaimContractService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fjhx.sale.entity.claim.vo.ClaimContractVo;
-import com.fjhx.sale.entity.claim.dto.ClaimContractSelectDto;
 import com.ruoyi.common.utils.wrapper.IWrapper;
-import com.fjhx.sale.entity.claim.dto.ClaimContractDto;
-import cn.hutool.core.bean.BeanUtil;
+import org.springframework.stereotype.Service;
 
 import java.util.List;
 
@@ -65,6 +65,7 @@ public class ClaimContractServiceImpl extends ServiceImpl<ClaimContractMapper, C
     public List<ClaimContract> getListByContractIds(List<Long> contractIds) {
         IWrapper<ClaimContract> wrapper = getWrapper();
         wrapper.in("t1.contract_id", contractIds);
+        wrapper.orderByDesc("t1.create_time");
         return baseMapper.getListByContractIds(wrapper);
     }
 

+ 11 - 4
hx-sale/src/main/java/com/fjhx/sale/service/contract/ContractProductService.java

@@ -1,11 +1,11 @@
 package com.fjhx.sale.service.contract;
 
-import com.fjhx.sale.entity.contract.po.ContractProduct;
-import com.ruoyi.common.core.service.BaseService;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.fjhx.sale.entity.contract.vo.ContractProductVo;
-import com.fjhx.sale.entity.contract.dto.ContractProductSelectDto;
 import com.fjhx.sale.entity.contract.dto.ContractProductDto;
+import com.fjhx.sale.entity.contract.dto.ContractProductSelectDto;
+import com.fjhx.sale.entity.contract.po.ContractProduct;
+import com.fjhx.sale.entity.contract.vo.ContractProductVo;
+import com.ruoyi.common.core.service.BaseService;
 
 import java.util.List;
 
@@ -26,10 +26,17 @@ public interface ContractProductService extends BaseService<ContractProduct> {
     Page<ContractProductVo> getPage(ContractProductSelectDto dto);
 
     /**
+     * 采购交接单 分页
+     */
+    Page<ContractProductVo> getPage1(ContractProductSelectDto dto);
+
+    /**
      * 外销合同-根据多个明细ID集合查询合同产品
      */
     List<ContractProductVo> getListDetail(List<Long> ids);
 
+    List<ContractProductVo> getListDetailByContractId(List<Long> contractIds);
+
     /**
      * 外销合同-产品明细
      */

+ 63 - 9
hx-sale/src/main/java/com/fjhx/sale/service/contract/impl/ContractProductServiceImpl.java

@@ -6,11 +6,12 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fjhx.common.entity.contract.po.ContractTemplate;
-import com.fjhx.common.enums.FlowStatusEnum;
+import com.fjhx.common.enums.FlowStatusEnum1;
 import com.fjhx.common.service.contract.ContractTemplateService;
 import com.fjhx.common.service.corporation.CorporationService;
 import com.fjhx.customer.service.customer.CustomerService;
 import com.fjhx.flow.service.flow.FlowExampleService;
+import com.fjhx.item.entity.product.po.ProductInfo;
 import com.fjhx.item.service.product.ProductClassifyService;
 import com.fjhx.item.service.product.ProductInfoService;
 import com.fjhx.purchase.entity.purchase.vo.PurchaseDetailVo;
@@ -82,23 +83,61 @@ public class ContractProductServiceImpl extends ServiceImpl<ContractProductMappe
     @Override
     public Page<ContractProductVo> getPage(ContractProductSelectDto dto) {
         IWrapper<ContractProduct> wrapper = getWrapper();
+        //过滤待处理数量为0的数据
+        wrapper.ne("t1", ContractProduct::getExpendQuantity, 0);
+        //是否到账过滤
+        if (ObjectUtil.isNotEmpty(dto.getIsReceived())) {
+            if (1 == dto.getIsReceived()) {
+                wrapper.isNotNull("co.id");
+            } else {
+                wrapper.isNull("co.id");
+            }
+        }
+        //下发交接单过滤
+        wrapper.eq("t2", Contract::getIssue, 1);
+        return commPage(wrapper, dto);
+    }
+
+    /**
+     * 采购交接单
+     */
+    @Override
+    public Page<ContractProductVo> getPage1(ContractProductSelectDto dto) {
+        IWrapper<ContractProduct> wrapper = getWrapper();
+        //过滤 已到账 或 预付比例==0 的数据
+        wrapper.and(q -> q.isNotNull("co.id").or().eq("t2.advance_ratio", 0));
+        return commPage(wrapper, dto);
+    }
+
+    /**
+     * 公共代码抽取
+     */
+    public Page<ContractProductVo> commPage(IWrapper<ContractProduct> wrapper, ContractProductSelectDto dto) {
         wrapper.orderByDesc("t1", ContractProduct::getCreateTime);
-        wrapper.ne("t1",ContractProduct::getExpendQuantity,0);
-        wrapper.between("t2", Contract::getStatus, FlowStatusEnum.PASS.getKey(), FlowStatusEnum.CANCELLATION.getKey() - 1);
-        if(ObjectUtil.isNotEmpty(dto.getDataType())&&dto.getDataType()==0){//合同交接单
+//        wrapper.between("t2", Contract::getStatus, FlowStatusEnum.PASS.getKey(), FlowStatusEnum.CANCELLATION.getKey() - 1);
+        wrapper.eq("t2", Contract::getStatus, FlowStatusEnum1.PASS.getKey());
+        if (ObjectUtil.isNotEmpty(dto.getDataType()) && dto.getDataType() == 0) {//合同交接单
             wrapper.ne("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
         }
-        if(ObjectUtil.isNotEmpty(dto.getPurchaseStatus())&&dto.getPurchaseStatus()==2){//已采购
+        if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 2) {//已采购
             wrapper.eq("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
-        }else if(ObjectUtil.isNotEmpty(dto.getPurchaseStatus())&&dto.getPurchaseStatus()==1){//部分采购
+        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 1) {//部分采购
             wrapper.gt("t1", ContractProduct::getExpendQuantity, BigDecimal.ZERO);
             wrapper.apply("t1.expend_quantity <t1.quantity");
-        }else if(ObjectUtil.isNotEmpty(dto.getPurchaseStatus())&&dto.getPurchaseStatus()==0){//未采购
+        } else if (ObjectUtil.isNotEmpty(dto.getPurchaseStatus()) && dto.getPurchaseStatus() == 0) {//未采购
             wrapper.apply("t1.expend_quantity = t1.quantity");
         }
-        wrapper.eq("t2",Contract::getIssue,1);
         if (StringUtils.isNotEmpty(dto.getKeyword())) {
-            wrapper.keyword(dto.getKeyword(), new SqlField("t2.`code`"), new SqlField("t2.`user_name`"));
+            List<Long> pids = productInfoService.listObject(ProductInfo::getId, q -> q
+                    .like(ProductInfo::getCode, dto.getKeyword())
+                    .or().like(ProductInfo::getName, dto.getKeyword())
+                    .or().like(ProductInfo::getSpec, dto.getKeyword())
+            );
+            wrapper.and(q -> q
+                    .like("t2.`code`", dto.getKeyword())
+                    .or().like("t2.`user_name`", dto.getKeyword())
+                    .or().in(ContractProductVo::getProductId, pids)
+            );
         }
         //所属公司id过滤
         if (ObjectUtil.isNotEmpty(dto.getCorporationId())) {
@@ -356,6 +395,21 @@ public class ContractProductServiceImpl extends ServiceImpl<ContractProductMappe
         return list;
     }
 
+
+    @Override
+    public List<ContractProductVo> getListDetailByContractId(List<Long> contractIds) {
+        List<ContractProduct> list = this.list(q -> q.in(ContractProduct::getContractId, contractIds));
+        List<ContractProductVo> contractProductVos = BeanUtil.copyToList(list, ContractProductVo.class);
+        // 赋值产品属性
+        productInfoService.attributeAssign(contractProductVos, ContractProductVo::getProductId, (item, product) -> {
+            item.setProductCode(product.getCode());
+            item.setProductName(product.getName());
+            item.setProductSpec(product.getSpec());
+            item.setProductUnit(product.getUnit());
+        });
+        return contractProductVos;
+    }
+
     @Override
     public ContractProductVo detail(Long id) {
         ContractProduct ContractProduct = this.getById(id);

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.