CourseTableServiceImpl.java 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. package com.xjrsoft.module.courseTable.service.impl;
  2. import cn.dev33.satoken.stp.StpUtil;
  3. import cn.hutool.core.bean.BeanUtil;
  4. import cn.hutool.core.date.DateField;
  5. import cn.hutool.core.date.DateTime;
  6. import cn.hutool.core.date.DateUtil;
  7. import cn.hutool.core.util.ObjectUtil;
  8. import cn.hutool.core.util.StrUtil;
  9. import com.alibaba.excel.EasyExcel;
  10. import com.alibaba.excel.ExcelWriter;
  11. import com.alibaba.excel.support.ExcelTypeEnum;
  12. import com.alibaba.excel.write.metadata.WriteTable;
  13. import com.alibaba.excel.write.metadata.style.WriteCellStyle;
  14. import com.alibaba.excel.write.metadata.style.WriteFont;
  15. import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
  16. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  17. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  18. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  19. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  20. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  21. import com.google.gson.JsonArray;
  22. import com.google.gson.JsonObject;
  23. import com.google.gson.JsonParser;
  24. import com.xjrsoft.common.enums.CourseAdjustTypeEnum;
  25. import com.xjrsoft.common.enums.TimeNumberEnum;
  26. import com.xjrsoft.common.enums.TimePeriodEnum;
  27. import com.xjrsoft.common.enums.WeekEnum;
  28. import com.xjrsoft.common.exception.MyException;
  29. import com.xjrsoft.common.utils.excel.ExcelFillCellMergePrevColUtil;
  30. import com.xjrsoft.common.utils.excel.ExcelMergeUtil;
  31. import com.xjrsoft.config.TimetableConfig;
  32. import com.xjrsoft.module.base.entity.BaseClass;
  33. import com.xjrsoft.module.base.entity.BaseSemester;
  34. import com.xjrsoft.module.base.mapper.BaseSemesterMapper;
  35. import com.xjrsoft.module.base.service.IBaseClassService;
  36. import com.xjrsoft.module.base.service.IBaseSemesterService;
  37. import com.xjrsoft.module.courseTable.dto.ClassListDto;
  38. import com.xjrsoft.module.courseTable.dto.CourseTableParse;
  39. import com.xjrsoft.module.courseTable.entity.ClassTime;
  40. import com.xjrsoft.module.courseTable.entity.CourseTable;
  41. import com.xjrsoft.module.courseTable.mapper.ClassTimeMapper;
  42. import com.xjrsoft.module.courseTable.mapper.CourseTableMapper;
  43. import com.xjrsoft.module.courseTable.service.ICourseTableService;
  44. import com.xjrsoft.module.courseTable.vo.ClassListVo;
  45. import com.xjrsoft.module.schedule.dto.CourseTableAdjustDto;
  46. import com.xjrsoft.module.schedule.dto.CourseTableDto;
  47. import com.xjrsoft.module.schedule.dto.ScheduleWeekExportQueryDto;
  48. import com.xjrsoft.module.schedule.entity.WfCourseAdjust;
  49. import com.xjrsoft.module.schedule.mapper.CourseTableBakMapper;
  50. import com.xjrsoft.module.schedule.util.ScheduleUtil;
  51. import com.xjrsoft.module.schedule.vo.CourseDetailVo;
  52. import com.xjrsoft.module.schedule.vo.CourseListVo;
  53. import com.xjrsoft.module.schedule.vo.CourseTableVo;
  54. import com.xjrsoft.module.schedule.vo.ScheduleWeekExportQueryVo;
  55. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  56. import com.xjrsoft.module.teacher.entity.XjrUser;
  57. import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
  58. import com.xjrsoft.module.textbook.entity.SubjectGroupCourse;
  59. import com.xjrsoft.module.textbook.vo.TextbookClaimExportQueryVo;
  60. import com.xjrsoft.module.textbook.vo.TextbookIssueRecordExcelVo;
  61. import io.swagger.models.auth.In;
  62. import lombok.AllArgsConstructor;
  63. import org.apache.poi.ss.usermodel.BorderStyle;
  64. import org.apache.poi.ss.usermodel.HorizontalAlignment;
  65. import org.apache.poi.ss.usermodel.IndexedColors;
  66. import org.apache.poi.ss.usermodel.VerticalAlignment;
  67. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  68. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  69. import org.apache.poi.xwpf.usermodel.XWPFTable;
  70. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  71. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  72. import org.checkerframework.checker.units.qual.C;
  73. import org.springframework.beans.BeanUtils;
  74. import org.springframework.stereotype.Service;
  75. import org.springframework.transaction.annotation.Transactional;
  76. import java.io.ByteArrayOutputStream;
  77. import java.io.IOException;
  78. import java.io.InputStream;
  79. import java.time.DayOfWeek;
  80. import java.time.Duration;
  81. import java.time.LocalDate;
  82. import java.time.LocalDateTime;
  83. import java.time.ZoneId;
  84. import java.time.format.DateTimeFormatter;
  85. import java.util.*;
  86. import java.util.stream.Collectors;
  87. /**
  88. * <p>
  89. * 课表 服务实现类
  90. * </p>
  91. *
  92. * @author baomidou
  93. * @since 2023-09-02 02:19:56
  94. */
  95. @Service
  96. @AllArgsConstructor
  97. public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, CourseTable> implements ICourseTableService {
  98. private final CourseTableMapper courseTableMapper;
  99. private final IBaseClassService baseClassService;
  100. private final ITeacherbaseManagerService teacherbaseManagerService;
  101. private final IBaseSemesterService baseSemesterService;
  102. private final TimetableConfig timetableConfig;
  103. private final ClassTimeMapper classTimeMapper;
  104. private final BaseSemesterMapper baseSemesterMapper;
  105. private final CourseTableBakMapper courseTableBakMapper;
  106. @Override
  107. @Transactional(rollbackFor = Exception.class)
  108. public Boolean wordImport(InputStream inputStream) throws IOException {
  109. List<CourseTableParse> parses = courseTableWordParses(inputStream);
  110. String semester = null;
  111. if (parses.size() > 0) {
  112. semester = parses.get(0).getSemester();
  113. }
  114. BaseSemester baseSemester = baseSemesterService.getOne(Wrappers.<BaseSemester>query().lambda().eq(BaseSemester::getName, semester));
  115. if (baseSemester == null) {
  116. throw new MyException(String.format("学期【%s】不存在", semester));
  117. }
  118. // 获取班级信息
  119. List<BaseClass> baseClassList = baseClassService.list();
  120. Map<String, BaseClass> baseClassMap = baseClassList.stream().collect(Collectors.toMap(BaseClass::getName, a -> a, (k1, k2) -> k1));
  121. // 获取教师信息
  122. MPJLambdaWrapper<XjrUser> queryWrapper = new MPJLambdaWrapper<>();
  123. queryWrapper
  124. .disableSubLogicDel()
  125. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
  126. .selectAll(XjrUser.class);
  127. List<XjrUser> xjrUserList = teacherbaseManagerService.list(queryWrapper);
  128. Map<String, XjrUser> xjrUsersMap = xjrUserList.stream().collect(Collectors.toMap(XjrUser::getName, a -> a, (k1, k2) -> k1));
  129. // 清空所有数据
  130. courseTableMapper.delete(Wrappers.<CourseTable>query().lambda().eq(CourseTable::getBaseSemesterId, baseSemester.getId()));
  131. List<CourseTable> params = new ArrayList<>();
  132. for (CourseTableParse item : parses) {
  133. CourseTable courseTable = BeanUtil.toBean(item, CourseTable.class);
  134. courseTable.setBaseSemesterId(baseSemester.getId());
  135. BaseClass baseClass = baseClassMap.get(item.getClassName());
  136. if (baseClass != null) {
  137. courseTable.setClassId(baseClass.getId());
  138. }
  139. XjrUser xjrUser = xjrUsersMap.get(item.getTeacherName());
  140. if (xjrUser != null) {
  141. courseTable.setTeacherId(xjrUser.getId());
  142. }
  143. if (item.getWeeksCn() != null) {
  144. courseTable.setWeeks(WeekEnum.getCode(item.getWeeksCn()));
  145. }
  146. params.add(courseTable);
  147. }
  148. return this.saveBatch(params);
  149. }
  150. @Override
  151. public List<ClassListVo> classList(ClassListDto dto) {
  152. LambdaQueryWrapper<CourseTable> queryWrapper = new LambdaQueryWrapper<>();
  153. queryWrapper.eq(CourseTable::getClassId, dto.getClassId())
  154. .eq(ObjectUtil.isNotEmpty(dto.getWeeks()), CourseTable::getWeeks, dto.getWeeks());
  155. List<CourseTable> courseTables = courseTableMapper.selectList(queryWrapper);
  156. List<ClassListVo> classListVos = BeanUtil.copyToList(courseTables, ClassListVo.class);
  157. Boolean isCurrentSummer = isCurrentSummer();
  158. Map<String, ClassTime> classTimeMap = getClassTimeMap();
  159. // 获取节次时间
  160. for (int i = 0; i < classListVos.size(); i++) {
  161. ClassListVo c = classListVos.get(i);
  162. String key = String.format("%d_%d", c.getTimePeriod(), c.getTimeNumber());
  163. ClassTime ct = classTimeMap.get(key);
  164. if (ct != null) {
  165. if (isCurrentSummer) {
  166. c.setStartTime(ct.getSummerStartTime());
  167. c.setEndTime(ct.getSummerEndTime());
  168. } else {
  169. c.setStartTime(ct.getWinterStartTime());
  170. c.setEndTime(ct.getWinterEndTime());
  171. }
  172. }
  173. }
  174. return classListVos;
  175. }
  176. @Override
  177. public CourseTableVo getList(CourseTableDto dto) {
  178. List<ClassTime> classTimes = classTimeMapper.selectList(
  179. new QueryWrapper<ClassTime>().lambda().orderByAsc(ClassTime::getSummerStartTime)
  180. );
  181. CourseTableVo tableVo = new CourseTableVo();
  182. tableVo.setClassTimeList(classTimes);
  183. if (dto.getSemesterId() != null) {
  184. BaseSemester baseSemester = baseSemesterMapper.selectById(dto.getSemesterId());
  185. tableVo.setSemesterName(baseSemester.getName());
  186. LocalDateTime now = LocalDateTime.now();
  187. //计算本周是第几周
  188. LocalDateTime startDateTime = LocalDateTime.ofInstant(baseSemester.getStartDate().toInstant(), ZoneId.systemDefault());
  189. LocalDateTime endDateTime = LocalDateTime.ofInstant(baseSemester.getEndDate().toInstant(), ZoneId.systemDefault());
  190. Duration between = Duration.between(startDateTime, endDateTime);
  191. long days = between.toDays();
  192. int weeks = (int) Math.ceil((double) days / 7);
  193. if (dto.getWeek() == null) {
  194. for (int i = 0; i < weeks; i++) {
  195. LocalDateTime startDate = startDateTime.plusDays(i * 6).withHour(0).withMinute(0).withSecond(0).withNano(0);
  196. LocalDateTime endDate = startDateTime.plusDays((i + 1) * 6).withHour(23).withMinute(59).withSecond(59).withNano(9999);
  197. if (now.isAfter(startDate) && now.isBefore(endDate)) {
  198. tableVo.setWeek("第" + (i + 1) + "周");
  199. }
  200. }
  201. } else {
  202. LocalDateTime startDate = startDateTime.plusDays((dto.getWeek() - 1) * 6).withHour(0).withMinute(0).withSecond(0).withNano(0);
  203. LocalDateTime endDate = startDateTime.plusDays(dto.getWeek() * 6).withHour(23).withMinute(59).withSecond(59).withNano(9999);
  204. dto.setStartDate(startDate);
  205. dto.setEndDate(endDate);
  206. tableVo.setWeek("第" + dto.getWeek() + "周");
  207. }
  208. }
  209. if (!StrUtil.isEmpty(dto.getTeacherName())) {
  210. List<XjrUser> userList = teacherbaseManagerService.list(
  211. new QueryWrapper<XjrUser>().lambda()
  212. .like(!StrUtil.isEmpty(dto.getTeacherName()), XjrUser::getName, dto.getTeacherName())
  213. );
  214. List<XjrUser> userList2 = teacherbaseManagerService.list(
  215. new QueryWrapper<XjrUser>().lambda()
  216. .like(!StrUtil.isEmpty(dto.getTeacherName()), XjrUser::getCode, dto.getTeacherName())
  217. );
  218. userList.addAll(userList2);
  219. if (userList != null && !userList.isEmpty()) {
  220. XjrUser xjrUser = userList.get(0);
  221. dto.setTeacherId(xjrUser.getId());
  222. tableVo.setTeacherName(xjrUser.getName());
  223. }
  224. }
  225. if(dto.getStartDate() != null && dto.getEndDate() != null){
  226. dto.setTeacherId(StpUtil.getLoginIdAsLong());
  227. }
  228. List<CourseDetailVo> list = courseTableMapper.getList(dto);
  229. tableVo.setCourseList(list);
  230. tableVo.setClassHour(list.size());
  231. if (dto.getClassId() != null) {
  232. BaseClass baseClass = baseClassService.getById(dto.getClassId());
  233. tableVo.setClassName(baseClass.getName());
  234. }
  235. return tableVo;
  236. }
  237. /**
  238. * 调课顶课查询
  239. */
  240. @Override
  241. public List<CourseListVo> getAdjustList(String teacherId, String adjustDate, String classId) {
  242. CourseTableAdjustDto dto = new CourseTableAdjustDto();
  243. if (adjustDate != null && !"".equals(adjustDate)) {
  244. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  245. LocalDate localDateTime = LocalDate.parse(adjustDate, formatter);
  246. DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
  247. dto.setAdjustDate(adjustDate);
  248. dto.setWeek(dayOfWeek.getValue());
  249. }
  250. dto.setClassId(classId);
  251. dto.setTeacherId(Long.parseLong(teacherId));
  252. List<CourseListVo> list = courseTableMapper.getAdjustList(dto);
  253. for (CourseListVo courseListVo : list) {
  254. if (courseListVo.getTimePeriod() == 1) {
  255. courseListVo.setTimePeriodCn("上午");
  256. } else if (courseListVo.getTimePeriod() == 2) {
  257. courseListVo.setTimePeriodCn("下午");
  258. } else if (courseListVo.getTimePeriod() == 3) {
  259. courseListVo.setTimePeriodCn("晚上");
  260. }
  261. }
  262. return list;
  263. }
  264. @Override
  265. public String getPreCheck(String preCheckType, String courseId, String swapCourseId, String swapDate, String subTeacherId) {
  266. if (preCheckType != null && !"".equals(preCheckType)) {
  267. if (CourseAdjustTypeEnum.courseExchange.getCode().equals(preCheckType)) {
  268. CourseTable courseTable = courseTableMapper.selectById(courseId);
  269. CourseTable swapCourseTable = courseTableMapper.selectById(swapCourseId);
  270. try {
  271. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  272. LocalDate localDateTime = LocalDate.parse(swapDate, formatter);
  273. JsonObject preCheck = getExtendPreCheck(localDateTime, courseTable, swapCourseTable);
  274. if (preCheck.get("code").getAsInt() == -1 && !preCheck.get("msg").isJsonNull()) {
  275. return preCheck.get("msg").getAsString();
  276. }
  277. } catch (Exception e) {
  278. throw new RuntimeException(e);
  279. }
  280. } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(preCheckType)) {
  281. CourseTable courseTable = courseTableMapper.selectById(courseId);
  282. try {
  283. JsonObject jsonObject = substitutePreTestin(subTeacherId, courseTable);
  284. if (jsonObject.get("code").getAsInt() == -1 && !jsonObject.get("msg").isJsonNull()) {
  285. return jsonObject.get("msg").getAsString();
  286. }
  287. } catch (Exception e) {
  288. throw new RuntimeException(e);
  289. }
  290. }
  291. }
  292. return null;
  293. }
  294. @Override
  295. public Boolean adjustCourse(WfCourseAdjust courseAdjust) throws Exception {
  296. if (CourseAdjustTypeEnum.courseExchange.getCode().equals(courseAdjust.getAdjustType())) {
  297. //调课,将双方课程的日期(schedule_date)、时段(time_period)、节次(time_number)、周(week)、星期几(1-7)(weeks)、星期中文(weeks_cn)对调
  298. CourseTable courseTable = courseTableMapper.selectById(courseAdjust.getCourseId());
  299. CourseTable swapCourseTable = courseTableMapper.selectById(courseAdjust.getExchangeCourseId());
  300. CourseTable courseTableBak = BeanUtil.toBean(courseTable, CourseTable.class);
  301. CourseTable swapCourseTableBak = BeanUtil.toBean(swapCourseTable, CourseTable.class);
  302. courseTable.setScheduleDate(swapCourseTableBak.getScheduleDate());
  303. courseTable.setTimePeriod(swapCourseTableBak.getTimePeriod());
  304. courseTable.setTimeNumber(swapCourseTableBak.getTimeNumber());
  305. courseTable.setWeek(swapCourseTableBak.getWeek());
  306. courseTable.setWeeks(swapCourseTableBak.getWeeks());
  307. courseTable.setWeeksCn(swapCourseTableBak.getWeeksCn());
  308. courseTableMapper.updateById(courseTable);
  309. swapCourseTable.setScheduleDate(courseTableBak.getScheduleDate());
  310. swapCourseTable.setTimePeriod(courseTableBak.getTimePeriod());
  311. swapCourseTable.setTimeNumber(courseTableBak.getTimeNumber());
  312. swapCourseTable.setWeek(courseTableBak.getWeek());
  313. swapCourseTable.setWeeks(courseTableBak.getWeeks());
  314. swapCourseTable.setWeeksCn(courseTableBak.getWeeksCn());
  315. courseTableMapper.updateById(swapCourseTable);
  316. //提交调课接口
  317. sendExchange(courseTableBak, swapCourseTableBak, courseAdjust);
  318. } else if (CourseAdjustTypeEnum.courseSubstitute.getCode().equals(courseAdjust.getAdjustType())) {
  319. CourseTable courseTable = courseTableMapper.selectById(courseAdjust.getCourseId());
  320. courseTable.setTeacherId(courseAdjust.getExchangeTeacherId());
  321. courseTableMapper.updateById(courseTable);
  322. //提交顶课接口
  323. sendSubstitute(courseTable, courseAdjust);
  324. }
  325. return Boolean.TRUE;
  326. }
  327. @Override
  328. public ByteArrayOutputStream listScheduleWeekExportQuery(ScheduleWeekExportQueryDto dto) {
  329. // 创建一个字节输出流
  330. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  331. // 获取课程表数据
  332. CourseTableVo courseTableVo = getCourseTableVo(dto);
  333. // 构建课程安排导出列表
  334. List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList = buildScheduleWeekExportQueryList(courseTableVo);
  335. // 将数据写入Excel文件
  336. writeScheduleWeekExportToExcel(courseTableVo, outputStream, scheduleWeekExportQueryVoList);
  337. return outputStream;
  338. }
  339. private CourseTableVo getCourseTableVo(ScheduleWeekExportQueryDto dto) {
  340. CourseTableDto courseTableDto = new CourseTableDto();
  341. BeanUtils.copyProperties(dto, courseTableDto);
  342. return this.getList(courseTableDto);
  343. }
  344. private List<ScheduleWeekExportQueryVo> buildScheduleWeekExportQueryList(CourseTableVo courseTableVo) {
  345. List<ClassTime> classTimeList = courseTableVo.getClassTimeList();
  346. List<CourseDetailVo> courseList = courseTableVo.getCourseList();
  347. List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList = new ArrayList<>();
  348. if (!courseList.isEmpty()) {
  349. Map<Integer, Map<Integer, List<CourseDetailVo>>> courseDetailVoMap = buildCourseDetailMap(courseList);
  350. scheduleWeekExportQueryVoList.addAll(buildScheduleWeekExportQueryVoList(courseDetailVoMap, classTimeList));
  351. }
  352. return scheduleWeekExportQueryVoList;
  353. }
  354. private Map<Integer, Map<Integer, List<CourseDetailVo>>> buildCourseDetailMap(List<CourseDetailVo> courseList) {
  355. // 实现构建课程详情Map的逻辑
  356. Map<Integer, Map<Integer, List<CourseDetailVo>>> courseDetailVoMap = new HashMap<>();
  357. for (CourseDetailVo courseDetailVo : courseList) {
  358. int timePeriod = Integer.parseInt(courseDetailVo.getTimePeriod().trim());
  359. int timeNumber = Integer.parseInt(courseDetailVo.getTimeNumber().trim());
  360. // 如果时间段不存在,则创建一个新的时间段Map
  361. courseDetailVoMap.putIfAbsent(timePeriod, new HashMap<>());
  362. // 获取当前时间段的Map
  363. Map<Integer, List<CourseDetailVo>> timePeriodMap = courseDetailVoMap.get(timePeriod);
  364. // 如果时间序号不存在,则创建一个新的课程列表
  365. timePeriodMap.putIfAbsent(timeNumber, new ArrayList<>());
  366. // 将课程详情添加到对应的时间段和时间序号中
  367. timePeriodMap.get(timeNumber).add(courseDetailVo);
  368. }
  369. // 返回构建好的课程详情Map
  370. return courseDetailVoMap;
  371. }
  372. private List<ScheduleWeekExportQueryVo> buildScheduleWeekExportQueryVoList(Map<Integer, Map<Integer, List<CourseDetailVo>>> courseDetailVoMap, List<ClassTime> classTimeList) {
  373. List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList = new ArrayList<>();
  374. // 实现构建ScheduleWeekExportQueryVo对象列表的逻辑
  375. for (ClassTime classTime : classTimeList) {
  376. ScheduleWeekExportQueryVo scheduleWeekExportQueryVo = new ScheduleWeekExportQueryVo();
  377. scheduleWeekExportQueryVo.setTimePeriod(TimePeriodEnum.getValue(classTime.getTimePeriod()));
  378. scheduleWeekExportQueryVo.setTimeNumber(TimeNumberEnum.getValue(classTime.getNumber()));
  379. Map<Integer, List<CourseDetailVo>> timePeriodListMap = courseDetailVoMap.get(classTime.getTimePeriod());
  380. if (timePeriodListMap != null) {
  381. List<CourseDetailVo> courseDetailVoList = timePeriodListMap.get(classTime.getNumber());
  382. if (courseDetailVoList != null) {
  383. Map<Integer, CourseDetailVo> courseDetailVoByWeeksMap = courseDetailVoList.stream()
  384. .collect(Collectors.toMap(CourseDetailVo::getWeeks, item -> item));
  385. for (int i = 1; i <= 7; i++) {
  386. CourseDetailVo courseDetailVo = courseDetailVoByWeeksMap.get(i);
  387. if (courseDetailVo != null) {
  388. String courseInfo = courseDetailVo.getCourseName() + "\n" +
  389. courseDetailVo.getTeacherName() + "\n" +
  390. courseDetailVo.getClassName() + "\n" +
  391. courseDetailVo.getClassroomName() + "\n";
  392. switch (i) {
  393. case 1:
  394. scheduleWeekExportQueryVo.setMonday(courseInfo);
  395. break;
  396. case 2:
  397. scheduleWeekExportQueryVo.setTuesday(courseInfo);
  398. break;
  399. case 3:
  400. scheduleWeekExportQueryVo.setWednesday(courseInfo);
  401. break;
  402. case 4:
  403. scheduleWeekExportQueryVo.setThursday(courseInfo);
  404. break;
  405. case 5:
  406. scheduleWeekExportQueryVo.setFriday(courseInfo);
  407. break;
  408. case 6:
  409. scheduleWeekExportQueryVo.setSaturday(courseInfo);
  410. break;
  411. case 7:
  412. scheduleWeekExportQueryVo.setSunday(courseInfo);
  413. break;
  414. }
  415. }
  416. }
  417. }
  418. }
  419. scheduleWeekExportQueryVoList.add(scheduleWeekExportQueryVo);
  420. }
  421. // 返回构建好的ScheduleWeekExportQueryVo对象列表
  422. return scheduleWeekExportQueryVoList;
  423. }
  424. private void writeScheduleWeekExportToExcel(CourseTableVo courseTableVo, ByteArrayOutputStream outputStream, List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList) {
  425. // 创建内容样式
  426. WriteCellStyle contentWriteCellStyle = createContentCellStyle();
  427. // 创建头部样式
  428. WriteCellStyle headWriteCellStyle = createHeadCellStyle();
  429. // 将数据写入Excel文件
  430. try (ExcelWriter excelWriter = EasyExcel.write(outputStream, ScheduleWeekExportQueryVo.class)
  431. .registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle))
  432. .build()) {
  433. writeSheetHead(courseTableVo, excelWriter);
  434. writeSheetContent(excelWriter, scheduleWeekExportQueryVoList);
  435. }
  436. }
  437. private void writeSheetContent(ExcelWriter excelWriter, List<ScheduleWeekExportQueryVo> scheduleWeekExportQueryVoList) {
  438. int mergeRowIndex = 2;
  439. int[] mergeColumeIndex = {0};
  440. ExcelMergeUtil excelFillCellMergeStrategy = new ExcelMergeUtil(mergeRowIndex, mergeColumeIndex);
  441. WriteTable writeSheetContentTable = EasyExcel.writerTable(1).needHead(Boolean.TRUE).automaticMergeHead(Boolean.TRUE).registerWriteHandler(excelFillCellMergeStrategy).build();
  442. excelWriter.write(scheduleWeekExportQueryVoList, EasyExcel.writerSheet("模板").build(), writeSheetContentTable);
  443. }
  444. private void writeSheetHead(CourseTableVo courseTableVo, ExcelWriter excelWriter) {
  445. List<List<String>> sheetHeadList = new ArrayList<>();
  446. sheetHeadList.add(Collections.singletonList(courseTableVo.getSemesterName() + " "
  447. + ((courseTableVo.getTeacherName() != null) ? courseTableVo.getTeacherName() : courseTableVo.getClassName()) + " "
  448. + courseTableVo.getWeek() + " "
  449. + "课程表"));
  450. ExcelFillCellMergePrevColUtil sheetHeadColumn = new ExcelFillCellMergePrevColUtil();
  451. sheetHeadColumn.add(0, 0, 8);
  452. WriteTable writeSheetHeadTable = EasyExcel.writerTable(0).needHead(Boolean.TRUE).head(sheetHeadList).registerWriteHandler(sheetHeadColumn).build();
  453. excelWriter.write(new ArrayList<>(), EasyExcel.writerSheet("模板").needHead(Boolean.FALSE).build(), writeSheetHeadTable);
  454. }
  455. private WriteCellStyle createContentCellStyle() {
  456. WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
  457. contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
  458. contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  459. contentWriteCellStyle.setWrapped(true);
  460. WriteFont contentWriteFont = new WriteFont();
  461. contentWriteFont.setFontHeightInPoints((short) 12);
  462. contentWriteFont.setFontName("宋体");
  463. contentWriteCellStyle.setWriteFont(contentWriteFont);
  464. contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
  465. contentWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
  466. contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
  467. contentWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
  468. contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
  469. contentWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
  470. contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
  471. contentWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
  472. return contentWriteCellStyle;
  473. }
  474. private WriteCellStyle createHeadCellStyle() {
  475. WriteCellStyle headWriteCellStyle = new WriteCellStyle();
  476. WriteFont headWriteFont = new WriteFont();
  477. headWriteFont.setFontName("宋体");
  478. headWriteFont.setFontHeightInPoints((short) 14);
  479. headWriteFont.setBold(true);
  480. headWriteCellStyle.setWriteFont(headWriteFont);
  481. headWriteCellStyle.setBorderBottom(BorderStyle.THIN);
  482. headWriteCellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
  483. headWriteCellStyle.setBorderLeft(BorderStyle.THIN);
  484. headWriteCellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
  485. headWriteCellStyle.setBorderRight(BorderStyle.THIN);
  486. headWriteCellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
  487. headWriteCellStyle.setBorderTop(BorderStyle.THIN);
  488. headWriteCellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
  489. headWriteCellStyle.setWrapped(true);
  490. headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
  491. headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
  492. headWriteCellStyle.setShrinkToFit(true);
  493. return headWriteCellStyle;
  494. }
  495. /**
  496. * 提交顶课接口
  497. *
  498. * @param courseTable
  499. * @param courseAdjust
  500. * @throws Exception
  501. */
  502. void sendSubstitute(CourseTable courseTable, WfCourseAdjust courseAdjust) throws Exception {
  503. String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/Substitute/Submit";
  504. JsonObject jsonObject = new JsonObject();
  505. jsonObject.addProperty("timetableId", courseTable.getJianyueId());
  506. jsonObject.addProperty("isCycles", Boolean.FALSE);
  507. jsonObject.addProperty("reason", courseAdjust.getReason());
  508. jsonObject.addProperty("teacherId", courseAdjust.getUserId());
  509. JsonArray extendIds = new JsonArray();
  510. extendIds.add(courseTable.getTeacherId());
  511. jsonObject.add("extendIds", extendIds);
  512. //获取时间戳
  513. long timestamp = System.currentTimeMillis();
  514. //生成签名
  515. String sign = ScheduleUtil.createSign(timestamp);
  516. String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
  517. }
  518. /**
  519. * 提交调课
  520. *
  521. * @param courseTable
  522. * @param swapCourseTable
  523. * @throws Exception
  524. */
  525. void sendExchange(CourseTable courseTable, CourseTable swapCourseTable, WfCourseAdjust courseAdjust) throws Exception {
  526. String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/Submit";
  527. JsonObject jsonObject = new JsonObject();
  528. jsonObject.addProperty("timetableId", courseTable.getJianyueId());
  529. jsonObject.addProperty("isCycles", Boolean.FALSE);
  530. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  531. jsonObject.addProperty("date", swapCourseTable.getScheduleDate().format(formatter));
  532. jsonObject.addProperty("numberOfDay", swapCourseTable.getTimeNumber());
  533. jsonObject.addProperty("rescheduleId", swapCourseTable.getJianyueId());
  534. jsonObject.addProperty("reason", courseAdjust.getReason());
  535. jsonObject.addProperty("teacherId", courseAdjust.getUserId());
  536. //获取时间戳
  537. long timestamp = System.currentTimeMillis();
  538. //生成签名
  539. String sign = ScheduleUtil.createSign(timestamp);
  540. String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
  541. }
  542. /**
  543. * 顶课预检查
  544. *
  545. * @param courseTable
  546. * @return 检查结果
  547. */
  548. JsonObject substitutePreTestin(String subTeacherId, CourseTable courseTable) throws Exception {
  549. JsonParser jsonParser = new JsonParser();
  550. String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/Substitute/PreTesting";
  551. JsonObject jsonObject = new JsonObject();
  552. jsonObject.addProperty("timetableId", courseTable.getJianyueId());
  553. jsonObject.addProperty("isCycles", Boolean.FALSE);
  554. JsonArray extendIds = new JsonArray();
  555. extendIds.add(subTeacherId);
  556. jsonObject.add("extendIds", extendIds);
  557. //获取时间戳
  558. long timestamp = System.currentTimeMillis();
  559. //生成签名
  560. String sign = ScheduleUtil.createSign(timestamp);
  561. String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
  562. if (StrUtil.isEmpty(result)) {
  563. return null;
  564. }
  565. return jsonParser.parse(result).getAsJsonObject();
  566. }
  567. /**
  568. * 调课预检查
  569. *
  570. * @param courseTable 需要调整的课程
  571. * @param swapCourseTable 对调的课程
  572. * @return 检查结果
  573. */
  574. JsonObject getExtendPreCheck(LocalDate swapDate, CourseTable courseTable, CourseTable swapCourseTable) throws Exception {
  575. JsonParser jsonParser = new JsonParser();
  576. String url = ScheduleUtil.apiUrl + "RescheduleApply/Extend/PreTesting";
  577. JsonObject jsonObject = new JsonObject();
  578. jsonObject.addProperty("timetableId", courseTable.getJianyueId());
  579. jsonObject.addProperty("isCycles", Boolean.FALSE);
  580. // jsonObject.addProperty("startDate", "2024-01-01");
  581. // jsonObject.addProperty("endDate", "2024-01-31");
  582. // jsonObject.addProperty("dayOfweek", 5);
  583. jsonObject.addProperty("numberOfday", swapCourseTable.getTimeNumber());
  584. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  585. jsonObject.addProperty("date", swapDate.format(formatter));
  586. jsonObject.addProperty("reschduleId", courseTable.getJianyueId());
  587. //获取时间戳
  588. long timestamp = System.currentTimeMillis();
  589. //生成签名
  590. String sign = ScheduleUtil.createSign(timestamp);
  591. String result = ScheduleUtil.doPost(url, jsonObject.toString(), sign, timestamp);
  592. if (StrUtil.isEmpty(result)) {
  593. return null;
  594. }
  595. return jsonParser.parse(result).getAsJsonObject();
  596. }
  597. /**
  598. * 获取节次
  599. *
  600. * @return
  601. */
  602. private Map<String, ClassTime> getClassTimeMap() {
  603. List<ClassTime> classTimes = classTimeMapper.selectList(null);
  604. Map<String, ClassTime> result = new HashMap<>();
  605. for (ClassTime item : classTimes) {
  606. String key = String.format("%d_%d", item.getTimePeriod(), item.getNumber());
  607. result.put(key, item);
  608. }
  609. return result;
  610. }
  611. /**
  612. * 当前时间是否在夏季
  613. *
  614. * @return
  615. */
  616. private Boolean isCurrentSummer() {
  617. DateTime now = DateUtil.date();
  618. DateTime summerStart = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getSummerStart()));
  619. DateTime summerEnd = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getSummerEnd()));
  620. DateTime winterStart = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getWinterStart()));
  621. DateTime winterEnd = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getWinterEnd()));
  622. // 如果开始时间大于结束时间,开始时间增加1年
  623. if (DateUtil.compare(summerStart, summerEnd) > 0) {
  624. summerEnd = DateUtil.offset(summerEnd, DateField.DAY_OF_YEAR, 1);
  625. }
  626. if (DateUtil.compare(winterStart, winterEnd) > 0) {
  627. winterEnd = DateUtil.offset(winterEnd, DateField.DAY_OF_YEAR, 1);
  628. }
  629. if (DateUtil.compare(summerStart, now) > 0 && DateUtil.compare(summerEnd, now) < 0) {
  630. return true;
  631. }
  632. return false;
  633. }
  634. /**
  635. * 解析word课表
  636. *
  637. * @param inputStream
  638. * @return
  639. * @throws IOException
  640. */
  641. private List<CourseTableParse> courseTableWordParses(InputStream inputStream) throws IOException {
  642. XWPFDocument doc = new XWPFDocument(inputStream);
  643. List<XWPFParagraph> paras = doc.getParagraphs();
  644. String semester = null;
  645. List<String> cNames = new ArrayList<>();
  646. //获取标题
  647. for (int i = 0; i < paras.size(); i++) {
  648. String txt = paras.get(i).getText();
  649. if (i == 0) {
  650. semester = txt;
  651. continue;
  652. }
  653. txt = txt.replaceAll("总课程表", "").replace("\n", "").trim();
  654. if (!txt.equals("") && !txt.equals(semester)) {
  655. cNames.add(txt);
  656. }
  657. }
  658. List<CourseTableParse> result = new ArrayList<>();
  659. //获取文档中所有的表格
  660. List<XWPFTable> tables = doc.getTables();
  661. int tNum = 0;
  662. for (XWPFTable table : tables) {
  663. int rNum = 0;
  664. String timePeriod = null;
  665. List<String> weeks = new ArrayList<>();
  666. List<XWPFTableRow> rows = table.getRows();
  667. for (XWPFTableRow row : rows) {
  668. //获取行对应的单元格
  669. List<XWPFTableCell> cells = row.getTableCells();
  670. String timeNumber = null;
  671. for (int i = 0; i < cells.size(); i++) {
  672. String cellText = cells.get(i).getText();
  673. if (cellText.equals("") || rNum < 1) continue;
  674. if (rNum == 1) {
  675. weeks.add(cellText);
  676. continue;
  677. }
  678. if (i == 0) {
  679. timePeriod = cellText;
  680. continue;
  681. }
  682. if (i == 1) {
  683. timeNumber = cellText;
  684. continue;
  685. }
  686. List<XWPFParagraph> cParagraph = cells.get(i).getParagraphs();
  687. CourseTableParse item = new CourseTableParse();
  688. item.setSemester(semester);
  689. item.setTimePeriod(TimePeriodEnum.getCode(timePeriod));
  690. item.setTimeNumber(TimeNumberEnum.getCode(timeNumber));
  691. String week = weeks.get(Math.max(i - 2, 0));
  692. item.setWeeksCn(week);
  693. item.setClassName(cNames.get(tNum));
  694. for (int j = 0; j < cParagraph.size(); j++) {
  695. cellText = cParagraph.get(j).getText().trim();
  696. switch (j) {
  697. case 0:
  698. item.setCourseName(cellText);
  699. break;
  700. case 1:
  701. item.setTeacherName(cellText);
  702. break;
  703. case 2:
  704. item.setSiteName(cellText);
  705. break;
  706. }
  707. }
  708. result.add(item);
  709. }
  710. rNum++;
  711. }
  712. tNum++;
  713. }
  714. inputStream.close();
  715. return result;
  716. }
  717. }