|
@@ -1,15 +1,54 @@
|
|
|
package com.xjrsoft.module.job;
|
|
|
|
|
|
-import cn.hutool.extra.spring.SpringUtil;
|
|
|
+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;
|
|
@@ -17,17 +56,18 @@ 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.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;
|
|
|
|
|
|
-import static org.junit.jupiter.api.Assertions.*;
|
|
|
-
|
|
|
/**
|
|
|
* @author dzx
|
|
|
* @date 2024/10/15
|
|
@@ -43,12 +83,52 @@ class JianyuekbScheduleTaskTest2 {
|
|
|
@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
|
|
|
- public void execute() throws Exception {
|
|
|
+ public void execute(){
|
|
|
doExecute();
|
|
|
}
|
|
|
- public void doExecute() throws Exception {
|
|
|
- String active = SpringUtil.getActiveProfile();
|
|
|
+ public void doExecute() {
|
|
|
String sql = "SELECT * FROM course_receive_msg WHERE delete_mark = 0 AND is_callback IS NULL";
|
|
|
List<Map<String, Object>> receiveMsgs = SqlRunnerAdapter.db().selectList(sql);
|
|
|
if(receiveMsgs.isEmpty()){
|
|
@@ -64,7 +144,7 @@ class JianyuekbScheduleTaskTest2 {
|
|
|
" and table_name = 'base_grade'" +
|
|
|
" and jianyue_id in (" + eduYearSerialNo1.toString().replace("[","").replace("]","") + ")";
|
|
|
List<Map<String, Object>> jianyueData = SqlRunnerAdapter.db().selectList(sql);
|
|
|
- Map<String, List<Long>> gradeClassMaps = new HashMap<>();//存入对应年级的所有班级id
|
|
|
+ Map<String, List<BaseClass>> gradeClassMaps = new HashMap<>();//存入对应年级的所有班级id
|
|
|
for (Map<String, Object> el : jianyueData) {
|
|
|
String gradeId = el.get("source_id").toString();
|
|
|
String orgId = null;
|
|
@@ -78,9 +158,7 @@ class JianyuekbScheduleTaskTest2 {
|
|
|
.eq(BaseClass::getGradeId, gradeId)
|
|
|
.eq(BaseClass::getOrgId, orgId)
|
|
|
);
|
|
|
- List<Long> classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
|
|
|
-
|
|
|
- gradeClassMaps.put(el.get("jianyue_id").toString(), classIds);
|
|
|
+ gradeClassMaps.put(el.get("jianyue_id").toString(), classList);
|
|
|
}
|
|
|
LocalDate today = LocalDate.now();
|
|
|
|
|
@@ -99,56 +177,68 @@ class JianyuekbScheduleTaskTest2 {
|
|
|
ongoing.add(eduYearSerialNo);
|
|
|
redisUtil.set(taskKey, ongoing);
|
|
|
|
|
|
- String updSql = "update course_receive_msg set is_callback = 0 where id = " + receiveMsg.get("id").toString();
|
|
|
- SqlRunnerAdapter.db().update(updSql);
|
|
|
+ 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);
|
|
|
- }
|
|
|
- //删除课表信息;
|
|
|
- String classIds = gradeClassMaps.get(eduYearSerialNo).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);
|
|
|
-
|
|
|
- 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;
|
|
|
+ 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);
|
|
|
}
|
|
|
|
|
|
- String endDate = endTime.format(formatter);
|
|
|
- //获取课表并存到数据库
|
|
|
- JsonArray scheduleInfo = dataUtil.getScheduleInfoByGrade(eduYearSerialNo, startDate, endDate);
|
|
|
- allScheduleInfo.addAll(scheduleInfo);
|
|
|
- }
|
|
|
+ //删除课表信息;
|
|
|
+ List<BaseClass> classList = gradeClassMaps.get(eduYearSerialNo);
|
|
|
+ List<Long> 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);
|
|
|
|
|
|
- updSql = "update course_receive_msg set is_callback = 1 where id = " + receiveMsg.get("id").toString();
|
|
|
- SqlRunnerAdapter.db().update(updSql);
|
|
|
- //作废调课和顶课
|
|
|
- updSql = "UPDATE wf_course_adjust SET enabled_mark = 0 WHERE adjust_type BETWEEN '" + startDateStr + "'" +
|
|
|
- " and '" + endDateStr + "' and class_id in (" + classIds + ")";
|
|
|
- SqlRunnerAdapter.db().update(updSql);
|
|
|
|
|
|
- ongoing.remove(eduYearSerialNo);
|
|
|
- redisUtil.set(taskKey, ongoing);
|
|
|
- doExecute(allScheduleInfo, dataMap, dataUtil);
|
|
|
- }
|
|
|
+ startDateStr = receiveMsg.get("start_date").toString();
|
|
|
+ List<String> 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 doExecute(JsonArray scheduleInfo, Map<String, Map<String, String>> dataMap, DataUtil dataUtil){
|
|
|
+ void insertCourse(JsonArray scheduleInfo, Map<String, Map<String, String>> dataMap, DataUtil dataUtil){
|
|
|
//获取年级
|
|
|
String tableName = "base_grade";
|
|
|
// Map<String, Long> gradeMap = dataMap.get(tableName);
|
|
@@ -195,4 +285,382 @@ class JianyuekbScheduleTaskTest2 {
|
|
|
}
|
|
|
return dataMap;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 课程数据同步完之后,处理调课和顶课申请
|
|
|
+ * 1、课程数据入库后,将新课表日期之后的的调课顶课数据再次更新到课表中
|
|
|
+ * 2、筛选出课表变化了的调课和顶课申请,通知发起人
|
|
|
+ */
|
|
|
+ public void handleCourseAdjust(List<BaseClass> classList, String startDate, String endDate){
|
|
|
+ List<Long> classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
|
|
|
+ Map<Long, String> classMap = classList.stream().collect(Collectors.toMap(BaseClass::getId, BaseClass::getName));
|
|
|
+ List<CourseTableBak> bakList = courseTableBakService.list(
|
|
|
+ new QueryWrapper<CourseTableBak>().lambda()
|
|
|
+ .in(CourseTableBak::getClassId, classIds)
|
|
|
+ .between(CourseTableBak::getScheduleDate, startDate, endDate)
|
|
|
+ );
|
|
|
+ Set<Long> courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet());
|
|
|
+ List<Long> courseAdjustIds = new ArrayList<>(courseAdjustIdSet);
|
|
|
+ List<WfCourseAdjust> list = adjustService.list(
|
|
|
+ new MPJLambdaWrapper<WfCourseAdjust>()
|
|
|
+ .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<WfCourseAdjust> cancelList = new ArrayList<>();//需要作废的申请
|
|
|
+
|
|
|
+ List<Long> userIds = list.stream().map(WfCourseAdjust::getUserId).collect(Collectors.toList());
|
|
|
+ List<User> userList = userService.list(
|
|
|
+ new MPJLambdaWrapper<User>()
|
|
|
+ .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<Long, String> userOpenIdMap = new HashMap<>();
|
|
|
+ for (User user : userList) {
|
|
|
+ userOpenIdMap.put(user.getId(), user.getOpenId());
|
|
|
+ }
|
|
|
+
|
|
|
+ for (WfCourseAdjust courseAdjust : list) {
|
|
|
+ List<CourseTable> courseList = courseTableService.list(
|
|
|
+ new MPJLambdaWrapper<CourseTable>()
|
|
|
+ .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<String> thing16Str = new ArrayList<>();
|
|
|
+ List<String> 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<WorkflowFormRelation> activeList = formRelationService.list(
|
|
|
+ new MPJLambdaWrapper<WorkflowFormRelation>()
|
|
|
+ .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<CourseTable> courseList = courseTableService.list(
|
|
|
+ new MPJLambdaWrapper<CourseTable>()
|
|
|
+ .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<CourseTableBak> thisbakList = courseTableBakService.list(
|
|
|
+ new QueryWrapper<CourseTableBak>().lambda()
|
|
|
+ .eq(CourseTableBak::getWfCourseAdjustId, relation.getFormKeyValue())
|
|
|
+ );
|
|
|
+ if(courseList.size() == thisbakList.size()){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ WfCourseAdjust courseAdjust = adjustService.getById(relation.getFormKeyValue());
|
|
|
+ //表明课程变化了,进行内部终止
|
|
|
+ List<String> thing16Str = new ArrayList<>();
|
|
|
+ List<String> 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<WorkflowExtra> extraList = workflowExtraService.list(
|
|
|
+ new QueryWrapper<WorkflowExtra>().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<Task> 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> historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId);
|
|
|
+ historicProcessInstance.ifPresent(item -> {
|
|
|
+ formRelationService.updateCurrentState(new WorkflowFormRelation() {{
|
|
|
+ setProcessId(processId);
|
|
|
+ setCurrentState(item.getState());
|
|
|
+ setStartTime(item.getStartTime());
|
|
|
+ setEndTime(item.getEndTime());
|
|
|
+ }});
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 挂起未通过的流程
|
|
|
+ */
|
|
|
+ List<String> suspendedCourseAdjust(List<BaseClass> classList, String startDate, String endDate) {
|
|
|
+ List<Long> classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
|
|
|
+ List<CourseTableBak> bakList = courseTableBakService.list(
|
|
|
+ new QueryWrapper<CourseTableBak>().lambda()
|
|
|
+ .in(CourseTableBak::getClassId, classIds)
|
|
|
+ .between(CourseTableBak::getScheduleDate, startDate, endDate)
|
|
|
+ );
|
|
|
+ Set<Long> courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet());
|
|
|
+
|
|
|
+ List<Long> courseAdjustIds = new ArrayList<>(courseAdjustIdSet);
|
|
|
+ List<WorkflowFormRelation> list = formRelationService.list(
|
|
|
+ new MPJLambdaWrapper<WorkflowFormRelation>()
|
|
|
+ .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<String> processIds = new ArrayList<>();
|
|
|
+ for (WorkflowFormRelation relation : list) {
|
|
|
+ String processId = relation.getProcessId();
|
|
|
+ ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
|
|
|
+ List<Task> 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> 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<String> processIds){
|
|
|
+ for (String processId : processIds) {
|
|
|
+ List<Task> 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> historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId);
|
|
|
+ historicProcessInstance.ifPresent(item -> {
|
|
|
+ formRelationService.updateCurrentState(new WorkflowFormRelation() {{
|
|
|
+ setProcessId(processId);
|
|
|
+ setCurrentState(item.getState());
|
|
|
+ setStartTime(item.getStartTime());
|
|
|
+ setEndTime(item.getEndTime());
|
|
|
+ }});
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|