JianyuekbScheduleTaskTest2.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. package com.xjrsoft.module.job;
  2. import cn.dev33.satoken.stp.StpUtil;
  3. import cn.hutool.core.convert.Convert;
  4. import cn.hutool.core.util.IdUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import com.alibaba.fastjson.JSONObject;
  7. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8. import com.fasterxml.jackson.core.type.TypeReference;
  9. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  10. import com.google.gson.JsonArray;
  11. import com.xjrsoft.XjrSoftApplication;
  12. import com.xjrsoft.common.enums.CourseAdjustTypeEnum;
  13. import com.xjrsoft.common.enums.EnabledMark;
  14. import com.xjrsoft.common.enums.WorkflowApproveType;
  15. import com.xjrsoft.common.enums.WorkflowMultiInstanceType;
  16. import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
  17. import com.xjrsoft.common.utils.RedisUtil;
  18. import com.xjrsoft.common.utils.VoToColumnUtil;
  19. import com.xjrsoft.config.CommonPropertiesConfig;
  20. import com.xjrsoft.module.base.entity.BaseClass;
  21. import com.xjrsoft.module.base.service.IBaseClassService;
  22. import com.xjrsoft.module.courseTable.entity.CourseTable;
  23. import com.xjrsoft.module.courseTable.service.ICourseTableService;
  24. import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
  25. import com.xjrsoft.module.organization.entity.User;
  26. import com.xjrsoft.module.organization.service.IUserService;
  27. import com.xjrsoft.module.organization.service.IWeChatService;
  28. import com.xjrsoft.module.schedule.entity.CourseTableBak;
  29. import com.xjrsoft.module.schedule.entity.WfCourseAdjust;
  30. import com.xjrsoft.module.schedule.service.ICourseTableBakService;
  31. import com.xjrsoft.module.schedule.service.IWfCourseAdjustService;
  32. import com.xjrsoft.module.schedule.util.DataUtil;
  33. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  34. import com.xjrsoft.module.workflow.constant.WorkflowConstant;
  35. import com.xjrsoft.module.workflow.entity.WorkflowExtra;
  36. import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
  37. import com.xjrsoft.module.workflow.entity.WorkflowRecord;
  38. import com.xjrsoft.module.workflow.entity.XjrWorkflowOperateRecord;
  39. import com.xjrsoft.module.workflow.mapper.XjrWorkflowOperateRecordMapper;
  40. import com.xjrsoft.module.workflow.service.IWorkflowExecuteService;
  41. import com.xjrsoft.module.workflow.service.IWorkflowExtraService;
  42. import com.xjrsoft.module.workflow.service.IWorkflowFormRelationService;
  43. import com.xjrsoft.module.workflow.service.IWorkflowRecordService;
  44. import me.zhyd.oauth.log.Log;
  45. import org.camunda.bpm.engine.RuntimeService;
  46. import org.camunda.bpm.engine.TaskService;
  47. import org.camunda.bpm.engine.history.HistoricProcessInstance;
  48. import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity;
  49. import org.camunda.bpm.engine.runtime.ActivityInstance;
  50. import org.camunda.bpm.engine.runtime.ProcessInstance;
  51. import org.camunda.bpm.engine.task.Task;
  52. import org.junit.jupiter.api.Test;
  53. import org.junit.runner.RunWith;
  54. import org.springframework.beans.factory.annotation.Autowired;
  55. import org.springframework.boot.test.context.SpringBootTest;
  56. import org.springframework.test.context.junit4.SpringRunner;
  57. import java.time.LocalDate;
  58. import java.time.LocalDateTime;
  59. import java.time.format.DateTimeFormatter;
  60. import java.time.temporal.ChronoUnit;
  61. import java.util.ArrayList;
  62. import java.util.Arrays;
  63. import java.util.HashMap;
  64. import java.util.HashSet;
  65. import java.util.List;
  66. import java.util.Map;
  67. import java.util.Optional;
  68. import java.util.Set;
  69. import java.util.stream.Collectors;
  70. /**
  71. * @author dzx
  72. * @date 2024/10/15
  73. */
  74. @RunWith(SpringRunner.class)
  75. @SpringBootTest(classes = XjrSoftApplication.class)
  76. class JianyuekbScheduleTaskTest2 {
  77. @Autowired
  78. private IBaseClassService classService;
  79. private final static String taskKey = "jianyuekbScheduleTask";
  80. @Autowired
  81. private RedisUtil redisUtil;
  82. @Autowired
  83. private IWfCourseAdjustService adjustService;
  84. @Autowired
  85. private ICourseTableService courseTableService;
  86. @Autowired
  87. private ICourseTableBakService courseTableBakService;
  88. @Autowired
  89. private RuntimeService runtimeService;
  90. @Autowired
  91. private IWorkflowFormRelationService formRelationService;
  92. @Autowired
  93. private TaskService taskService;
  94. @Autowired
  95. private IWorkflowExecuteService workflowExecuteService;
  96. @Autowired
  97. private IWorkflowRecordService workflowRecordService;
  98. @Autowired
  99. private XjrWorkflowOperateRecordMapper xjrWorkflowOperateRecordMapper;
  100. private final static String wechatTemplate = "OO5Ryu9_6Hh5LQW0aKG7qu3g5uV8VxvBusq1i5UFesk";
  101. @Autowired
  102. private IWeChatService weChatService;
  103. @Autowired
  104. private CommonPropertiesConfig commonPropertiesConfig;
  105. @Autowired
  106. private IUserService userService;
  107. @Autowired
  108. private IWorkflowExtraService workflowExtraService;
  109. @Test
  110. void test2(){
  111. WfCourseAdjust courseAdjust = adjustService.getById(1851529228440875008L);
  112. courseTableService.adjustCourse(courseAdjust);
  113. }
  114. @Test
  115. public void execute(){
  116. doExecute();
  117. }
  118. public void doExecute() {
  119. String sql = "SELECT * FROM course_receive_msg WHERE delete_mark = 0 AND is_callback is null";
  120. List<Map<String, Object>> receiveMsgs = SqlRunnerAdapter.db().selectList(sql);
  121. if(receiveMsgs.isEmpty()){
  122. return;
  123. }
  124. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  125. //查询出传入排课系统的年级和班级
  126. List<String> eduYearSerialNo1 = receiveMsgs.stream().map(x -> "'" + x.get("edu_year_serial_no").toString() + "'").collect(Collectors.toList());
  127. //查询出传入排课系统的年级和班级
  128. sql = "SELECT * FROM jianyue_data WHERE source_id IS NOT NULL AND jianyue_id != ''" +
  129. " and table_name = 'base_grade'" +
  130. " and jianyue_id in (" + eduYearSerialNo1.toString().replace("[","").replace("]","") + ")";
  131. List<Map<String, Object>> jianyueData = SqlRunnerAdapter.db().selectList(sql);
  132. Map<String, List<BaseClass>> gradeClassMaps = new HashMap<>();//存入对应年级的所有班级id
  133. for (Map<String, Object> el : jianyueData) {
  134. String gradeId = el.get("source_id").toString();
  135. String orgId = null;
  136. if(gradeId.contains("_")){
  137. String[] split = el.get("source_id").toString().split("_");
  138. gradeId = split[1];
  139. orgId = split[0];
  140. }
  141. List<BaseClass> classList = classService.list(
  142. new QueryWrapper<BaseClass>().lambda()
  143. .eq(BaseClass::getGradeId, gradeId)
  144. .eq(BaseClass::getOrgId, orgId)
  145. );
  146. gradeClassMaps.put(el.get("jianyue_id").toString(), classList);
  147. }
  148. LocalDate today = LocalDate.now();
  149. DataUtil dataUtil = new DataUtil();
  150. Set<String> ongoing = redisUtil.get(taskKey, new TypeReference<Set<String>>() {});//正在进行中的
  151. if(ongoing == null){
  152. ongoing = new HashSet<>();
  153. }
  154. Map<String, Map<String, String>> dataMap = initDataMap();
  155. for (Map<String, Object> receiveMsg : receiveMsgs) {
  156. String eduYearSerialNo = receiveMsg.get("edu_year_serial_no").toString();
  157. if(ongoing.contains(eduYearSerialNo)){
  158. continue;
  159. }
  160. ongoing.add(eduYearSerialNo);
  161. redisUtil.set(taskKey, ongoing);
  162. try {
  163. String updSql = "update course_receive_msg set is_callback = 0 where id = " + receiveMsg.get("id").toString();
  164. SqlRunnerAdapter.db().update(updSql);
  165. JsonArray allScheduleInfo = new JsonArray();
  166. String startDateStr = receiveMsg.get("start_date").toString();
  167. LocalDate startDateObj = LocalDate.parse(startDateStr);
  168. String endDateStr = receiveMsg.get("end_date").toString();
  169. LocalDate endDateObj = LocalDate.parse(endDateStr);
  170. if(today.isAfter(startDateObj)){
  171. startDateStr = today.format(formatter);
  172. }
  173. //删除课表信息;
  174. List<BaseClass> classList = gradeClassMaps.get(eduYearSerialNo);
  175. List<Long> classIdList = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
  176. String classIds = classIdList.toString().replace("[", "").replace("]", "");
  177. String delSql = "delete from course_table where schedule_date between '" + startDateStr + "'" +
  178. " and '" + endDateStr +
  179. "' and class_id in (" + classIds + ")";
  180. SqlRunnerAdapter.db().delete(delSql);
  181. startDateStr = receiveMsg.get("start_date").toString();
  182. List<String> processIds = suspendedCourseAdjust(classList, startDateStr, endDateStr);
  183. long between = ChronoUnit.DAYS.between(startDateObj, endDateObj);
  184. int times = Integer.parseInt(((between / 7) + 1) + "");
  185. for (int index = 0; index < times; index ++) {
  186. LocalDate statrTime = startDateObj.plusDays(index * 7L);
  187. String startDate = statrTime.format(formatter);
  188. LocalDate endTime = statrTime.plusDays(6L);
  189. if(endTime.isAfter(endDateObj)){
  190. endTime = endDateObj;
  191. }
  192. String endDate = endTime.format(formatter);
  193. //获取课表并存到数据库
  194. JsonArray scheduleInfo = dataUtil.getScheduleInfoByGrade(eduYearSerialNo, startDate, endDate);
  195. allScheduleInfo.addAll(scheduleInfo);
  196. }
  197. updSql = "update course_receive_msg set is_callback = 1 where id = " + receiveMsg.get("id").toString();
  198. SqlRunnerAdapter.db().update(updSql);
  199. ongoing.remove(eduYearSerialNo);
  200. redisUtil.set(taskKey, ongoing);
  201. insertCourse(allScheduleInfo, dataMap, dataUtil);
  202. //恢复挂起的流程
  203. restoreCourseAdjust(processIds);
  204. //处理该日期内已经审批通过的调课和顶课申请
  205. handleCourseAdjust(classList, startDateStr, endDateStr);
  206. }catch (Exception e){
  207. Log.error(e.getMessage(), e);
  208. ongoing.remove(eduYearSerialNo);
  209. redisUtil.set(taskKey, ongoing);
  210. }
  211. }
  212. }
  213. void insertCourse(JsonArray scheduleInfo, Map<String, Map<String, String>> dataMap, DataUtil dataUtil){
  214. //获取年级
  215. String tableName = "base_grade";
  216. // Map<String, Long> gradeMap = dataMap.get(tableName);
  217. //获取学期
  218. tableName = "base_semester";
  219. Map<String, String> semesterMap = dataMap.get(tableName);
  220. //获取课程
  221. tableName = "base_course_subject";
  222. Map<String, String> courseMap = dataMap.get(tableName);
  223. //获取教职工
  224. tableName = "base_teacher";
  225. Map<String, String> teacherMap = dataMap.get(tableName);
  226. //获取行政班
  227. tableName = "base_class";
  228. Map<String, String> classMap = dataMap.get(tableName);
  229. tableName = "base_classroom";
  230. Map<String, String> classroomMap = dataMap.get(tableName);
  231. dataUtil.insertCourseTableEntiy(scheduleInfo, classroomMap, courseMap, semesterMap, teacherMap, classMap, null);
  232. dataUtil.insertClassTime(scheduleInfo);
  233. }
  234. Map<String, Map<String, String>> initDataMap(){
  235. Map<String, Map<String, String>> dataMap = new HashMap<>();
  236. String sql = "SELECT distinct table_name FROM jianyue_data WHERE 1 = 1";
  237. List<Map<String, Object>> query = SqlRunnerAdapter.db().selectList(sql);
  238. Set<String> tables = new HashSet<>();
  239. for (Map<String, Object> jianyueData : query) {
  240. tables.add(jianyueData.get("table_name").toString());
  241. }
  242. sql = "SELECT * FROM jianyue_data WHERE source_id IS NOT NULL AND jianyue_id != ''";
  243. List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
  244. for (String table : tables) {
  245. Map<String, String> tableData = new HashMap<>();
  246. for (Map<String, Object> jianyueData : list) {
  247. if(!table.equals(jianyueData.get("table_name").toString())){
  248. continue;
  249. }
  250. tableData.put(jianyueData.get("jianyue_id").toString(), jianyueData.get("source_id").toString());
  251. }
  252. dataMap.put(table, tableData);
  253. }
  254. return dataMap;
  255. }
  256. /**
  257. * 课程数据同步完之后,处理调课和顶课申请
  258. * 1、课程数据入库后,将新课表日期之后的的调课顶课数据再次更新到课表中
  259. * 2、筛选出课表变化了的调课和顶课申请,通知发起人
  260. */
  261. public void handleCourseAdjust(List<BaseClass> classList, String startDate, String endDate){
  262. List<Long> classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
  263. Map<Long, String> classMap = classList.stream().collect(Collectors.toMap(BaseClass::getId, BaseClass::getName));
  264. List<CourseTableBak> bakList = courseTableBakService.list(
  265. new QueryWrapper<CourseTableBak>().lambda()
  266. .in(CourseTableBak::getClassId, classIds)
  267. .between(CourseTableBak::getScheduleDate, startDate, endDate)
  268. );
  269. Set<Long> courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet());
  270. List<Long> courseAdjustIds = new ArrayList<>(courseAdjustIdSet);
  271. List<WfCourseAdjust> list = adjustService.list(
  272. new MPJLambdaWrapper<WfCourseAdjust>()
  273. .select(WfCourseAdjust::getId)
  274. .select(WfCourseAdjust.class, x -> VoToColumnUtil.fieldsToColumns(WfCourseAdjust.class).contains(x.getProperty()))
  275. .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfCourseAdjust::getId)
  276. .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds)
  277. .between(WfCourseAdjust::getAdjustDate, startDate, endDate)
  278. .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
  279. );
  280. List<WfCourseAdjust> cancelList = new ArrayList<>();//需要作废的申请
  281. List<Long> userIds = list.stream().map(WfCourseAdjust::getUserId).collect(Collectors.toList());
  282. List<User> userList = userService.list(
  283. new MPJLambdaWrapper<User>()
  284. .select(User::getId)
  285. .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
  286. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, User::getId)
  287. .in(!userIds.isEmpty(), User::getId, userIds)
  288. );
  289. Map<Long, String> userOpenIdMap = new HashMap<>();
  290. for (User user : userList) {
  291. userOpenIdMap.put(user.getId(), user.getOpenId());
  292. }
  293. for (WfCourseAdjust courseAdjust : list) {
  294. if(courseAdjust.getUserId() == 14954805813957L){
  295. System.out.println(courseAdjust.getId());
  296. }
  297. List<CourseTable> courseList = courseTableService.list(
  298. new MPJLambdaWrapper<CourseTable>()
  299. .select(CourseTable::getId)
  300. .select(CourseTable.class, x -> VoToColumnUtil.fieldsToColumns(CourseTable.class).contains(x.getProperty()))
  301. .innerJoin(CourseTableBak.class, CourseTableBak::getKeyInfo, CourseTable::getKeyInfo)
  302. .eq(CourseTableBak::getWfCourseAdjustId, courseAdjust.getId())
  303. );
  304. String[] courseIds = courseAdjust.getCourseId().split(",");
  305. String[] exchangeCourseIds = null;
  306. int courseCount = courseIds.length;
  307. if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) {
  308. exchangeCourseIds = courseAdjust.getExchangeCourseId().split(",");
  309. courseCount += exchangeCourseIds.length;
  310. }
  311. if(courseList.size() != courseCount){
  312. //表明课程变化了,需要重新申请,需要将原来的申请作废并进行微信消息通知
  313. courseAdjust.setEnabledMark(EnabledMark.DISABLED.getCode());
  314. courseAdjust.setCancelReason("由于课表更新,当前调/顶课课程发生变化,该调顶课已失效,请重新发起调顶课");
  315. cancelList.add(courseAdjust);
  316. List<String> thing16Str = new ArrayList<>();
  317. List<String> thing2Str = new ArrayList<>();
  318. for (CourseTableBak tableBak : bakList) {
  319. if(!tableBak.getWfCourseAdjustId().equals(courseAdjust.getId())){
  320. continue;
  321. }
  322. thing16Str.add(classMap.get(tableBak.getId()));
  323. thing2Str.add(tableBak.getClassName());
  324. }
  325. WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
  326. weChatSendMessageDto.setTemplateId(wechatTemplate);
  327. JSONObject paramJson = new JSONObject();
  328. JSONObject thing16 = new JSONObject();
  329. thing16.put("value", thing16Str.toString().replace(" ", "").replace("[", "").replace("]", ""));
  330. paramJson.put("thing16", thing16);
  331. JSONObject thing2 = new JSONObject();
  332. thing2.put("value", thing2Str.toString().replace(" ", "").replace("[", "").replace("]", ""));
  333. paramJson.put("thing2", thing2);
  334. String const12Str = "";
  335. if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) {
  336. const12Str = "调课失败";
  337. } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) {
  338. const12Str = "顶课失败";
  339. }
  340. JSONObject const12 = new JSONObject();
  341. const12.put("value", const12Str);
  342. paramJson.put("const23", const12);
  343. //迟到人数或者缺勤人数
  344. JSONObject thing5 = new JSONObject();
  345. thing5.put("value", "由于课表更新,该调顶课已失效");
  346. paramJson.put("thing5", thing5);
  347. String url = StrUtil.format(
  348. "{}/xjrsoft/pages/workflow/look?processId={}&type=my",
  349. commonPropertiesConfig.getDomainApp(),
  350. "relation.getProcessId()"
  351. );
  352. weChatSendMessageDto.setContent(paramJson);
  353. weChatSendMessageDto.setUrl(url);
  354. weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
  355. String openId = userOpenIdMap.get(courseAdjust.getUserId());
  356. if(openId != null && !"".equals(openId)){
  357. weChatSendMessageDto.setUserId(openId);
  358. weChatService.sendTemplateMessage(weChatSendMessageDto);
  359. }
  360. continue;
  361. }
  362. courseTableService.adjustCourse(courseAdjust);
  363. }
  364. if(!cancelList.isEmpty()){
  365. adjustService.updateBatchById(cancelList);
  366. }
  367. List<WorkflowFormRelation> activeList = formRelationService.list(
  368. new MPJLambdaWrapper<WorkflowFormRelation>()
  369. .select(WorkflowFormRelation::getId)
  370. .select(WorkflowFormRelation.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowFormRelation.class).contains(x.getProperty()))
  371. .innerJoin(WfCourseAdjust.class, WfCourseAdjust::getId, WorkflowFormRelation::getFormKeyValue)
  372. .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds)
  373. .between(WfCourseAdjust::getAdjustDate, startDate, endDate)
  374. .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_ACTIVE)
  375. );
  376. for (WorkflowFormRelation relation : activeList) {
  377. List<CourseTable> courseList = courseTableService.list(
  378. new MPJLambdaWrapper<CourseTable>()
  379. .select(CourseTable::getId)
  380. .select(CourseTable.class, x -> VoToColumnUtil.fieldsToColumns(CourseTable.class).contains(x.getProperty()))
  381. .innerJoin(CourseTableBak.class, CourseTableBak::getKeyInfo, CourseTable::getKeyInfo)
  382. .eq(CourseTableBak::getWfCourseAdjustId, relation.getFormKeyValue())
  383. );
  384. List<CourseTableBak> thisbakList = courseTableBakService.list(
  385. new QueryWrapper<CourseTableBak>().lambda()
  386. .eq(CourseTableBak::getWfCourseAdjustId, relation.getFormKeyValue())
  387. );
  388. if(courseList.size() == thisbakList.size()){
  389. continue;
  390. }
  391. WfCourseAdjust courseAdjust = adjustService.getById(relation.getFormKeyValue());
  392. //表明课程变化了,进行内部终止
  393. List<String> thing16Str = new ArrayList<>();
  394. List<String> thing2Str = new ArrayList<>();
  395. for (CourseTableBak tableBak : bakList) {
  396. if(!tableBak.getWfCourseAdjustId().equals(courseAdjust.getId())){
  397. continue;
  398. }
  399. thing16Str.add(classMap.get(tableBak.getId()));
  400. thing2Str.add(tableBak.getClassName());
  401. }
  402. WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
  403. weChatSendMessageDto.setTemplateId(wechatTemplate);
  404. JSONObject paramJson = new JSONObject();
  405. JSONObject thing16 = new JSONObject();
  406. thing16.put("value", thing16Str.toString().replace(" ", "").replace("[", "").replace("]", ""));
  407. paramJson.put("thing16", classMap);
  408. JSONObject thing2 = new JSONObject();
  409. thing2.put("value", thing2Str.toString().replace(" ", "").replace("[", "").replace("]", ""));
  410. paramJson.put("thing2", thing2);
  411. String const12Str = "";
  412. if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) {
  413. const12Str = "调课失败";
  414. } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) {
  415. const12Str = "顶课失败";
  416. }
  417. JSONObject const12 = new JSONObject();
  418. const12.put("value", const12Str);
  419. paramJson.put("const23", const12);
  420. //迟到人数或者缺勤人数
  421. JSONObject thing5 = new JSONObject();
  422. thing5.put("value", "由于课表更新,该调顶课已失效");
  423. paramJson.put("thing5", thing5);
  424. weChatSendMessageDto.setContent(paramJson);
  425. List<WorkflowExtra> extraList = workflowExtraService.list(
  426. new QueryWrapper<WorkflowExtra>().lambda()
  427. .eq(WorkflowExtra::getProcessId, relation.getProcessId())
  428. .orderByDesc(WorkflowExtra::getStartTime)
  429. );
  430. if(!extraList.isEmpty()){
  431. String url = StrUtil.format(
  432. "{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo",
  433. commonPropertiesConfig.getDomainApp(),
  434. extraList.get(0).getTaskId(),
  435. relation.getProcessId()
  436. );
  437. weChatSendMessageDto.setUrl(url);
  438. weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
  439. String openId = userOpenIdMap.get(courseAdjust.getExchangeTeacherId());
  440. if(openId != null && !"".equals(openId)){
  441. weChatSendMessageDto.setUserId(openId);
  442. weChatService.sendTemplateMessage(weChatSendMessageDto);
  443. }
  444. }
  445. String url = StrUtil.format(
  446. "{}/xjrsoft/pages/workflow/look?processId={}&type=my",
  447. commonPropertiesConfig.getDomainApp(),
  448. relation.getProcessId()
  449. );
  450. weChatSendMessageDto.setUrl(url);
  451. weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
  452. String openId = userOpenIdMap.get(courseAdjust.getUserId());
  453. if(openId != null && !"".equals(openId)){
  454. weChatSendMessageDto.setUserId(openId);
  455. weChatService.sendTemplateMessage(weChatSendMessageDto);
  456. }
  457. String processId = relation.getProcessId();
  458. List<Task> taskList = taskService.createTaskQuery().processInstanceId(processId).list();
  459. Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity());
  460. Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY));
  461. //获取到当前活动的实例
  462. ActivityInstance activityInstance = runtimeService.getActivityInstance(task.getProcessInstanceId());
  463. String message = " 因课表更新之后当前课程已发生变更,该流程已内部终止,如还需调/顶课,请重新发起调/顶课流程";
  464. //先停止当前活动示例 然后 关闭流程
  465. runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
  466. .cancelActivityInstance(activityInstance.getId())
  467. .cancelAllForActivity(activityInstance.getId())
  468. .setAnnotation("因课表更新之后当前课程已发生变更,该流程已内部终止")
  469. .execute();
  470. //新增流程发起流程记录
  471. WorkflowRecord record = new WorkflowRecord();
  472. record.setNodeId(task.getId());
  473. record.setNodeName(task.getName());
  474. record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME);
  475. record.setProcessId(task.getProcessInstanceId());
  476. record.setSchemaId(schemaId);
  477. record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode());
  478. record.setRecordTime(LocalDateTime.now());
  479. record.setWorkflowApproveType(WorkflowApproveType.FINISH.getCode());
  480. record.setMessage(message);
  481. workflowRecordService.save(record);
  482. //新增流程发起流程记录
  483. XjrWorkflowOperateRecord xjrWorkflowOperateRecord = new XjrWorkflowOperateRecord();
  484. xjrWorkflowOperateRecord.setNodeId(task.getId());
  485. xjrWorkflowOperateRecord.setNodeName(task.getName());
  486. xjrWorkflowOperateRecord.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME);
  487. xjrWorkflowOperateRecord.setProcessId(task.getProcessInstanceId());
  488. xjrWorkflowOperateRecord.setSchemaId(schemaId);
  489. xjrWorkflowOperateRecord.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode());
  490. xjrWorkflowOperateRecord.setRecordTime(LocalDateTime.now());
  491. xjrWorkflowOperateRecord.setUsageScenario(1);
  492. xjrWorkflowOperateRecord.setOperateInfo(message);
  493. xjrWorkflowOperateRecordMapper.insert(xjrWorkflowOperateRecord);
  494. Optional<HistoricProcessInstance> historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId);
  495. historicProcessInstance.ifPresent(item -> {
  496. formRelationService.updateCurrentState(new WorkflowFormRelation() {{
  497. setProcessId(processId);
  498. setCurrentState(item.getState());
  499. setStartTime(item.getStartTime());
  500. setEndTime(item.getEndTime());
  501. }});
  502. });
  503. }
  504. }
  505. /**
  506. * 挂起未通过的流程
  507. */
  508. List<String> suspendedCourseAdjust(List<BaseClass> classList, String startDate, String endDate) {
  509. List<Long> classIds = classList.stream().map(BaseClass::getId).collect(Collectors.toList());
  510. List<CourseTableBak> bakList = courseTableBakService.list(
  511. new QueryWrapper<CourseTableBak>().lambda()
  512. .in(CourseTableBak::getClassId, classIds)
  513. .between(CourseTableBak::getScheduleDate, startDate, endDate)
  514. );
  515. Set<Long> courseAdjustIdSet = bakList.stream().map(CourseTableBak::getWfCourseAdjustId).collect(Collectors.toSet());
  516. List<Long> courseAdjustIds = new ArrayList<>(courseAdjustIdSet);
  517. List<WorkflowFormRelation> list = formRelationService.list(
  518. new MPJLambdaWrapper<WorkflowFormRelation>()
  519. .select(WorkflowFormRelation::getId)
  520. .select(WorkflowFormRelation.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowFormRelation.class).contains(x.getProperty()))
  521. .innerJoin(WfCourseAdjust.class, WfCourseAdjust::getId, WorkflowFormRelation::getFormKeyValue)
  522. .between(WfCourseAdjust::getAdjustDate, startDate, endDate)
  523. .in(!courseAdjustIds.isEmpty(), WfCourseAdjust::getId, courseAdjustIds)
  524. .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_ACTIVE)
  525. );
  526. List<String> processIds = new ArrayList<>();
  527. for (WorkflowFormRelation relation : list) {
  528. String processId = relation.getProcessId();
  529. ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
  530. List<Task> taskList = taskService.createTaskQuery().processInstanceId(processId).list();
  531. Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity());
  532. Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY));
  533. //新增流程发起流程记录
  534. WorkflowRecord record = new WorkflowRecord();
  535. record.setNodeId(task.getId());
  536. record.setNodeName(task.getName());
  537. record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME);
  538. record.setProcessId(task.getProcessInstanceId());
  539. record.setSchemaId(schemaId);
  540. record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode());
  541. record.setRecordTime(LocalDateTime.now());
  542. if (processInstance.isSuspended()) {
  543. runtimeService.activateProcessInstanceById(relation.getProcessId());
  544. //[操作人名称] 将流程恢复
  545. record.setMessage("课表同步成功,流程恢复");
  546. } else {
  547. runtimeService.suspendProcessInstanceById(relation.getProcessId());
  548. //[操作人名称] 将流程挂起
  549. record.setMessage("课表更新中,暂停流程审核,请等待课表更新完成之后进行审核");
  550. }
  551. workflowRecordService.save(record);
  552. Optional<HistoricProcessInstance> historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId);
  553. historicProcessInstance.ifPresent(item -> {
  554. formRelationService.updateCurrentState(new WorkflowFormRelation() {{
  555. setProcessId(processId);
  556. setCurrentState(item.getState());
  557. setStartTime(item.getStartTime());
  558. setEndTime(item.getEndTime());
  559. }});
  560. });
  561. processIds.add(relation.getProcessId());
  562. }
  563. return processIds;
  564. }
  565. /**
  566. * 将挂起的流程恢复
  567. */
  568. void restoreCourseAdjust(List<String> processIds){
  569. for (String processId : processIds) {
  570. List<Task> taskList = taskService.createTaskQuery().processInstanceId(processId).list();
  571. Task task = taskList.stream().filter(x -> x.getProcessInstanceId().equals(processId)).findFirst().orElse(new TaskEntity());
  572. Long schemaId = Convert.toLong(taskService.getVariable(task.getId(), WorkflowConstant.PROCESS_SCHEMA_ID_KEY));
  573. //新增流程发起流程记录
  574. WorkflowRecord record = new WorkflowRecord();
  575. record.setNodeId(task.getId());
  576. record.setNodeName(task.getName());
  577. record.setNodeType(WorkflowConstant.USER_TASK_TYPE_NAME);
  578. record.setProcessId(task.getProcessInstanceId());
  579. record.setSchemaId(schemaId);
  580. record.setNodeMultiType(WorkflowMultiInstanceType.NONE.getCode());
  581. record.setRecordTime(LocalDateTime.now());
  582. record.setMessage("课表同步成功,流程恢复");
  583. workflowRecordService.save(record);
  584. runtimeService.activateProcessInstanceById(processId);
  585. Optional<HistoricProcessInstance> historicProcessInstance = workflowExecuteService.getHistoricProcessInstance(processId);
  586. historicProcessInstance.ifPresent(item -> {
  587. formRelationService.updateCurrentState(new WorkflowFormRelation() {{
  588. setProcessId(processId);
  589. setCurrentState(item.getState());
  590. setStartTime(item.getStartTime());
  591. setEndTime(item.getEndTime());
  592. }});
  593. });
  594. }
  595. }
  596. }