Browse Source

Merge branch 'master_20240722' of http://git.dgtis.com/15896567520/oneportal_saas into master_20240722

zhaopeiqing 6 months ago
parent
commit
beeb889cdf
33 changed files with 1536 additions and 112 deletions
  1. 46 0
      yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ProcessKeyEnum.java
  2. 5 13
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
  3. 93 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/business/OaBusinessServiceImpl.java
  4. 93 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImpl.java
  5. 86 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java
  6. 99 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/expense/OaExpenseServiceImpl.java
  7. 93 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/leave/OaLeaveServiceImpl.java
  8. 93 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/out/OaOutServiceImpl.java
  9. 89 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/purchase/OaPurchaseServiceImpl.java
  10. 94 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/receive/OaReceiveServiceImpl.java
  11. 93 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/renew/OaRenewServiceImpl.java
  12. 95 7
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/stamp/OaStampServiceImpl.java
  13. 93 8
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/turnover/OaTurnoverServiceImpl.java
  14. 83 6
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java
  15. 46 0
      yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/OANotifyContentUtil.java
  16. 10 0
      yudao-module-finance/yudao-module-cash-biz/pom.xml
  17. 43 0
      yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/RefundInfoController.java
  18. 2 2
      yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/vo/RefundInfoPageReqVO.java
  19. 0 1
      yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/vo/RefundInfoSaveReqVO.java
  20. 14 10
      yudao-module-finance/yudao-module-cash-biz/src/main/resources/mapper/refundinfo/RefundInfoMapper.xml
  21. 14 0
      yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/CustomerContractApi.java
  22. 62 0
      yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/dto/CustomerContractDTO.java
  23. 2 0
      yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/enums/ErrorCodeConstants.java
  24. 22 0
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/CustomerContractApiImpl.java
  25. 10 0
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/customercontract/CustomerContractController.java
  26. 30 0
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/customercontract/vo/CustomerContractListVO.java
  27. 16 1
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/customercontract/CustomerContractService.java
  28. 41 0
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/customercontract/CustomerContractServiceImpl.java
  29. 20 0
      yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/suppliercontract/SupplierContractServiceImpl.java
  30. 9 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java
  31. 11 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeConstants.java
  32. 16 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java
  33. 13 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java

+ 46 - 0
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/ProcessKeyEnum.java

@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.bpm.enums;
+
+/**
+ * 流程标识枚举
+ */
+public enum ProcessKeyEnum {
+
+    OA_UNIVERSAL("oa_universal", "通用事项"),
+    OA_ENTRY("oa_entry", "入职"),
+    OA_CONVERSION("oa_conversion", "转正"),
+    OA_RENEW("oa_renew", "续签"),
+    OA_TURNOVER("oa_turnover", "离职"),
+    OA_LEAVE("oa_leave", "请假"),
+    OA_BUSINESS("oa_business", "出差"),
+    OA_OUT("oa_out", "公务外出"),
+    OA_RECEIVE("oa_receive", "领用"),
+    OA_PURCHASE("oa_purchase", "采购"),
+    OA_EXPENSE("oa_expense", "报销"),
+    OA_STAMP("oa_stamp", "用印"),
+    ;
+
+    private final String processKey;
+    private final String processName;
+
+    ProcessKeyEnum(String processKey, String processName) {
+        this.processKey = processKey;
+        this.processName = processName;
+    }
+
+    public String getProcessKey() {
+        return processKey;
+    }
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public static String getByProcessKey(String processKey) {
+        for (ProcessKeyEnum value : values()) {
+            if (value.getProcessKey().equals(processKey)) {
+                return value.processName;
+            }
+        }
+        return "";
+    }
+}

+ 5 - 13
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java

@@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs
 import cn.iocoder.yudao.module.bpm.convert.definition.BpmModelConvert;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
@@ -46,6 +47,8 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
@@ -111,19 +114,8 @@ public class BpmModelServiceImpl implements BpmModelService {
         // StringBuilder resultBuilder = new StringBuilder();
 
         // 模型key列表:共12个
-        List<String> modelKeyList = new ArrayList<>();
-        modelKeyList.add("oa_universal");
-        modelKeyList.add("oa_entry");
-        modelKeyList.add("oa_conversion");
-        modelKeyList.add("oa_renew");
-        modelKeyList.add("oa_turnover");
-        modelKeyList.add("oa_leave");
-        modelKeyList.add("oa_business");
-        modelKeyList.add("oa_out");
-        modelKeyList.add("oa_receive");
-        modelKeyList.add("oa_purchase");
-        modelKeyList.add("oa_expense");
-        modelKeyList.add("oa_stamp");
+        List<String> modelKeyList = Stream.of(ProcessKeyEnum.values())
+                .map(ProcessKeyEnum::getProcessKey).collect(Collectors.toList());
 
         // 默认租户:1
         if (StrUtil.isBlank(modelTenantId)) {

+ 93 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/business/OaBusinessServiceImpl.java

@@ -24,14 +24,17 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.business.OaBusinessDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.business.OaBusinessMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -43,7 +46,12 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -61,7 +69,7 @@ public class OaBusinessServiceImpl implements OaBusinessService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_business";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_BUSINESS.getProcessKey();
 
     @Resource
     private OaBusinessMapper oaBusinessMapper;
@@ -87,6 +95,10 @@ public class OaBusinessServiceImpl implements OaBusinessService {
     @Resource
     private AttendanceBusinessApi attendanceBusinessApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaBusiness(OaBusinessSaveReqVO stagingReqVO) {
@@ -223,7 +235,24 @@ public class OaBusinessServiceImpl implements OaBusinessService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaBusiness.getBusinessId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaBusiness.getId();
     }
 
@@ -302,7 +331,33 @@ public class OaBusinessServiceImpl implements OaBusinessService {
             attendanceBusinessApi.createBusinessInfoAfterAudit(businessCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaBusiness.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -341,7 +396,22 @@ public class OaBusinessServiceImpl implements OaBusinessService {
                 .eq(OaBusinessDO::getProcInstId, currentTask.getProcessInstanceId());
         oaBusinessMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaBusinessDO oaBusinessDO = oaBusinessMapper.selectOne(OaBusinessDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaBusinessDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaBusinessDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -393,8 +463,6 @@ public class OaBusinessServiceImpl implements OaBusinessService {
                 .eq(OaBusinessDO::getProcInstId, currentTask.getProcessInstanceId());
         oaBusinessMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -460,6 +528,24 @@ public class OaBusinessServiceImpl implements OaBusinessService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaBusinessNew.getBusinessId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 93 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/conversion/OaConversionServiceImpl.java

@@ -22,8 +22,10 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.conversion.OaConversionDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.conversion.OaConversionMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
@@ -32,6 +34,7 @@ import cn.iocoder.yudao.module.relations.api.conversion.RelationsConversionApi;
 import cn.iocoder.yudao.module.relations.api.conversion.dto.RelationsConversionCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -43,7 +46,12 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -61,7 +69,7 @@ public class OaConversionServiceImpl implements OaConversionService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_conversion";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_CONVERSION.getProcessKey();
 
     @Resource
     private OaConversionMapper oaConversionMapper;
@@ -87,6 +95,10 @@ public class OaConversionServiceImpl implements OaConversionService {
     @Resource
     private RelationsConversionApi relationsConversionApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaConversion(OaConversionSaveReqVO stagingReqVO) {
@@ -228,7 +240,24 @@ public class OaConversionServiceImpl implements OaConversionService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaConversion.getConversionId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaConversion.getId();
     }
 
@@ -307,7 +336,33 @@ public class OaConversionServiceImpl implements OaConversionService {
             relationsConversionApi.createConversionInfoAfterAudit(conversionCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaConversion.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -346,7 +401,22 @@ public class OaConversionServiceImpl implements OaConversionService {
                 .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
         oaConversionMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaConversionDO oaConversionDO = oaConversionMapper.selectOne(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaConversionDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaConversionDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -398,8 +468,6 @@ public class OaConversionServiceImpl implements OaConversionService {
                 .eq(OaConversionDO::getProcInstId, currentTask.getProcessInstanceId());
         oaConversionMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -465,6 +533,24 @@ public class OaConversionServiceImpl implements OaConversionService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaConversionNew.getConversionId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 86 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/entry/OaEntryServiceImpl.java

@@ -22,8 +22,10 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.entry.OaEntryDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.entry.OaEntryMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
@@ -32,6 +34,7 @@ import cn.iocoder.yudao.module.relations.api.entry.RelationsEntryApi;
 import cn.iocoder.yudao.module.relations.api.entry.dto.RelationsEntryCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -61,7 +64,7 @@ public class OaEntryServiceImpl implements OaEntryService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_entry";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_ENTRY.getProcessKey();
 
     @Resource
     private OaEntryMapper oaEntryMapper;
@@ -87,6 +90,10 @@ public class OaEntryServiceImpl implements OaEntryService {
     @Resource
     private RelationsEntryApi relationsEntryApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaEntry(OaEntrySaveReqVO stagingReqVO) {
@@ -200,7 +207,24 @@ public class OaEntryServiceImpl implements OaEntryService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaEntry.getEntryId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaEntry.getId();
     }
 
@@ -271,7 +295,34 @@ public class OaEntryServiceImpl implements OaEntryService {
             // 保存单据信息
             relationsEntryApi.createEntryInfoAfterAudit(entryCreateReqDTO);
         }
-        // TODO 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaEntry.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -304,7 +355,21 @@ public class OaEntryServiceImpl implements OaEntryService {
                 .eq(OaEntryDO::getProcInstId, currentTask.getProcessInstanceId());
         oaEntryMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaEntryDO oaEntryDO = oaEntryMapper.selectOne(OaEntryDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaEntryDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaEntryDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
 
         return 1L;
     }
@@ -350,8 +415,6 @@ public class OaEntryServiceImpl implements OaEntryService {
                 .eq(OaEntryDO::getProcInstId, currentTask.getProcessInstanceId());
         oaEntryMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -399,6 +462,23 @@ public class OaEntryServiceImpl implements OaEntryService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaEntryNew.getEntryId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return 1L;
     }
 

+ 99 - 8
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/expense/OaExpenseServiceImpl.java

@@ -24,8 +24,10 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.oa.expense.OaExpenseMapper;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.expense.OaExpenseObjMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.expense.api.expenseinfo.ExpenseInfoApi;
@@ -39,6 +41,7 @@ import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -51,11 +54,20 @@ import org.springframework.validation.annotation.Validated;
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EXPENSE_NOT_EXISTS;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EXPENSE_OBJ_END_DATE_NULL;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EXPENSE_OBJ_MONEY_ZERO;
+import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.OA_EXPENSE_OBJ_START_DATE_NULL;
 
 /**
  * 报销流程信息 Service 实现类
@@ -70,7 +82,7 @@ public class OaExpenseServiceImpl implements OaExpenseService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_expense";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_EXPENSE.getProcessKey();
 
 
     @Resource
@@ -106,6 +118,10 @@ public class OaExpenseServiceImpl implements OaExpenseService {
     @Resource
     private ExpenseInfoApi expenseInfoApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaExpense(OaExpenseSaveReqVO stagingReqVO) {
@@ -268,7 +284,24 @@ public class OaExpenseServiceImpl implements OaExpenseService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaExpense.getExpenseUuid());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaExpense.getId();
     }
 
@@ -356,7 +389,34 @@ public class OaExpenseServiceImpl implements OaExpenseService {
             // 调用接口创建费用信息
             expenseInfoApi.createExpenseInfo(expenseInfoCreateReqDTO);
         }
-        // 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaExpense.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -395,7 +455,22 @@ public class OaExpenseServiceImpl implements OaExpenseService {
                 .eq(OaExpenseDO::getProcInstId, currentTask.getProcessInstanceId());
         oaExpenseMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaExpenseDO oaExpenseDO = oaExpenseMapper.selectOne(OaExpenseDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaExpenseDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaExpenseDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -447,8 +522,6 @@ public class OaExpenseServiceImpl implements OaExpenseService {
                 .eq(OaExpenseDO::getProcInstId, currentTask.getProcessInstanceId());
         oaExpenseMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -534,6 +607,24 @@ public class OaExpenseServiceImpl implements OaExpenseService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaExpenseNew.getExpenseUuid());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 93 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/leave/OaLeaveServiceImpl.java

@@ -24,14 +24,17 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.leave.OaLeaveDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.leave.OaLeaveMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -43,7 +46,12 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -62,7 +70,7 @@ public class OaLeaveServiceImpl implements OaLeaveService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_leave";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_LEAVE.getProcessKey();
 
 
     @Resource
@@ -89,6 +97,10 @@ public class OaLeaveServiceImpl implements OaLeaveService {
     @Resource
     private AttendanceLeaveApi attendanceLeaveApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaLeave(OaLeaveSaveReqVO stagingReqVO) {
@@ -221,7 +233,24 @@ public class OaLeaveServiceImpl implements OaLeaveService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaLeave.getLeaveId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaLeave.getId();
     }
 
@@ -300,7 +329,33 @@ public class OaLeaveServiceImpl implements OaLeaveService {
             attendanceLeaveApi.createLeaveInfoAfterAudit(leaveCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaLeave.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -339,7 +394,22 @@ public class OaLeaveServiceImpl implements OaLeaveService {
                 .eq(OaLeaveDO::getProcInstId, currentTask.getProcessInstanceId());
         oaLeaveMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaLeaveDO oaLeaveDO = oaLeaveMapper.selectOne(OaLeaveDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaLeaveDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaLeaveDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -391,8 +461,6 @@ public class OaLeaveServiceImpl implements OaLeaveService {
                 .eq(OaLeaveDO::getProcInstId, currentTask.getProcessInstanceId());
         oaLeaveMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -457,6 +525,24 @@ public class OaLeaveServiceImpl implements OaLeaveService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaLeaveNew.getLeaveId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 93 - 8
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/out/OaOutServiceImpl.java

@@ -21,18 +21,20 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveR
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.out.OaOutDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.out.OaOutDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.out.OaOutMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -44,7 +46,12 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -62,7 +69,7 @@ public class OaOutServiceImpl implements OaOutService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_out";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_OUT.getProcessKey();
 
 
     @Resource
@@ -89,6 +96,10 @@ public class OaOutServiceImpl implements OaOutService {
     @Resource
     private AttendanceOutApi attendanceOutApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaOut(OaOutSaveReqVO stagingReqVO) {
@@ -221,7 +232,24 @@ public class OaOutServiceImpl implements OaOutService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaOut.getOutId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaOut.getId();
     }
 
@@ -300,7 +328,33 @@ public class OaOutServiceImpl implements OaOutService {
             attendanceOutApi.createOutInfoAfterAudit(outCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaOut.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -339,7 +393,22 @@ public class OaOutServiceImpl implements OaOutService {
                 .eq(OaOutDO::getProcInstId, currentTask.getProcessInstanceId());
         oaOutMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaOutDO oaOutDO = oaOutMapper.selectOne(OaOutDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaOutDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaOutDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -391,8 +460,6 @@ public class OaOutServiceImpl implements OaOutService {
                 .eq(OaOutDO::getProcInstId, currentTask.getProcessInstanceId());
         oaOutMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -456,6 +523,24 @@ public class OaOutServiceImpl implements OaOutService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaOutNew.getOutId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 89 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/purchase/OaPurchaseServiceImpl.java

@@ -19,18 +19,22 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.purchase.OaPurchaseDO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.purchase.OaPurchaseObjDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.purchase.OaPurchaseDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.purchase.OaPurchaseMapper;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.purchase.OaPurchaseObjMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -60,7 +64,7 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_purchase";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_PURCHASE.getProcessKey();
 
 
     @Resource
@@ -87,6 +91,10 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
     @Resource
     private DeptApi deptApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaPurchase(OaPurchaseSaveReqVO stagingReqVO) {
@@ -246,7 +254,24 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaPurchase.getPurchaseUuid());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaPurchase.getId();
     }
 
@@ -311,7 +336,34 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
                     .setId(oaPurchase.getId());
         }
         oaPurchaseMapper.updateById(oaPurchaseDO);
-        // 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaPurchase.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -350,7 +402,22 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
                 .eq(OaPurchaseDO::getProcInstId, currentTask.getProcessInstanceId());
         oaPurchaseMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaPurchaseDO oaPurchaseDO = oaPurchaseMapper.selectOne(OaPurchaseDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaPurchaseDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaPurchaseDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -402,8 +469,6 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
                 .eq(OaPurchaseDO::getProcInstId, currentTask.getProcessInstanceId());
         oaPurchaseMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -483,6 +548,24 @@ public class OaPurchaseServiceImpl implements OaPurchaseService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaPurchaseNew.getPurchaseUuid());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 94 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/receive/OaReceiveServiceImpl.java

@@ -23,14 +23,17 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.oa.receive.OaReceiveMapper;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.receive.OaReceiveObjMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -42,7 +45,12 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -61,7 +69,7 @@ public class OaReceiveServiceImpl implements OaReceiveService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_receive";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_RECEIVE.getProcessKey();
 
 
     @Resource
@@ -88,6 +96,10 @@ public class OaReceiveServiceImpl implements OaReceiveService {
     @Resource
     private DeptApi deptApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaReceive(OaReceiveSaveReqVO stagingReqVO) {
@@ -244,7 +256,24 @@ public class OaReceiveServiceImpl implements OaReceiveService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaReceive.getReceiveUuid());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaReceive.getId();
     }
 
@@ -309,7 +338,34 @@ public class OaReceiveServiceImpl implements OaReceiveService {
                     .setId(oaReceive.getId());
         }
         oaReceiveMapper.updateById(oaReceiveDO);
-        // 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaReceive.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -348,7 +404,22 @@ public class OaReceiveServiceImpl implements OaReceiveService {
                 .eq(OaReceiveDO::getProcInstId, currentTask.getProcessInstanceId());
         oaReceiveMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaReceiveDO oaReceiveDO = oaReceiveMapper.selectOne(OaReceiveDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaReceiveDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaReceiveDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -400,8 +471,6 @@ public class OaReceiveServiceImpl implements OaReceiveService {
                 .eq(OaReceiveDO::getProcInstId, currentTask.getProcessInstanceId());
         oaReceiveMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -481,6 +550,24 @@ public class OaReceiveServiceImpl implements OaReceiveService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaReceiveNew.getReceiveUuid());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 93 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/renew/OaRenewServiceImpl.java

@@ -22,8 +22,10 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.renew.OaRenewDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.renew.OaRenewMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
@@ -32,6 +34,7 @@ import cn.iocoder.yudao.module.relations.api.renew.RelationsRenewApi;
 import cn.iocoder.yudao.module.relations.api.renew.dto.RelationsRenewCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -45,7 +48,12 @@ import javax.annotation.Resource;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -64,7 +72,7 @@ public class OaRenewServiceImpl implements OaRenewService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_renew";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_RENEW.getProcessKey();
 
     @Resource
     private OaRenewMapper oaRenewMapper;
@@ -90,6 +98,10 @@ public class OaRenewServiceImpl implements OaRenewService {
     @Resource
     private RelationsRenewApi relationsRenewApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaRenew(OaRenewSaveReqVO stagingReqVO) {
@@ -247,7 +259,24 @@ public class OaRenewServiceImpl implements OaRenewService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaRenew.getRenewId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaRenew.getId();
     }
 
@@ -326,7 +355,33 @@ public class OaRenewServiceImpl implements OaRenewService {
             relationsRenewApi.createRenewInfoAfterAudit(renewCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaRenew.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -365,7 +420,22 @@ public class OaRenewServiceImpl implements OaRenewService {
                 .eq(OaRenewDO::getProcInstId, currentTask.getProcessInstanceId());
         oaRenewMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaRenewDO oaRenewDO = oaRenewMapper.selectOne(OaRenewDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaRenewDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaRenewDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -417,8 +487,6 @@ public class OaRenewServiceImpl implements OaRenewService {
                 .eq(OaRenewDO::getProcInstId, currentTask.getProcessInstanceId());
         oaRenewMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -493,6 +561,24 @@ public class OaRenewServiceImpl implements OaRenewService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaRenewNew.getRenewId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 95 - 7
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/stamp/OaStampServiceImpl.java

@@ -23,15 +23,18 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.stamp.stampinfo.OaStampInfoDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.stamp.OaStampMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.stamp.stampinfo.OaStampInfoService;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -43,7 +46,13 @@ import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -61,7 +70,7 @@ public class OaStampServiceImpl implements OaStampService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_stamp";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_STAMP.getProcessKey();
 
 
     @Resource
@@ -88,6 +97,10 @@ public class OaStampServiceImpl implements OaStampService {
     @Resource
     private DeptApi deptApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaStamp(OaStampSaveReqVO stagingReqVO) {
@@ -232,7 +245,24 @@ public class OaStampServiceImpl implements OaStampService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaStamp.getStampUuid());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaStamp.getId();
     }
 
@@ -314,7 +344,34 @@ public class OaStampServiceImpl implements OaStampService {
             // 保存单据信息
             oaStampInfoService.createStampInfoAfterAudit(stampInfoDO);
         }
-        // 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaStamp.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -353,7 +410,22 @@ public class OaStampServiceImpl implements OaStampService {
                 .eq(OaStampDO::getProcInstId, currentTask.getProcessInstanceId());
         oaStampMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaStampDO oaStampDO = oaStampMapper.selectOne(OaStampDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaStampDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaStampDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -405,8 +477,6 @@ public class OaStampServiceImpl implements OaStampService {
                 .eq(OaStampDO::getProcInstId, currentTask.getProcessInstanceId());
         oaStampMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -476,6 +546,24 @@ public class OaStampServiceImpl implements OaStampService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaStampNew.getStampUuid());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 93 - 8
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/turnover/OaTurnoverServiceImpl.java

@@ -19,12 +19,13 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveR
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskReturnReqVO;
 import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.turnover.OaTurnoverDO;
-import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.turnover.OaTurnoverDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.turnover.OaTurnOverMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
@@ -33,6 +34,7 @@ import cn.iocoder.yudao.module.relations.api.turnover.RelationsTurnoverApi;
 import cn.iocoder.yudao.module.relations.api.turnover.dto.RelationsTurnoverCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -46,7 +48,12 @@ import javax.annotation.Resource;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -65,7 +72,7 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_turnover";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_TURNOVER.getProcessKey();
 
 
     @Resource
@@ -92,6 +99,10 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
     @Resource
     private RelationsTurnoverApi relationsTurnoverApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaTurnover(OaTurnoverSaveReqVO stagingReqVO) {
@@ -239,7 +250,24 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaTurnover.getTurnoverId());
-        // TODO DP 发送提交成功站内信
+
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return oaTurnover.getId();
     }
 
@@ -318,7 +346,33 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
             relationsTurnoverApi.createTurnoverInfoAfterAudit(turnoverCreateReqDTO);
         }
 
-        // 发送通知
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaTurnover.getApplyEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -357,7 +411,22 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
                 .eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
         oaTurnoverMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaTurnoverDO oaTurnoverDO = oaTurnoverMapper.selectOne(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaTurnoverDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaTurnoverDO.getApplyEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+
 
         return 1L;
     }
@@ -409,8 +478,6 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
                 .eq(OaTurnoverDO::getProcInstId, currentTask.getProcessInstanceId());
         oaTurnoverMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -482,6 +549,24 @@ public class OaTurnoverServiceImpl implements OaTurnoverService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaTurnoverNew.getTurnoverId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
+
         return 1L;
     }
 

+ 83 - 6
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/oa/universal/OaUniversalServiceImpl.java

@@ -21,14 +21,17 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.universal.OaUniversalDO;
 import cn.iocoder.yudao.module.bpm.dal.mysql.oa.universal.OaUniversalMapper;
 import cn.iocoder.yudao.module.bpm.enums.DictDataConstants;
 import cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants;
+import cn.iocoder.yudao.module.bpm.enums.ProcessKeyEnum;
 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmConstants;
 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
+import cn.iocoder.yudao.module.bpm.util.OANotifyContentUtil;
 import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
+import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.commons.lang3.StringUtils;
@@ -58,7 +61,7 @@ public class OaUniversalServiceImpl implements OaUniversalService {
     /**
      * 对应的流程定义 KEY
      */
-    public static final String PROCESS_KEY = "oa_universal";
+    public static final String PROCESS_KEY = ProcessKeyEnum.OA_UNIVERSAL.getProcessKey();
 
 
     @Resource
@@ -82,6 +85,9 @@ public class OaUniversalServiceImpl implements OaUniversalService {
     @Resource
     private EmployeeApi employeeApi;
 
+    @Resource
+    private NotifyMessageSendApi notifyMessageSendApi;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long stagingOaUniversal(OaUniversalSaveReqVO stagingReqVO) {
@@ -199,7 +205,22 @@ public class OaUniversalServiceImpl implements OaUniversalService {
                 .setStartUserSelectAssignees(selectAssignees.stream().map(String::valueOf).collect(Collectors.joining(","))));
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(commitReqVO.getFileIdList(), oaUniversal.getUniversalId());
-        // TODO DP 发送提交成功站内信
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (employeeAssignee != null) {
+                assigneeId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
         return oaUniversal.getId();
     }
 
@@ -260,7 +281,34 @@ public class OaUniversalServiceImpl implements OaUniversalService {
 
         }
         oaUniversalMapper.updateById(oaUniversalDO);
-        // 发送通知
+
+        // 发送站内信
+        Long assignId = -1L;
+        String assigneeName = "";
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaUniversal.getEmployeeId());
+        if (applyEmployee != null) {
+            applyId = applyEmployee.getId();
+            applyName = applyEmployee.getName();
+        }
+        if (nextTask != null) {
+            EmployeeRespDTO employeeAssignee = employeeApi.getEmployeeById(Long.valueOf(nextTask.getAssignee()));
+            if (employeeAssignee != null) {
+                assignId = employeeAssignee.getId();
+                assigneeName = employeeAssignee.getName();
+            }
+            // 给审批人发送审批站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(assignId, content.toString());
+        } else {
+            // 给申请人发送审批完成站内信
+            StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForComplete(applyName, processName);
+            notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
+        }
+
 
         // 返回
         return 1L;
@@ -293,7 +341,21 @@ public class OaUniversalServiceImpl implements OaUniversalService {
                 .eq(OaUniversalDO::getProcInstId, currentTask.getProcessInstanceId());
         oaUniversalMapper.update(updateWrapper);
 
-        // 发送通知
+        // 给申请人发送驳回站内信
+        String assigneeName = loginEmployee.getName();
+        Long applyId = -1L;
+        String applyName = "";
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+        OaUniversalDO oaUniversalDO = oaUniversalMapper.selectOne(OaUniversalDO::getProcInstId, currentTask.getProcessInstanceId());
+        if (oaUniversalDO != null) {
+            EmployeeRespDTO applyEmployee = employeeApi.getEmployeeById(oaUniversalDO.getEmployeeId());
+            if (applyEmployee != null) {
+                applyId = applyEmployee.getId();
+                applyName = applyEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToApplyForDisagree(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(applyId, content.toString());
 
         return 1L;
     }
@@ -339,8 +401,6 @@ public class OaUniversalServiceImpl implements OaUniversalService {
                 .eq(OaUniversalDO::getProcInstId, currentTask.getProcessInstanceId());
         oaUniversalMapper.update(updateWrapper);
 
-        // 发送通知
-
         return 1L;
     }
 
@@ -388,6 +448,23 @@ public class OaUniversalServiceImpl implements OaUniversalService {
         // 保存业务uuid到附件中
         fileApi.updateFileBiz(reCommitReqVO.getFileIdList(), oaUniversalNew.getUniversalId());
 
+        // 给审批人发送审批站内信
+        Long assigneeId = -1L;
+        String assigneeName = "";
+        String applyName = loginEmployee.getName();
+        String processName = ProcessKeyEnum.getByProcessKey(PROCESS_KEY);
+
+        String assignee = nextTask.getAssignee();
+        if (StrUtil.isNotBlank(assignee)) {
+            EmployeeRespDTO assigneeEmployee = employeeApi.getEmployeeById(Long.valueOf(assignee));
+            if (assigneeEmployee != null) {
+                assigneeId = assigneeEmployee.getId();
+                assigneeName = assigneeEmployee.getName();
+            }
+        }
+        StringBuilder content = OANotifyContentUtil.buildContentSendToAssignee(assigneeName, applyName, processName);
+        notifyMessageSendApi.sendSingleMessageToMemberForOA(assigneeId, content.toString());
+
         return 1L;
     }
 

+ 46 - 0
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/OANotifyContentUtil.java

@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.bpm.util;
+
+public class OANotifyContentUtil {
+
+    /**
+     * 构建审批通知内容
+     *
+     * @param assigneeName 审批人姓名
+     * @param applyName    申请人姓名
+     * @param processName  流程名称
+     * @return 通知内容
+     */
+    public static StringBuilder buildContentSendToAssignee(String assigneeName, String applyName, String processName) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(assigneeName).append(":您好,").append(applyName).append("发起的")
+                .append(processName).append("申请单已到您处,请及时处理。详情请在审批中心-我的待办查看,谢谢!");
+        return builder;
+    }
+
+    /**
+     * 构建审批驳回通知内容
+     *
+     * @param assigneeName 当前审批人姓名
+     * @param applyName    申请人姓名
+     * @param processName  流程名称
+     * @return 通知内容
+     */
+    public static StringBuilder buildContentSendToApplyForDisagree(String assigneeName, String applyName, String processName) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(applyName).append(":您好,您的").append(processName).append("申请单已被").append(assigneeName).append("驳回。详情请在审批中心-我的待办查看,谢谢!");
+        return builder;
+    }
+
+    /**
+     * 构建审批完成通知内容
+     *
+     * @param applyName    申请人姓名
+     * @param processName  流程名称
+     * @return 通知内容
+     */
+    public static StringBuilder buildContentSendToApplyForComplete(String applyName, String processName) {
+        StringBuilder builder = new StringBuilder();
+        builder.append(applyName).append(":您好,您的").append(processName).append("申请单已审批通过。详情请在审批中心-已发起中查看,谢谢!");
+        return builder;
+    }
+}

+ 10 - 0
yudao-module-finance/yudao-module-cash-biz/pom.xml

@@ -37,6 +37,16 @@
             <artifactId>yudao-module-employee-api</artifactId>
             <version>${revision}</version>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-customer-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-module-contract-api</artifactId>
+            <version>${revision}</version>
+        </dependency>
 
         <!-- 业务组件 -->
         <dependency>

+ 43 - 0
yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/RefundInfoController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.cash.controller.admin.refundinfo;
 
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -11,6 +12,12 @@ import cn.iocoder.yudao.module.cash.controller.admin.refundinfo.vo.RefundInfoRes
 import cn.iocoder.yudao.module.cash.controller.admin.refundinfo.vo.RefundInfoSaveReqVO;
 import cn.iocoder.yudao.module.cash.dal.dataobject.refundinfo.RefundInfoDO;
 import cn.iocoder.yudao.module.cash.service.refundinfo.RefundInfoService;
+import cn.iocoder.yudao.module.contract.api.customercontract.CustomerContractApi;
+import cn.iocoder.yudao.module.contract.api.customercontract.dto.CustomerContractDTO;
+import cn.iocoder.yudao.module.customer.api.info.CustomerInfoApi;
+import cn.iocoder.yudao.module.customer.api.info.dto.CustomerInfoDTO;
+import cn.iocoder.yudao.module.employee.api.EmployeeApi;
+import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@@ -42,6 +49,15 @@ public class RefundInfoController {
     @Resource
     private FileApi fileApi;
 
+    @Resource
+    private EmployeeApi employeeApi;
+
+    @Resource
+    private CustomerInfoApi customerInfoApi;
+
+    @Resource
+    private CustomerContractApi customerContractApi;
+
     @PostMapping("/create")
     @Operation(summary = "创建回款信息")
     @ApiOperationSupport(order = 1)
@@ -78,6 +94,33 @@ public class RefundInfoController {
         RefundInfoDO refundInfo = refundInfoService.getRefundInfo(id);
         RefundInfoRespVO refundInfoRespVO = BeanUtils.toBean(refundInfo, RefundInfoRespVO.class);
 
+        // 客户名称
+        Long customerId = refundInfo.getCustomerId();
+        if (customerId != null) {
+            CustomerInfoDTO customerInfo = customerInfoApi.getCustomerInfo(customerId);
+            if (customerInfo != null) {
+                refundInfoRespVO.setCustomerName(customerInfo.getCustomerName());
+                refundInfoRespVO.setCustomerCode(customerInfo.getCustomerCode());
+            }
+        }
+
+        // 合同名称
+        Long contractId = refundInfo.getContractId();
+        if (contractId != null) {
+            CustomerContractDTO customerContract = customerContractApi.getCustomerContract(contractId);
+            if (customerContract != null) {
+                refundInfoRespVO.setContractName(customerContract.getCustomerContractName());
+                refundInfoRespVO.setContractCode(customerContract.getCustomerContractCode());
+            }
+        }
+
+        // 创建人姓名
+        String creator = refundInfo.getCreator();
+        if (StrUtil.isNotBlank(creator)) {
+            EmployeeRespDTO creatorName = employeeApi.getEmployeeById(Long.valueOf(creator));
+            refundInfoRespVO.setCreatorName(creatorName.getName());
+        }
+
         // 附件列表
         List<FileDTO> fileList = fileApi.getFileDTOListByBiz(refundInfoRespVO.getRefundInfoUuid());
         refundInfoRespVO.setFileList(fileList);

+ 2 - 2
yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/vo/RefundInfoPageReqVO.java

@@ -21,8 +21,8 @@ public class RefundInfoPageReqVO extends PageParam {
     @Schema(description = "回款编号:年月日+uuid")
     private String refundInfoUuid;
 
-    @Schema(description = "客户名称")
-    private String customerName;
+    @Schema(description = "客户id")
+    private Long customerId;
 
     @Schema(description = "合同名称")
     private Long contractName;

+ 0 - 1
yudao-module-finance/yudao-module-cash-biz/src/main/java/cn/iocoder/yudao/module/cash/controller/admin/refundinfo/vo/RefundInfoSaveReqVO.java

@@ -25,7 +25,6 @@ public class RefundInfoSaveReqVO {
     private Long customerId;
 
     @Schema(description = "合同id", example = "1")
-    @NotNull(message = "合同id不能为空")
     private Long contractId;
 
     @Schema(description = "回款日期", example = "2024-08-07")

+ 14 - 10
yudao-module-finance/yudao-module-cash-biz/src/main/resources/mapper/refundinfo/RefundInfoMapper.xml

@@ -15,6 +15,8 @@
         FROM
             finance_refund_info fri
         LEFT JOIN employee_info ei ON fri.creator = ei.id AND ei.deleted = 0
+        LEFT JOIN customer_info ci ON fri.customer_id = ci.id AND ci.deleted = 0
+        LEFT JOIN finance_customer_contract fcc ON fri.contract_id = fcc.id AND fcc.deleted = 0
         WHERE
             fri.deleted = 0
         <if test="page.refundTitle != null and page.refundTitle != ''">
@@ -23,11 +25,11 @@
         <if test="page.refundInfoUuid != null and page.refundInfoUuid != ''">
             AND fri.refund_info_uuid like concat('%',#{page.refundInfoUuid},'%')
         </if>
-        <if test="page.customerName != null and page.customerName != ''">
-            AND fri.customer_id like concat('%',#{page.customerName},'%')
+        <if test="page.customerId != null">
+            AND fri.customer_id like concat('%',#{page.customerId},'%')
         </if>
         <if test="page.contractName != null and page.contractName != ''">
-            AND fri.contract_id like concat('%',#{page.contractName},'%')
+            AND fcc.customer_contract_name like concat('%',#{page.contractName},'%')
         </if>
         <if test="page.refundDate != null and page.refundDate.length > 0">
             AND fri.refund_date BETWEEN #{page.refundDate[0]} AND #{page.refundDate[1]}
@@ -45,11 +47,11 @@
             fri.refund_info_uuid,
             fri.refund_title,
             fri.customer_id,
-           '客户名称' customerName,
-           '客户编码' customerCode,
+            ci.customer_name customerName,
+            ci.customer_code customerCode,
             fri.contract_id,
-           '合同名称' contractName,
-           '合同编码' contractCode,
+            fcc.customer_contract_name contractName,
+            fcc.customer_contract_code contractCode,
             fri.refund_date,
             fri.refund_money,
             fri.refund_cycle,
@@ -69,6 +71,8 @@
         FROM
             finance_refund_info fri
                 LEFT JOIN employee_info ei ON fri.creator = ei.id AND ei.deleted = 0
+                LEFT JOIN customer_info ci ON fri.customer_id = ci.id AND ci.deleted = 0
+                LEFT JOIN finance_customer_contract fcc ON fri.contract_id = fcc.id AND fcc.deleted = 0
         WHERE
             fri.deleted = 0
         <if test="page.refundTitle != null and page.refundTitle != ''">
@@ -77,11 +81,11 @@
         <if test="page.refundInfoUuid != null and page.refundInfoUuid != ''">
             AND fri.refund_info_uuid like concat('%',#{page.refundInfoUuid},'%')
         </if>
-        <if test="page.customerName != null and page.customerName != ''">
-            AND fri.customer_id like concat('%',#{page.customerName},'%')
+        <if test="page.customerId != null">
+            AND fri.customer_id like concat('%',#{page.customerId},'%')
         </if>
         <if test="page.contractName != null and page.contractName != ''">
-            AND fri.contract_id like concat('%',#{page.contractName},'%')
+            AND fcc.customer_contract_name like concat('%',#{page.contractName},'%')
         </if>
         <if test="page.refundDate != null and page.refundDate.length > 0">
             AND fri.refund_date BETWEEN #{page.refundDate[0]} AND #{page.refundDate[1]}

+ 14 - 0
yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/CustomerContractApi.java

@@ -0,0 +1,14 @@
+package cn.iocoder.yudao.module.contract.api.customercontract;
+
+import cn.iocoder.yudao.module.contract.api.customercontract.dto.CustomerContractDTO;
+
+public interface CustomerContractApi {
+
+    /**
+     * 获得销售合同信息
+     *
+     * @param id 主键id
+     * @return 销售合同信息
+     */
+    CustomerContractDTO getCustomerContract(Long id);
+}

+ 62 - 0
yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/dto/CustomerContractDTO.java

@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.contract.api.customercontract.dto;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class CustomerContractDTO {
+
+    /**
+     * 主键id
+     */
+    private Long id;
+    /**
+     * uuid
+     */
+    private String customerContractUuid;
+    /**
+     * 合同编号,年月日+uuid
+     */
+    private String customerContractCode;
+    /**
+     * 合同名称
+     */
+    private String customerContractName;
+    /**
+     * 客户id
+     */
+    private Long customerId;
+    /**
+     * 合同开始日期
+     */
+    private String startDate;
+    /**
+     * 合同结束日期
+     */
+    private String endDate;
+    /**
+     * 合同金额
+     */
+    private BigDecimal money;
+    /**
+     * 合同负责人
+     */
+    private Long ownerEmployeeId;
+    /**
+     * 负责人部门
+     */
+    private Long deptId;
+    /**
+     * 合同状态:0、未归档;1、已归档;2、已完结
+     */
+    private String contractStatus;
+    /**
+     * 是否关闭 0开启 1关闭
+     */
+    private Integer closed;
+    /**
+     * 是否终止 0否 1是
+     */
+    private Integer terminate;
+}

+ 2 - 0
yudao-module-finance/yudao-module-contract-api/src/main/java/cn/iocoder/yudao/module/contract/enums/ErrorCodeConstants.java

@@ -7,6 +7,7 @@ public interface ErrorCodeConstants {
     ErrorCode SUPPLIER_CONTRACT_NOT_EXISTS = new ErrorCode(1_052_000_001, "采购合同信息不存在");
     ErrorCode SUPPLIER_CONTRACT_NOT_CLOSED = new ErrorCode(1_052_000_002, "采购合同已经是开启状态");
     ErrorCode SUPPLIER_CONTRACT_CODE_EXISTS = new ErrorCode(1_052_000_003, "采购合同编号已存在");
+    ErrorCode SUPPLIER_CONTRACT_NAME_EXISTS = new ErrorCode(1_052_000_004, "采购合同名称已存在");
     // ========== 采购合同历史信息 1_052_001_001 ==========
     ErrorCode SUPPLIER_CONTRACT_HISTORY_NOT_EXISTS = new ErrorCode(1_052_001_001, "采购合同历史信息不存在");
 
@@ -14,6 +15,7 @@ public interface ErrorCodeConstants {
     ErrorCode CUSTOMER_CONTRACT_NOT_EXISTS = new ErrorCode(1_052_002_001, "销售合同信息不存在");
     ErrorCode CUSTOMER_CONTRACT_NOT_CLOSED = new ErrorCode(1_052_002_002, "销售合同已经是开启状态");
     ErrorCode CUSTOMER_CONTRACT_CODE_EXISTS = new ErrorCode(1_052_002_003, "销售合同编号已存在");
+    ErrorCode CUSTOMER_CONTRACT_NAME_EXISTS = new ErrorCode(1_052_002_004, "销售合同名称已存在");
     // ========== 销售合同历史信息 1_052_003_001 ==========
     ErrorCode CUSTOMER_CONTRACT_HISTORY_NOT_EXISTS = new ErrorCode(1_052_003_001, "销售合同历史信息不存在");
 

+ 22 - 0
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/api/customercontract/CustomerContractApiImpl.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.contract.api.customercontract;
+
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.contract.api.customercontract.dto.CustomerContractDTO;
+import cn.iocoder.yudao.module.contract.dal.dataobject.customercontract.CustomerContractDO;
+import cn.iocoder.yudao.module.contract.service.customercontract.CustomerContractService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+@Service
+public class CustomerContractApiImpl implements CustomerContractApi {
+
+    @Resource
+    private CustomerContractService customerContractService;
+
+    @Override
+    public CustomerContractDTO getCustomerContract(Long id) {
+        CustomerContractDO customerContract = customerContractService.getCustomerContract(id);
+        return BeanUtils.toBean(customerContract, CustomerContractDTO.class);
+    }
+}

+ 10 - 0
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/customercontract/CustomerContractController.java

@@ -160,6 +160,16 @@ public class CustomerContractController {
         return success(pageResult);
     }
 
+    @GetMapping("/list")
+    @Operation(summary = "获得销售合同信息列表,closed:0开启1关闭")
+    @ApiOperationSupport(order = 6)
+    // @PreAuthorize("@ss.hasPermission('contract:customer-contract:query')")
+    public CommonResult<List<CustomerContractListVO>> getCustomerContractList(@Valid @ParameterObject CustomerContractListVO listVO) {
+        List<CustomerContractDO> listResult = customerContractService.getCustomerContractList(listVO);
+        List<CustomerContractListVO> listVOList = BeanUtils.toBean(listResult, CustomerContractListVO.class);
+        return success(listVOList);
+    }
+
     @GetMapping("/export-excel")
     @Operation(summary = "导出销售合同信息 Excel")
     @ApiOperationSupport(order = 7)

+ 30 - 0
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/controller/admin/customercontract/vo/CustomerContractListVO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "销售合同信息列表 Request VO")
+@Data
+public class CustomerContractListVO {
+
+    @Schema(description = "主键id")
+    private Long id;
+
+    @Schema(description = "合同编号,年月日+uuid")
+    private String customerContractCode;
+
+    @Schema(description = "合同名称")
+    private String customerContractName;
+
+    @Schema(description = "客户id,不传客户id返回空列表")
+    private Long customerId;
+
+    @Schema(description = "合同开始日期")
+    private String startDate;
+
+    @Schema(description = "合同结束日期")
+    private String endDate;
+
+    @Schema(description = "是否关闭 0开启 1关闭")
+    private Integer closed;
+}

+ 16 - 1
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/customercontract/CustomerContractService.java

@@ -2,11 +2,18 @@ package cn.iocoder.yudao.module.contract.service.customercontract;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.*;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractCloseReqVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractListVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractPageReqVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractRespVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractSaveReqVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractStatusReqVO;
+import cn.iocoder.yudao.module.contract.controller.admin.customercontract.vo.CustomerContractTerminatedReqVO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.customercontract.CustomerContractDO;
 import cn.iocoder.yudao.module.contract.dal.dataobject.customercontract.CustomerContractHistoryDO;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 销售合同信息 Service 接口
@@ -61,6 +68,14 @@ public interface CustomerContractService {
      */
     PageResult<CustomerContractRespVO> getCustomerContractPage(CustomerContractPageReqVO pageReqVO);
 
+    /**
+     * 获得销售合同信息列表
+     *
+     * @param listVO 列表查询
+     * @return 销售合同信息列表
+     */
+    List<CustomerContractDO> getCustomerContractList(CustomerContractListVO listVO);
+
     /**
      * 开启销售合同
      *

+ 41 - 0
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/customercontract/CustomerContractServiceImpl.java

@@ -18,13 +18,16 @@ import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
+import org.w3c.dom.ls.LSException;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.List;
 import java.util.Objects;
@@ -74,6 +77,10 @@ public class CustomerContractServiceImpl implements CustomerContractService {
         if (StrUtil.isNotBlank(customerContractCode)) {
             validateCustomerContractCode(customerContractCode);
         }
+        String customerContractName = createReqVO.getCustomerContractName();
+        if (StrUtil.isNotBlank(customerContractName)) {
+            validateCustomerContractName(customerContractName, createReqVO.getId());
+        }
         // 插入
         CustomerContractDO customerContract = BeanUtils.toBean(createReqVO, CustomerContractDO.class);
         // uuid
@@ -111,6 +118,17 @@ public class CustomerContractServiceImpl implements CustomerContractService {
         return customerContract.getId();
     }
 
+    private void validateCustomerContractName(String customerContractName, Long id) {
+        LambdaQueryWrapper<CustomerContractDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(CustomerContractDO::getCustomerContractName, customerContractName);
+        if (Objects.nonNull(id)) {
+            lambdaQueryWrapper.ne(CustomerContractDO::getId, id);
+        }
+        if (customerContractMapper.selectCount(lambdaQueryWrapper) > 0) {
+            throw exception(CUSTOMER_CONTRACT_NAME_EXISTS);
+        }
+    }
+
     private void validateCustomerContractCode(String customerContractCode) {
         Long aLong = customerContractMapper.selectCount(CustomerContractDO::getCustomerContractCode, customerContractCode);
         if (aLong > 0) {
@@ -122,6 +140,10 @@ public class CustomerContractServiceImpl implements CustomerContractService {
     public void updateCustomerContract(CustomerContractSaveReqVO updateReqVO) {
         // 校验存在
         CustomerContractDO customerContractDO = validateCustomerContractExists(updateReqVO.getId());
+        String customerContractName = updateReqVO.getCustomerContractName();
+        if (StrUtil.isNotBlank(customerContractName)) {
+            validateCustomerContractName(customerContractName, updateReqVO.getId());
+        }
         // 更新
         CustomerContractDO updateObj = BeanUtils.toBean(updateReqVO, CustomerContractDO.class);
         // 负责人及部门
@@ -190,6 +212,25 @@ public class CustomerContractServiceImpl implements CustomerContractService {
         return new PageResult<>(pageList, pageCount);
     }
 
+    @Override
+    public List<CustomerContractDO> getCustomerContractList(CustomerContractListVO listVO) {
+        // Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
+        // EmployeeRespDTO loginEmployee = employeeApi.getEmployeeByUserId(loginUserId);
+        // if (loginEmployee == null || loginEmployee.getDeptId() == null) {
+        //     // 没有员工信息或部门信息,返回空集合
+        //     return Collections.emptyList();
+        // }
+        if (listVO.getCustomerId() == null) {
+            // 没有客户id,返回空集合
+            return Collections.emptyList();
+        }
+        LambdaQueryWrapper<CustomerContractDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(CustomerContractDO::getCustomerId, listVO.getCustomerId())
+                .eq(listVO.getClosed() != null, CustomerContractDO::getClosed, listVO.getClosed());
+        return customerContractMapper.selectList(lambdaQueryWrapper);
+
+    }
+
     @Override
     public Integer openCustomerContract(Long id) {
         CustomerContractDO customerContractDO = validateCustomerContractExists(id);

+ 20 - 0
yudao-module-finance/yudao-module-contract-biz/src/main/java/cn/iocoder/yudao/module/contract/service/suppliercontract/SupplierContractServiceImpl.java

@@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.employee.api.EmployeeApi;
 import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -73,6 +74,10 @@ public class SupplierContractServiceImpl implements SupplierContractService {
         if (StrUtil.isNotBlank(supplierContractCode)) {
             validateSupplierContractCode(supplierContractCode);
         }
+        String supplierContractName = createReqVO.getSupplierContractName();
+        if (StrUtil.isNotBlank(supplierContractName)) {
+            validateSupplierContractName(supplierContractName, createReqVO.getId());
+        }
         // 插入
         SupplierContractDO supplierContract = BeanUtils.toBean(createReqVO, SupplierContractDO.class);
         // uuid
@@ -110,6 +115,17 @@ public class SupplierContractServiceImpl implements SupplierContractService {
         return supplierContract.getId();
     }
 
+    private void validateSupplierContractName(String supplierContractName, Long id) {
+        LambdaQueryWrapper<SupplierContractDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(SupplierContractDO::getSupplierContractName, supplierContractName);
+        if (Objects.nonNull(id)) {
+            lambdaQueryWrapper.ne(SupplierContractDO::getId, id);
+        }
+        if (supplierContractMapper.selectCount(lambdaQueryWrapper) > 0) {
+            throw exception(SUPPLIER_CONTRACT_NAME_EXISTS);
+        }
+    }
+
     private void validateSupplierContractCode(String supplierContractCode) {
         Long aLong = supplierContractMapper.selectCount(SupplierContractDO::getSupplierContractCode, supplierContractCode);
         if (aLong > 0) {
@@ -121,6 +137,10 @@ public class SupplierContractServiceImpl implements SupplierContractService {
     public void updateSupplierContract(SupplierContractSaveReqVO updateReqVO) {
         // 校验存在
         SupplierContractDO supplierContractDO = validateSupplierContractExists(updateReqVO.getId());
+        String supplierContractName = updateReqVO.getSupplierContractName();
+        if (StrUtil.isNotBlank(supplierContractName)) {
+            validateSupplierContractName(supplierContractName, updateReqVO.getId());
+        }
         // 更新
         SupplierContractDO updateObj = BeanUtils.toBean(updateReqVO, SupplierContractDO.class);
         // 负责人及部门

+ 9 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApi.java

@@ -27,4 +27,13 @@ public interface NotifyMessageSendApi {
      */
     Long sendSingleMessageToMember(@Valid NotifySendSingleToUserReqDTO reqDTO);
 
+    /**
+     * OA模块发送站内信
+     *
+     * @param employeeId 收信员工id
+     * @param content    内容
+     * @return 发送消息 ID
+     */
+    Long sendSingleMessageToMemberForOA(Long employeeId, String content);
+
 }

+ 11 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/notify/NotifyTemplateTypeConstants.java

@@ -0,0 +1,11 @@
+package cn.iocoder.yudao.module.system.enums.notify;
+
+public interface NotifyTemplateTypeConstants {
+
+    /**
+     * 系统消息
+     */
+    String SYSTEM_MESSAGE = "SYSTEM_MESSAGE";
+
+
+}

+ 16 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/notify/NotifyMessageSendApiImpl.java

@@ -1,10 +1,14 @@
 package cn.iocoder.yudao.module.system.api.notify;
 
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
+import cn.iocoder.yudao.module.system.enums.notify.NotifyTemplateTypeConstants;
 import cn.iocoder.yudao.module.system.service.notify.NotifySendService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * 站内信发送 API 实现类
@@ -29,4 +33,16 @@ public class NotifyMessageSendApiImpl implements NotifyMessageSendApi {
                 reqDTO.getTemplateCode(), reqDTO.getTemplateParams());
     }
 
+    @Override
+    public Long sendSingleMessageToMemberForOA(Long employeeId, String content) {
+        if (employeeId == null || StrUtil.isBlank(content)) {
+            return -1L;
+        }
+        // 使用定义好的模版
+        String templateCode = NotifyTemplateTypeConstants.SYSTEM_MESSAGE;
+        Map<String, Object> templateParams = new HashMap<>();
+        templateParams.put("content", content);
+        return notifySendService.sendSingleNotifyToMember(employeeId, templateCode, templateParams);
+    }
+
 }

+ 13 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java

@@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.employee.api.EmployeeApi;
+import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageRespVO;
@@ -21,8 +23,10 @@ import javax.annotation.Resource;
 import javax.validation.Valid;
 import java.util.List;
 
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+import static cn.iocoder.yudao.module.employee.enums.ErrorCodeConstants.EMPLOYEE_INFO_NOT_EXISTS;
 
 @Tag(name = "管理后台 - 我的站内信")
 @RestController
@@ -33,6 +37,9 @@ public class NotifyMessageController {
     @Resource
     private NotifyMessageService notifyMessageService;
 
+    @Resource
+    private EmployeeApi employeeApi;
+
     // ========== 管理所有的站内信 ==========
 
     @GetMapping("/get")
@@ -82,8 +89,13 @@ public class NotifyMessageController {
     @Parameter(name = "size", description = "10")
     public CommonResult<List<NotifyMessageRespVO>> getUnreadNotifyMessageList(
             @RequestParam(name = "size", defaultValue = "10") Integer size) {
+        Long loginUserId = getLoginUserId();
+        EmployeeRespDTO loginEmployee = employeeApi.getEmployeeByUserId(loginUserId);
+        if (loginEmployee == null) {
+            throw exception(EMPLOYEE_INFO_NOT_EXISTS);
+        }
         List<NotifyMessageDO> list = notifyMessageService.getUnreadNotifyMessageList(
-                getLoginUserId(), UserTypeEnum.ADMIN.getValue(), size);
+                loginEmployee.getId(), UserTypeEnum.MEMBER.getValue(), size);
         return success(BeanUtils.toBean(list, NotifyMessageRespVO.class));
     }