|
@@ -0,0 +1,128 @@
|
|
|
+package com.xjrsoft.module.job;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.google.gson.JsonObject;
|
|
|
+import com.google.gson.JsonParser;
|
|
|
+import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
|
|
|
+import com.xjrsoft.module.oa.utils.SendMessageUtil;
|
|
|
+import com.xjrsoft.module.workflow.entity.WorkflowAlertRecord;
|
|
|
+import com.xjrsoft.module.workflow.entity.WorkflowSchema;
|
|
|
+import com.xjrsoft.module.workflow.service.IWorkflowAlertRecordService;
|
|
|
+import com.xjrsoft.module.workflow.service.IWorkflowSchemaService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.camunda.bpm.engine.HistoryService;
|
|
|
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
|
|
|
+import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.time.Duration;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 流程未处理提醒申请人
|
|
|
+ */
|
|
|
+@Component
|
|
|
+@Slf4j
|
|
|
+public class ProcessTimeoutAlertTask {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private HistoryService historyService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWorkflowSchemaService schemaService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IWorkflowAlertRecordService alertRecordService;
|
|
|
+ @Scheduled(cron = "0 0 * * * ?")
|
|
|
+ public void execute() {
|
|
|
+ doExecute();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void doExecute(){
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ try {
|
|
|
+ HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery().unfinished();
|
|
|
+
|
|
|
+ List<HistoricProcessInstance> historicProcessInstances = historicProcessInstanceQuery.list();
|
|
|
+
|
|
|
+ List<String> processIds = historicProcessInstances.stream().map(HistoricProcessInstance::getId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if(!processIds.isEmpty()){
|
|
|
+ //获取所有未完成流程的所有节点
|
|
|
+ String uncloseProcessIdStr = processIds.stream()
|
|
|
+ .map(entity -> "'" + entity + "'")
|
|
|
+ .collect(Collectors.joining(","));
|
|
|
+ String listWorkflowExtraSql = "select * " +
|
|
|
+ "from xjr_workflow_extra "
|
|
|
+ + "where process_id in (" + uncloseProcessIdStr + ") and end_time is null;";
|
|
|
+ List<Map<String, Object>> workflowExtraList = SqlRunnerAdapter.db().selectList(listWorkflowExtraSql);
|
|
|
+
|
|
|
+ JsonParser parser = new JsonParser();
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ Map<String, StringBuilder> message = new HashMap<>();
|
|
|
+ List<WorkflowAlertRecord> recordList = new ArrayList<>();
|
|
|
+ for (Map<String, Object> el : workflowExtraList) {
|
|
|
+ WorkflowSchema schema = schemaService.getById(el.get("schema_id").toString());
|
|
|
+ JsonObject jsonContent = parser.parse(schema.getJsonContent()).getAsJsonObject();
|
|
|
+ JsonObject timeoutRemidConfig = jsonContent.get("processConfig").getAsJsonObject().get("timeoutRemidConfig").getAsJsonObject();
|
|
|
+ if(!timeoutRemidConfig.get("enabled").getAsBoolean()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String startUserId = el.get("start_user_id").toString();
|
|
|
+ List<WorkflowAlertRecord> record = alertRecordService.list(
|
|
|
+ new QueryWrapper<WorkflowAlertRecord>().lambda()
|
|
|
+ .eq(WorkflowAlertRecord::getUserId, Long.parseLong(startUserId))
|
|
|
+ .eq(WorkflowAlertRecord::getProcessId, Long.parseLong(el.get("process_id").toString()))
|
|
|
+ .eq(WorkflowAlertRecord::getType, 1)
|
|
|
+ .orderByDesc(WorkflowAlertRecord::getSendTime)
|
|
|
+ );
|
|
|
+ WorkflowAlertRecord alertRecord = record.get(0);
|
|
|
+ Duration lastBetween = Duration.between(alertRecord.getSendTime(), now);
|
|
|
+ long lasttime = Math.abs(lastBetween.getSeconds());
|
|
|
+
|
|
|
+ LocalDateTime startTime = LocalDateTime.parse(el.get("start_time").toString(), formatter);
|
|
|
+ Duration between = Duration.between(startTime, now);
|
|
|
+ long abs = Math.abs(between.getSeconds());
|
|
|
+ int hour = timeoutRemidConfig.get("hour").getAsInt() * 60 * 60;
|
|
|
+ int interval = timeoutRemidConfig.get("interval").getAsInt() * 60 * 60;
|
|
|
+ if(abs >= hour && lasttime >= interval){
|
|
|
+ //对未结束的流程节点进行处理,通知下一个节点需要处理的人
|
|
|
+
|
|
|
+ if(message.containsKey(startUserId)){
|
|
|
+ message.get(startUserId).append(",").append(el.get("process_name").toString());
|
|
|
+ }else {
|
|
|
+ message.put(startUserId, new StringBuilder(el.get("process_name").toString()));
|
|
|
+ }
|
|
|
+ recordList.add(
|
|
|
+ new WorkflowAlertRecord(){{
|
|
|
+ setProcessId(Long.parseLong(el.get("process_id").toString()));
|
|
|
+ setUserId(Long.parseLong(startUserId));
|
|
|
+ setProcessName(el.get("process_name").toString());
|
|
|
+ setType(1);
|
|
|
+ setSendTime(now);
|
|
|
+ }}
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!recordList.isEmpty()){
|
|
|
+ alertRecordService.saveBatch(recordList);
|
|
|
+ }
|
|
|
+
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ SendMessageUtil.sendWorkflowUnapprovedWx(message);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), "定时提醒流程未处理");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|