CourseTableServiceImpl.java 40 KB

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