package com.xjrsoft.module.job; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.fasterxml.jackson.core.type.TypeReference; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.google.gson.JsonArray; import com.xjrsoft.XjrSoftApplication; import com.xjrsoft.common.enums.CourseAdjustTypeEnum; import com.xjrsoft.common.enums.EnabledMark; import com.xjrsoft.common.enums.WorkflowApproveType; import com.xjrsoft.common.enums.WorkflowMultiInstanceType; import com.xjrsoft.common.mybatis.SqlRunnerAdapter; import com.xjrsoft.common.utils.RedisUtil; import com.xjrsoft.common.utils.VoToColumnUtil; import com.xjrsoft.config.CommonPropertiesConfig; import com.xjrsoft.module.base.entity.BaseClass; import com.xjrsoft.module.base.service.IBaseClassService; import com.xjrsoft.module.courseTable.entity.CourseTable; import com.xjrsoft.module.courseTable.service.ICourseTableService; import com.xjrsoft.module.organization.dto.WeChatSendMessageDto; import com.xjrsoft.module.organization.entity.User; import com.xjrsoft.module.organization.service.IUserService; import com.xjrsoft.module.organization.service.IWeChatService; import com.xjrsoft.module.schedule.entity.CourseTableBak; import com.xjrsoft.module.schedule.entity.WfCourseAdjust; import com.xjrsoft.module.schedule.service.ICourseTableBakService; import com.xjrsoft.module.schedule.service.IWfCourseAdjustService; import com.xjrsoft.module.schedule.util.DataUtil; import com.xjrsoft.module.teacher.entity.BaseTeacher; import com.xjrsoft.module.workflow.constant.WorkflowConstant; import com.xjrsoft.module.workflow.entity.WorkflowExtra; import com.xjrsoft.module.workflow.entity.WorkflowFormRelation; import com.xjrsoft.module.workflow.entity.WorkflowRecord; import com.xjrsoft.module.workflow.entity.XjrWorkflowOperateRecord; import com.xjrsoft.module.workflow.mapper.XjrWorkflowOperateRecordMapper; import com.xjrsoft.module.workflow.service.IWorkflowExecuteService; import com.xjrsoft.module.workflow.service.IWorkflowExtraService; import com.xjrsoft.module.workflow.service.IWorkflowFormRelationService; import com.xjrsoft.module.workflow.service.IWorkflowRecordService; import me.zhyd.oauth.log.Log; import org.camunda.bpm.engine.RuntimeService; import org.camunda.bpm.engine.TaskService; import org.camunda.bpm.engine.history.HistoricProcessInstance; import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity; import org.camunda.bpm.engine.runtime.ActivityInstance; import org.camunda.bpm.engine.runtime.ProcessInstance; import org.camunda.bpm.engine.task.Task; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; /** * @author dzx * @date 2024/10/15 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = XjrSoftApplication.class) class JianyuekbScheduleTaskTest2 { @Autowired private IBaseClassService classService; private final static String taskKey = "jianyuekbScheduleTask"; @Autowired private RedisUtil redisUtil; @Autowired private IWfCourseAdjustService adjustService; @Autowired private ICourseTableService courseTableService; @Autowired private ICourseTableBakService courseTableBakService; @Autowired private RuntimeService runtimeService; @Autowired private IWorkflowFormRelationService formRelationService; @Autowired private TaskService taskService; @Autowired private IWorkflowExecuteService workflowExecuteService; @Autowired private IWorkflowRecordService workflowRecordService; @Autowired private XjrWorkflowOperateRecordMapper xjrWorkflowOperateRecordMapper; private final static String wechatTemplate = "OO5Ryu9_6Hh5LQW0aKG7qu3g5uV8VxvBusq1i5UFesk"; @Autowired private IWeChatService weChatService; @Autowired private CommonPropertiesConfig commonPropertiesConfig; @Autowired private IUserService userService; @Autowired private IWorkflowExtraService workflowExtraService; @Test void test2(){ WfCourseAdjust courseAdjust = adjustService.getById(1851529228440875008L); courseTableService.adjustCourse(courseAdjust); } @Test public void execute(){ doExecute(); } public void doExecute() { String sql = "SELECT * FROM course_receive_msg WHERE delete_mark = 0 AND is_callback is null"; List> receiveMsgs = SqlRunnerAdapter.db().selectList(sql); if(receiveMsgs.isEmpty()){ return; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); //查询出传入排课系统的年级和班级 List eduYearSerialNo1 = receiveMsgs.stream().map(x -> "'" + x.get("edu_year_serial_no").toString() + "'").collect(Collectors.toList()); //查询出传入排课系统的年级和班级 sql = "SELECT * FROM jianyue_data WHERE source_id IS NOT NULL AND jianyue_id != ''" + " and table_name = 'base_grade'" + " and jianyue_id in (" + eduYearSerialNo1.toString().replace("[","").replace("]","") + ")"; List> jianyueData = SqlRunnerAdapter.db().selectList(sql); Map> gradeClassMaps = new HashMap<>();//存入对应年级的所有班级id for (Map el : jianyueData) { String gradeId = el.get("source_id").toString(); String orgId = null; if(gradeId.contains("_")){ String[] split = el.get("source_id").toString().split("_"); gradeId = split[1]; orgId = split[0]; } List classList = classService.list( new QueryWrapper().lambda() .eq(BaseClass::getGradeId, gradeId) .eq(BaseClass::getOrgId, orgId) ); gradeClassMaps.put(el.get("jianyue_id").toString(), classList); } LocalDate today = LocalDate.now(); DataUtil dataUtil = new DataUtil(); Set ongoing = redisUtil.get(taskKey, new TypeReference>() {});//正在进行中的 if(ongoing == null){ ongoing = new HashSet<>(); } Map> dataMap = initDataMap(); for (Map receiveMsg : receiveMsgs) { String eduYearSerialNo = receiveMsg.get("edu_year_serial_no").toString(); if(ongoing.contains(eduYearSerialNo)){ continue; } ongoing.add(eduYearSerialNo); redisUtil.set(taskKey, ongoing); try { String updSql = "update course_receive_msg set is_callback = 0 where id = " + receiveMsg.get("id").toString(); SqlRunnerAdapter.db().update(updSql); JsonArray allScheduleInfo = new JsonArray(); String startDateStr = receiveMsg.get("start_date").toString(); LocalDate startDateObj = LocalDate.parse(startDateStr); String endDateStr = receiveMsg.get("end_date").toString(); LocalDate endDateObj = LocalDate.parse(endDateStr); if(today.isAfter(startDateObj)){ startDateStr = today.format(formatter); } //删除课表信息; List classList = gradeClassMaps.get(eduYearSerialNo); List classIdList = classList.stream().map(BaseClass::getId).collect(Collectors.toList()); String classIds = classIdList.toString().replace("[", "").replace("]", ""); String delSql = "delete from course_table where schedule_date between '" + startDateStr + "'" + " and '" + endDateStr + "' and class_id in (" + classIds + ")"; SqlRunnerAdapter.db().delete(delSql); startDateStr = receiveMsg.get("start_date").toString(); List processIds = suspendedCourseAdjust(classList, startDateStr, endDateStr); long between = ChronoUnit.DAYS.between(startDateObj, endDateObj); int times = Integer.parseInt(((between / 7) + 1) + ""); for (int index = 0; index < times; index ++) { LocalDate statrTime = startDateObj.plusDays(index * 7L); String startDate = statrTime.format(formatter); LocalDate endTime = statrTime.plusDays(6L); if(endTime.isAfter(endDateObj)){ endTime = endDateObj; } String endDate = endTime.format(formatter); //获取课表并存到数据库 JsonArray scheduleInfo = dataUtil.getScheduleInfoByGrade(eduYearSerialNo, startDate, endDate); allScheduleInfo.addAll(scheduleInfo); } updSql = "update course_receive_msg set is_callback = 1 where id = " + receiveMsg.get("id").toString(); SqlRunnerAdapter.db().update(updSql); ongoing.remove(eduYearSerialNo); redisUtil.set(taskKey, ongoing); insertCourse(allScheduleInfo, dataMap, dataUtil); //恢复挂起的流程 restoreCourseAdjust(processIds); //处理该日期内已经审批通过的调课和顶课申请 handleCourseAdjust(classList, startDateStr, endDateStr); }catch (Exception e){ Log.error(e.getMessage(), e); ongoing.remove(eduYearSerialNo); redisUtil.set(taskKey, ongoing); } } } void insertCourse(JsonArray scheduleInfo, Map> dataMap, DataUtil dataUtil){ //获取年级 String tableName = "base_grade"; // Map gradeMap = dataMap.get(tableName); //获取学期 tableName = "base_semester"; Map semesterMap = dataMap.get(tableName); //获取课程 tableName = "base_course_subject"; Map courseMap = dataMap.get(tableName); //获取教职工 tableName = "base_teacher"; Map teacherMap = dataMap.get(tableName); //获取行政班 tableName = "base_class"; Map classMap = dataMap.get(tableName); tableName = "base_classroom"; Map classroomMap = dataMap.get(tableName); dataUtil.insertCourseTableEntiy(scheduleInfo, classroomMap, courseMap, semesterMap, teacherMap, classMap, null); dataUtil.insertClassTime(scheduleInfo); } Map> initDataMap(){ Map> dataMap = new HashMap<>(); String sql = "SELECT distinct table_name FROM jianyue_data WHERE 1 = 1"; List> query = SqlRunnerAdapter.db().selectList(sql); Set tables = new HashSet<>(); for (Map jianyueData : query) { tables.add(jianyueData.get("table_name").toString()); } sql = "SELECT * FROM jianyue_data WHERE source_id IS NOT NULL AND jianyue_id != ''"; List> list = SqlRunnerAdapter.db().selectList(sql); for (String table : tables) { Map tableData = new HashMap<>(); for (Map jianyueData : list) { if(!table.equals(jianyueData.get("table_name").toString())){ continue; } tableData.put(jianyueData.get("jianyue_id").toString(), jianyueData.get("source_id").toString()); } dataMap.put(table, tableData); } return dataMap; } /** * 课程数据同步完之后,处理调课和顶课申请 * 1、课程数据入库后,将新课表日期之后的的调课顶课数据再次更新到课表中 * 2、筛选出课表变化了的调课和顶课申请,通知发起人 */ public void handleCourseAdjust(List classList, String startDate, String endDate){ List classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList()); Map classMap = classList.stream().collect(Collectors.toMap(BaseClass::getId, BaseClass::getName)); List bakList = courseTableBakService.list( new QueryWrapper().lambda() .in(CourseTableBak::getClassId, classIds) .between(CourseTableBak::getScheduleDate, startDate, endDate) ); Set courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet()); List courseAdjustIds = new ArrayList<>(courseAdjustIdSet); List list = adjustService.list( new MPJLambdaWrapper() .select(WfCourseAdjust::getId) .select(WfCourseAdjust.class, x -> VoToColumnUtil.fieldsToColumns(WfCourseAdjust.class).contains(x.getProperty())) .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfCourseAdjust::getId) .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds) .between(WfCourseAdjust::getAdjustDate, startDate, endDate) .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED) ); List cancelList = new ArrayList<>();//需要作废的申请 List userIds = list.stream().map(WfCourseAdjust::getUserId).collect(Collectors.toList()); List userList = userService.list( new MPJLambdaWrapper() .select(User::getId) .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty())) .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId) .in(!userIds.isEmpty(), User::getId, userIds) ); Map userOpenIdMap = new HashMap<>(); for (User user : userList) { userOpenIdMap.put(user.getId(), user.getOpenId()); } for (WfCourseAdjust courseAdjust : list) { if(courseAdjust.getUserId() == 14954805813957L){ System.out.println(courseAdjust.getId()); } List courseList = courseTableService.list( new MPJLambdaWrapper() .select(CourseTable::getId) .select(CourseTable.class, x -> VoToColumnUtil.fieldsToColumns(CourseTable.class).contains(x.getProperty())) .innerJoin(CourseTableBak.class, CourseTableBak::getKeyInfo, CourseTable::getKeyInfo) .eq(CourseTableBak::getWfCourseAdjustId, courseAdjust.getId()) ); String[] courseIds = courseAdjust.getCourseId().split(","); String[] exchangeCourseIds = null; int courseCount = courseIds.length; if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) { exchangeCourseIds = courseAdjust.getExchangeCourseId().split(","); courseCount += exchangeCourseIds.length; } if(courseList.size() != courseCount){ //表明课程变化了,需要重新申请,需要将原来的申请作废并进行微信消息通知 courseAdjust.setEnabledMark(EnabledMark.DISABLED.getCode()); courseAdjust.setCancelReason("由于课表更新,当前调/顶课课程发生变化,该调顶课已失效,请重新发起调顶课"); cancelList.add(courseAdjust); List thing16Str = new ArrayList<>(); List thing2Str = new ArrayList<>(); for (CourseTableBak tableBak : bakList) { if(!tableBak.getWfCourseAdjustId().equals(courseAdjust.getId())){ continue; } thing16Str.add(classMap.get(tableBak.getId())); thing2Str.add(tableBak.getClassName()); } WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto(); weChatSendMessageDto.setTemplateId(wechatTemplate); JSONObject paramJson = new JSONObject(); JSONObject thing16 = new JSONObject(); thing16.put("value", thing16Str.toString().replace(" ", "").replace("[", "").replace("]", "")); paramJson.put("thing16", thing16); JSONObject thing2 = new JSONObject(); thing2.put("value", thing2Str.toString().replace(" ", "").replace("[", "").replace("]", "")); paramJson.put("thing2", thing2); String const12Str = ""; if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) { const12Str = "调课失败"; } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) { const12Str = "顶课失败"; } JSONObject const12 = new JSONObject(); const12.put("value", const12Str); paramJson.put("const23", const12); //迟到人数或者缺勤人数 JSONObject thing5 = new JSONObject(); thing5.put("value", "由于课表更新,该调顶课已失效"); paramJson.put("thing5", thing5); String url = StrUtil.format( "{}/xjrsoft/pages/workflow/look?processId={}&type=my", commonPropertiesConfig.getDomainApp(), "relation.getProcessId()" ); weChatSendMessageDto.setContent(paramJson); weChatSendMessageDto.setUrl(url); weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + ""); String openId = userOpenIdMap.get(courseAdjust.getUserId()); if(openId != null && !"".equals(openId)){ weChatSendMessageDto.setUserId(openId); weChatService.sendTemplateMessage(weChatSendMessageDto); } continue; } courseTableService.adjustCourse(courseAdjust); } if(!cancelList.isEmpty()){ adjustService.updateBatchById(cancelList); } List activeList = formRelationService.list( new MPJLambdaWrapper() .select(WorkflowFormRelation::getId) .select(WorkflowFormRelation.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowFormRelation.class).contains(x.getProperty())) .innerJoin(WfCourseAdjust.class, WfCourseAdjust::getId, WorkflowFormRelation::getFormKeyValue) .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds) .between(WfCourseAdjust::getAdjustDate, startDate, endDate) .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_ACTIVE) ); for (WorkflowFormRelation relation : activeList) { List courseList = courseTableService.list( new MPJLambdaWrapper() .select(CourseTable::getId) .select(CourseTable.class, x -> VoToColumnUtil.fieldsToColumns(CourseTable.class).contains(x.getProperty())) .innerJoin(CourseTableBak.class, CourseTableBak::getKeyInfo, CourseTable::getKeyInfo) .eq(CourseTableBak::getWfCourseAdjustId, relation.getFormKeyValue()) ); List thisbakList = courseTableBakService.list( new QueryWrapper().lambda() .eq(CourseTableBak::getWfCourseAdjustId, relation.getFormKeyValue()) ); if(courseList.size() == thisbakList.size()){ continue; } WfCourseAdjust courseAdjust = adjustService.getById(relation.getFormKeyValue()); //表明课程变化了,进行内部终止 List thing16Str = new ArrayList<>(); List thing2Str = new ArrayList<>(); for (CourseTableBak tableBak : bakList) { if(!tableBak.getWfCourseAdjustId().equals(courseAdjust.getId())){ continue; } thing16Str.add(classMap.get(tableBak.getId())); thing2Str.add(tableBak.getClassName()); } WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto(); weChatSendMessageDto.setTemplateId(wechatTemplate); JSONObject paramJson = new JSONObject(); JSONObject thing16 = new JSONObject(); thing16.put("value", thing16Str.toString().replace(" ", "").replace("[", "").replace("]", "")); paramJson.put("thing16", classMap); JSONObject thing2 = new JSONObject(); thing2.put("value", thing2Str.toString().replace(" ", "").replace("[", "").replace("]", "")); paramJson.put("thing2", thing2); String const12Str = ""; if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) { const12Str = "调课失败"; } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) { const12Str = "顶课失败"; } JSONObject const12 = new JSONObject(); const12.put("value", const12Str); paramJson.put("const23", const12); //迟到人数或者缺勤人数 JSONObject thing5 = new JSONObject(); thing5.put("value", "由于课表更新,该调顶课已失效"); paramJson.put("thing5", thing5); weChatSendMessageDto.setContent(paramJson); List extraList = workflowExtraService.list( new QueryWrapper().lambda() .eq(WorkflowExtra::getProcessId, relation.getProcessId()) .orderByDesc(WorkflowExtra::getStartTime) ); if(!extraList.isEmpty()){ String url = StrUtil.format( "{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo", commonPropertiesConfig.getDomainApp(), extraList.get(0).getTaskId(), relation.getProcessId() ); weChatSendMessageDto.setUrl(url); weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + ""); String openId = userOpenIdMap.get(courseAdjust.getExchangeTeacherId()); if(openId != null && !"".equals(openId)){ weChatSendMessageDto.setUserId(openId); weChatService.sendTemplateMessage(weChatSendMessageDto); } } String url = StrUtil.format( "{}/xjrsoft/pages/workflow/look?processId={}&type=my", commonPropertiesConfig.getDomainApp(), relation.getProcessId() ); weChatSendMessageDto.setUrl(url); weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + ""); String openId = userOpenIdMap.get(courseAdjust.getUserId()); if(openId != null && !"".equals(openId)){ weChatSendMessageDto.setUserId(openId); weChatService.sendTemplateMessage(weChatSendMessageDto); } String processId = relation.getProcessId(); List taskList = taskService.createTaskQuery().processInstanceId(processId).list(); Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity()); Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY)); //获取到当前活动的实例 ActivityInstance activityInstance = runtimeService.getActivityInstance(task.getProcessInstanceId()); String message = " 因课表更新之后当前课程已发生变更,该流程已内部终止,如还需调/顶课,请重新发起调/顶课流程"; //先停止当前活动示例 然后 关闭流程 runtimeService.createProcessInstanceModification(task.getProcessInstanceId()) .cancelActivityInstance(activityInstance.getId()) .cancelAllForActivity(activityInstance.getId()) .setAnnotation("因课表更新之后当前课程已发生变更,该流程已内部终止") .execute(); //新增流程发起流程记录 WorkflowRecord record = new WorkflowRecord(); record.setNodeId(task.getId()); record.setNodeName(task.getName()); record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME); record.setProcessId(task.getProcessInstanceId()); record.setSchemaId(schemaId); record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode()); record.setRecordTime(LocalDateTime.now()); record.setWorkflowApproveType(WorkflowApproveType.FINISH.getCode()); record.setMessage(message); workflowRecordService.save(record); //新增流程发起流程记录 XjrWorkflowOperateRecord xjrWorkflowOperateRecord = new XjrWorkflowOperateRecord(); xjrWorkflowOperateRecord.setNodeId(task.getId()); xjrWorkflowOperateRecord.setNodeName(task.getName()); xjrWorkflowOperateRecord.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME); xjrWorkflowOperateRecord.setProcessId(task.getProcessInstanceId()); xjrWorkflowOperateRecord.setSchemaId(schemaId); xjrWorkflowOperateRecord.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode()); xjrWorkflowOperateRecord.setRecordTime(LocalDateTime.now()); xjrWorkflowOperateRecord.setUsageScenario(1); xjrWorkflowOperateRecord.setOperateInfo(message); xjrWorkflowOperateRecordMapper.insert(xjrWorkflowOperateRecord); Optional historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId); historicProcessInstance.ifPresent(item -> { formRelationService.updateCurrentState(new WorkflowFormRelation() {{ setProcessId(processId); setCurrentState(item.getState()); setStartTime(item.getStartTime()); setEndTime(item.getEndTime()); }}); }); } } /** * 挂起未通过的流程 */ List suspendedCourseAdjust(List classList, String startDate, String endDate) { List classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList()); List bakList = courseTableBakService.list( new QueryWrapper().lambda() .in(CourseTableBak::getClassId, classIds) .between(CourseTableBak::getScheduleDate, startDate, endDate) ); Set courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet()); List courseAdjustIds = new ArrayList<>(courseAdjustIdSet); List list = formRelationService.list( new MPJLambdaWrapper() .select(WorkflowFormRelation::getId) .select(WorkflowFormRelation.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowFormRelation.class).contains(x.getProperty())) .innerJoin(WfCourseAdjust.class, WfCourseAdjust::getId, WorkflowFormRelation::getFormKeyValue) .between(WfCourseAdjust::getAdjustDate, startDate, endDate) .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds) .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_ACTIVE) ); List processIds = new ArrayList<>(); for (WorkflowFormRelation relation : list) { String processId = relation.getProcessId(); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult(); List taskList = taskService.createTaskQuery().processInstanceId(processId).list(); Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity()); Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY)); //新增流程发起流程记录 WorkflowRecord record = new WorkflowRecord(); record.setNodeId(task.getId()); record.setNodeName(task.getName()); record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME); record.setProcessId(task.getProcessInstanceId()); record.setSchemaId(schemaId); record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode()); record.setRecordTime(LocalDateTime.now()); if (processInstance.isSuspended()) { runtimeService.activateProcessInstanceById(relation.getProcessId()); //[操作人名称] 将流程恢复 record.setMessage("课表同步成功,流程恢复"); } else { runtimeService.suspendProcessInstanceById(relation.getProcessId()); //[操作人名称] 将流程挂起 record.setMessage("课表更新中,暂停流程审核,请等待课表更新完成之后进行审核"); } workflowRecordService.save(record); Optional historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId); historicProcessInstance.ifPresent(item -> { formRelationService.updateCurrentState(new WorkflowFormRelation() {{ setProcessId(processId); setCurrentState(item.getState()); setStartTime(item.getStartTime()); setEndTime(item.getEndTime()); }}); }); processIds.add(relation.getProcessId()); } return processIds; } /** * 将挂起的流程恢复 */ void restoreCourseAdjust(List processIds){ for (String processId : processIds) { List taskList = taskService.createTaskQuery().processInstanceId(processId).list(); Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity()); Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY)); //新增流程发起流程记录 WorkflowRecord record = new WorkflowRecord(); record.setNodeId(task.getId()); record.setNodeName(task.getName()); record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME); record.setProcessId(task.getProcessInstanceId()); record.setSchemaId(schemaId); record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode()); record.setRecordTime(LocalDateTime.now()); record.setMessage("课表同步成功,流程恢复"); workflowRecordService.save(record); runtimeService.activateProcessInstanceById(processId); Optional historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId); historicProcessInstance.ifPresent(item -> { formRelationService.updateCurrentState(new WorkflowFormRelation() {{ setProcessId(processId); setCurrentState(item.getState()); setStartTime(item.getStartTime()); setEndTime(item.getEndTime()); }}); }); } } }