Browse Source

流程信息添加未处理消息提醒

大数据与最优化研究所 1 year ago
parent
commit
e6ccab37a5

+ 109 - 0
src/main/java/com/xjrsoft/module/job/ProcessNotProcessingAlertTask.java

@@ -0,0 +1,109 @@
+package com.xjrsoft.module.job;
+
+import cn.hutool.db.Db;
+import cn.hutool.db.Entity;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.utils.DatasourceUtil;
+import com.xjrsoft.common.utils.DateUtils;
+import com.xjrsoft.module.evaluate.entity.EvaluateManage;
+import com.xjrsoft.module.oa.utils.SendMessageUtil;
+import com.xjrsoft.module.workflow.entity.WorkflowExtra;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+/**
+ * 流程未处理提醒
+ */
+@Component
+@Slf4j
+public class ProcessNotProcessingAlertTask {
+    /**
+     * 流程未处理提醒
+     */
+    @Scheduled(cron = "0 0 14 * * ?")
+    public void alertProcessNotProcessing() {
+        System.out.printf("定时提醒流程未处理:%s", DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
+        DataSource datasource = DatasourceUtil.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
+        try {
+            Db use = Db.use(datasource);
+
+            //获取未结束流程的流程id
+            String listUncloseProcessIdSql = "SELECT DISTINCT process_id " +
+                    "FROM xjr_workflow_record w1 " +
+                    "WHERE NOT EXISTS ( " +
+                    "        SELECT 1 " +
+                    "        FROM xjr_workflow_record w2 " +
+                    "        WHERE w2.node_id = 'Event_140v10k' " +
+                    "          AND w1.process_id = w2.process_id " +
+                    "    );";
+            List<Entity> listUncloseProcessId = use.query(listUncloseProcessIdSql);
+
+            if(!listUncloseProcessId.isEmpty()){
+                //获取所有未完成流程的所有节点
+                String uncloseProcessIdStr = listUncloseProcessId.stream()
+                        .map(entity -> "'" + entity.getStr("process_id") + "'")
+                        .collect(Collectors.joining(","));
+                String listWorkflowExtraSql = "select * " +
+                        "from xjr_workflow_extra "
+                        + "where process_id in (" + uncloseProcessIdStr + ");";;
+                List<WorkflowExtra> workflowExtraList = use.query(listWorkflowExtraSql, WorkflowExtra.class);
+
+                List<String> uncloseProcessIdList = listUncloseProcessId.stream()
+                        .map(entity -> entity.getStr("process_id"))
+                        .collect(Collectors.toList());
+
+                //筛选出每个流程的最后一个节点的记录,需要的是有任务节点id的记录
+                List<WorkflowExtra> workflowExtraLastNodeList = new ArrayList<>();
+                LocalDateTime now = LocalDateTime.now();
+                for(String processId : uncloseProcessIdList){
+                    workflowExtraList.stream()
+                            .filter(e -> e.getProcessId().equals(processId))
+                            .max(Comparator.comparing(WorkflowExtra::getStartTime))
+                            .ifPresent(e -> {
+                                if((e.getEndTime() == null || e.getEndTime().toString().equals("")) && e.getApproveUserIds() != null && !e.getApproveUserIds().equals("")){
+                                    // 计算两个时间之间的差值
+                                    Duration duration = Duration.between(e.getStartTime(), now);
+                                    if (duration.toHours() > 24) {
+                                        //System.out.println("时间差大于24小时");
+                                        workflowExtraLastNodeList.add(e);
+                                    }
+                                }
+                            });
+                }
+
+                //对未结束的流程节点进行处理,通知下一个节点需要处理的人
+                Map<String, StringBuilder> message = new HashMap<>();
+                for (WorkflowExtra w : workflowExtraLastNodeList){
+                    String approveUserIds = w.getApproveUserIds();
+                    String[] aapproveUserIdArray = approveUserIds.trim().split(",");
+                    for (String str : aapproveUserIdArray){
+                        if(message.containsKey(str)){
+                            message.get(str).append(",").append(w.getProcessName());
+                        }else {
+                            message.put(str, new StringBuilder(w.getProcessName()));
+                        }
+                    }
+                }
+
+//                SendMessageUtil.sendWorkflowUnapprovedWx(message);
+
+                CompletableFuture.runAsync(() -> {
+                    SendMessageUtil.sendWorkflowUnapprovedWx(message);
+                });
+
+//                System.err.println(workflowExtraLastNodeList.size());
+//                System.err.println(workflowExtraLastNodeList.get(0));
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage(), "定时提醒流程未处理");
+        }
+    }
+}

+ 66 - 0
src/main/java/com/xjrsoft/module/oa/utils/SendMessageUtil.java

@@ -25,6 +25,7 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -125,6 +126,71 @@ public class SendMessageUtil {
         }
     }
 
+    /**
+     * 发送工作流未审批微信消息
+     */
+    public static void sendWorkflowUnapprovedWx(Map<String, StringBuilder> message) {
+        IUserService userService = SpringUtil.getBean(IUserService.class);
+        RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
+
+        WeChatUtil weChatUtil = SpringUtil.getBean(WeChatUtil.class);
+
+        CommonPropertiesConfig cpConfig = SpringUtil.getBean(CommonPropertiesConfig.class);
+
+        //获取用户相关信息
+        List<User> userList = redisUtil.get(GlobalConstant.USER_CACHE_KEY, new TypeReference<List<User>>() {
+        });
+        //如果缓存中不存在用户信息,就直接去数据库查询,并保存到缓存中去
+        if (userList.size() == 0) {
+            userList = userService.list();
+            redisUtil.set(GlobalConstant.USER_CACHE_KEY, userList);
+        }
+
+        for (Map.Entry<String, StringBuilder> entry : message.entrySet()) {
+            String key = entry.getKey();
+            StringBuilder value = entry.getValue();
+//            System.out.println(key + "--" + value);
+            // 处理每个用户
+            User user = userList.stream().filter(u -> key.equals(u.getId())).findFirst().orElse(new User());
+            String openId = user.getOpenId();
+//            System.err.println(openId);
+            if (StrUtil.isEmpty(openId)) {
+                continue;
+            }
+
+            JSONObject data = new JSONObject();
+            // 任务名称
+            data.put("thing8", new JSONObject() {{
+                put("value", value.toString());
+            }});
+            // 事项名称
+            data.put("thing2", new JSONObject() {{
+                put("value", value.toString());
+            }});
+            // 申请人
+            data.put("thing6", new JSONObject() {{
+                put("value", "");
+            }});
+            // 时间
+            data.put("time3", new JSONObject() {{
+                put("value", LocalDateTimeUtil.format(LocalDateTime.now(), LocalDateTimeUtil.LOCAL_DATE_TIME_FORMAT));
+            }});
+
+            JSONObject object = new JSONObject();
+            object.put("touser", openId);
+            object.put("template_id", "sHsmz7LRj7HLd7GSTS3r2jCLvK-4Wp19iGzEvYK8n_I");
+//                object.put("miniprogram", new JSONObject() {{
+//                    put("appid", weChatUtil.getAppletAppKey());
+//                    put("pagepath", StrUtil.format("{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo",cpConfig.getDomainApp(), param.getTaskId(), param.getProcessId()));
+//                }});
+            object.put("url", StrUtil.format("{}/xjrsoft/pages/home/home",cpConfig.getDomainApp()));
+//            object.put("client_msg_id", param.getTaskId());
+            object.put("data", data);
+            Boolean isSuccess = weChatUtil.sendTemplateMessage(object);
+            //System.err.println(isSuccess);
+        }
+    }
+
     /**
      * 添加工作流审批消息
      */

+ 1 - 1
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookServiceImpl.java

@@ -709,7 +709,7 @@ public class TextbookServiceImpl extends MPJBaseServiceImpl<TextbookMapper, Text
                             subtotalColumn.add(rowIndex + vv.size() + 2, 1, 4);
                             BigDecimal subtotal = new BigDecimal("0");
                             for (TextbookClaimExportQueryVo tv : vv) {
-                                subtotal = subtotal.add(tv.getSubtotal());
+                                subtotal = subtotal.add(tv.getSubtotal()==null?new BigDecimal("0"):tv.getSubtotal());
                             }
                             BigDecimal finalSubtotal = subtotal;
                             vv.add(new TextbookClaimExportQueryVo(){{

+ 0 - 1
src/main/java/com/xjrsoft/module/workflow/controller/WorkflowExecuteController.java

@@ -51,7 +51,6 @@ public class WorkflowExecuteController {
         return R.ok(workflowExecuteService.getStartProcessInfo(schemaId));
     }
 
-
     @GetMapping("/approve-process-info")
     @ApiOperation(value = "审批流程所需要的信息")
     public R approveProcessInfo(@RequestParam String taskId) {

+ 107 - 0
src/test/java/com/xjrsoft/module/job/ProcessNotProcessingAlertTaskTest.java

@@ -0,0 +1,107 @@
+package com.xjrsoft.module.job;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.db.Db;
+import cn.hutool.db.Entity;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.xjrsoft.common.utils.DatasourceUtil;
+import com.xjrsoft.common.utils.DateUtils;
+import com.xjrsoft.module.oa.service.INewsService;
+import com.xjrsoft.module.oa.utils.SendMessageUtil;
+import com.xjrsoft.module.workflow.constant.WorkflowConstant;
+import com.xjrsoft.module.workflow.entity.WorkflowExtra;
+import com.xjrsoft.module.workflow.vo.MyProcessPageVo;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.sql.DataSource;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
+import static org.junit.jupiter.api.Assertions.*;
+@SpringBootTest
+class ProcessNotProcessingAlertTaskTest {
+
+    @Test
+    void alertProcessNotProcessing() {
+        DataSource datasource = DatasourceUtil.getDataSource(GlobalConstant.DEFAULT_DATASOURCE_KEY);
+        try {
+            Db use = Db.use(datasource);
+
+            //获取未结束流程的流程id
+            String listUncloseProcessIdSql = "SELECT DISTINCT process_id " +
+                    "FROM xjr_workflow_record w1 " +
+                    "WHERE NOT EXISTS ( " +
+                    "        SELECT 1 " +
+                    "        FROM xjr_workflow_record w2 " +
+                    "        WHERE w2.node_id = 'Event_140v10k' " +
+                    "          AND w1.process_id = w2.process_id " +
+                    "    );";
+            List<Entity> listUncloseProcessId = use.query(listUncloseProcessIdSql);
+
+            if(!listUncloseProcessId.isEmpty()){
+                //获取所有未完成流程的所有节点
+                String uncloseProcessIdStr = listUncloseProcessId.stream()
+                        .map(entity -> "'" + entity.getStr("process_id") + "'")
+                        .collect(Collectors.joining(","));
+                String listWorkflowExtraSql = "select * " +
+                        "from xjr_workflow_extra "
+                        + "where process_id in (" + uncloseProcessIdStr + ");";;
+                List<WorkflowExtra> workflowExtraList = use.query(listWorkflowExtraSql, WorkflowExtra.class);
+
+                List<String> uncloseProcessIdList = listUncloseProcessId.stream()
+                        .map(entity -> entity.getStr("process_id"))
+                        .collect(Collectors.toList());
+
+                //筛选出每个流程的最后一个节点的记录,需要的是有任务节点id的记录
+                List<WorkflowExtra> workflowExtraLastNodeList = new ArrayList<>();
+                LocalDateTime now = LocalDateTime.now();
+                for(String processId : uncloseProcessIdList){
+                    workflowExtraList.stream()
+                            .filter(e -> e.getProcessId().equals(processId))
+                            .max(Comparator.comparing(WorkflowExtra::getStartTime))
+                            .ifPresent(e -> {
+                                if((e.getEndTime() == null || e.getEndTime().toString().equals("")) && e.getApproveUserIds() != null && !e.getApproveUserIds().equals("")){
+                                    // 计算两个时间之间的差值
+                                    Duration duration = Duration.between(e.getStartTime(), now);
+                                    if (duration.toHours() > 24) {
+                                        System.out.println("时间差大于24小时");
+                                        workflowExtraLastNodeList.add(e);
+                                    }
+                                }
+                            });
+                }
+
+                //对未结束的流程节点进行处理,通知下一个节点需要处理的人
+                Map<String, StringBuilder> message = new HashMap<>();
+                for (WorkflowExtra w : workflowExtraLastNodeList){
+                    String approveUserIds = w.getApproveUserIds();
+                    String[] aapproveUserIdArray = approveUserIds.trim().split(",");
+                    for (String str : aapproveUserIdArray){
+                        System.err.println(str);
+                        if(message.containsKey(str)){
+                            message.get(str).append(",").append(w.getProcessName());
+                        }else {
+                            message.put(str, new StringBuilder(w.getProcessName()));
+                        }
+                    }
+                }
+
+//                SendMessageUtil.sendWorkflowUnapprovedWx(message);
+
+                CompletableFuture.runAsync(() -> {
+                    SendMessageUtil.sendWorkflowUnapprovedWx(message);
+                });
+
+//                System.err.println(workflowExtraLastNodeList.size());
+//                System.err.println(workflowExtraLastNodeList.get(0));
+            }
+        } catch (Exception e) {
+            System.err.println(e.getMessage()+"定时提醒流程未处理");
+        }
+    }
+}