CourseTableServiceImpl.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. package com.xjrsoft.module.courseTable.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.date.DateField;
  4. import cn.hutool.core.date.DateTime;
  5. import cn.hutool.core.date.DateUtil;
  6. import cn.hutool.core.util.ObjectUtil;
  7. import cn.hutool.core.util.StrUtil;
  8. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  9. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  10. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  11. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  12. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  13. import com.xjrsoft.common.enums.TimeNumberEnum;
  14. import com.xjrsoft.common.enums.TimePeriodEnum;
  15. import com.xjrsoft.common.enums.WeekEnum;
  16. import com.xjrsoft.common.exception.MyException;
  17. import com.xjrsoft.config.TimetableConfig;
  18. import com.xjrsoft.module.base.entity.BaseClass;
  19. import com.xjrsoft.module.base.entity.BaseSemester;
  20. import com.xjrsoft.module.base.mapper.BaseSemesterMapper;
  21. import com.xjrsoft.module.base.service.IBaseClassService;
  22. import com.xjrsoft.module.base.service.IBaseSemesterService;
  23. import com.xjrsoft.module.courseTable.dto.ClassListDto;
  24. import com.xjrsoft.module.courseTable.dto.CourseTableParse;
  25. import com.xjrsoft.module.courseTable.entity.ClassTime;
  26. import com.xjrsoft.module.courseTable.entity.CourseTable;
  27. import com.xjrsoft.module.courseTable.mapper.ClassTimeMapper;
  28. import com.xjrsoft.module.courseTable.mapper.CourseTableMapper;
  29. import com.xjrsoft.module.courseTable.service.ICourseTableService;
  30. import com.xjrsoft.module.courseTable.vo.ClassListVo;
  31. import com.xjrsoft.module.schedule.dto.CourseTableDto;
  32. import com.xjrsoft.module.schedule.vo.CourseDetailVo;
  33. import com.xjrsoft.module.schedule.vo.CourseTableVo;
  34. import com.xjrsoft.module.teacher.entity.BaseTeacher;
  35. import com.xjrsoft.module.teacher.entity.XjrUser;
  36. import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
  37. import lombok.AllArgsConstructor;
  38. import org.apache.poi.xwpf.usermodel.XWPFDocument;
  39. import org.apache.poi.xwpf.usermodel.XWPFParagraph;
  40. import org.apache.poi.xwpf.usermodel.XWPFTable;
  41. import org.apache.poi.xwpf.usermodel.XWPFTableCell;
  42. import org.apache.poi.xwpf.usermodel.XWPFTableRow;
  43. import org.springframework.stereotype.Service;
  44. import org.springframework.transaction.annotation.Transactional;
  45. import java.io.IOException;
  46. import java.io.InputStream;
  47. import java.time.Duration;
  48. import java.time.Instant;
  49. import java.time.LocalDateTime;
  50. import java.time.ZoneId;
  51. import java.util.ArrayList;
  52. import java.util.HashMap;
  53. import java.util.List;
  54. import java.util.Map;
  55. import java.util.stream.Collectors;
  56. /**
  57. * <p>
  58. * 课表 服务实现类
  59. * </p>
  60. *
  61. * @author baomidou
  62. * @since 2023-09-02 02:19:56
  63. */
  64. @Service
  65. @AllArgsConstructor
  66. public class CourseTableServiceImpl extends ServiceImpl<CourseTableMapper, CourseTable> implements ICourseTableService {
  67. private final CourseTableMapper courseTableMapper;
  68. private final IBaseClassService baseClassService;
  69. private final ITeacherbaseManagerService teacherbaseManagerService;
  70. private final IBaseSemesterService baseSemesterService;
  71. private final TimetableConfig timetableConfig;
  72. private final ClassTimeMapper classTimeMapper;
  73. private final BaseSemesterMapper baseSemesterMapper;
  74. @Override
  75. @Transactional(rollbackFor = Exception.class)
  76. public Boolean wordImport(InputStream inputStream) throws IOException {
  77. List<CourseTableParse> parses = courseTableWordParses(inputStream);
  78. String semester = null;
  79. if (parses.size() > 0) {
  80. semester = parses.get(0).getSemester();
  81. }
  82. BaseSemester baseSemester = baseSemesterService.getOne(Wrappers.<BaseSemester>query().lambda().eq(BaseSemester::getName, semester));
  83. if (baseSemester == null) {
  84. throw new MyException(String.format("学期【%s】不存在", semester));
  85. }
  86. // 获取班级信息
  87. List<BaseClass> baseClassList = baseClassService.list();
  88. Map<String, BaseClass> baseClassMap = baseClassList.stream().collect(Collectors.toMap(BaseClass::getName, a -> a, (k1, k2) -> k1));
  89. // 获取教师信息
  90. MPJLambdaWrapper<XjrUser> queryWrapper = new MPJLambdaWrapper<>();
  91. queryWrapper
  92. .disableSubLogicDel()
  93. .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
  94. .selectAll(XjrUser.class);
  95. List<XjrUser> xjrUserList = teacherbaseManagerService.list(queryWrapper);
  96. Map<String, XjrUser> xjrUsersMap = xjrUserList.stream().collect(Collectors.toMap(XjrUser::getName, a -> a, (k1, k2) -> k1));
  97. // 清空所有数据
  98. courseTableMapper.delete(Wrappers.<CourseTable>query().lambda().eq(CourseTable::getBaseSemesterId, baseSemester.getId()));
  99. List<CourseTable> params = new ArrayList<>();
  100. for (CourseTableParse item : parses) {
  101. CourseTable courseTable = BeanUtil.toBean(item, CourseTable.class);
  102. courseTable.setBaseSemesterId(baseSemester.getId());
  103. BaseClass baseClass = baseClassMap.get(item.getClassName());
  104. if (baseClass != null) {
  105. courseTable.setClassId(baseClass.getId());
  106. }
  107. XjrUser xjrUser = xjrUsersMap.get(item.getTeacherName());
  108. if (xjrUser != null) {
  109. courseTable.setTeacherId(xjrUser.getId());
  110. }
  111. if (item.getWeeksCn() != null) {
  112. courseTable.setWeeks(WeekEnum.getCode(item.getWeeksCn()));
  113. }
  114. params.add(courseTable);
  115. }
  116. return this.saveBatch(params);
  117. }
  118. @Override
  119. public List<ClassListVo> classList(ClassListDto dto) {
  120. LambdaQueryWrapper<CourseTable> queryWrapper = new LambdaQueryWrapper<>();
  121. queryWrapper.eq(CourseTable::getClassId, dto.getClassId())
  122. .eq(ObjectUtil.isNotEmpty(dto.getWeeks()), CourseTable::getWeeks,dto.getWeeks());
  123. List<CourseTable> courseTables = courseTableMapper.selectList(queryWrapper);
  124. List<ClassListVo> classListVos = BeanUtil.copyToList(courseTables, ClassListVo.class);
  125. Boolean isCurrentSummer = isCurrentSummer();
  126. Map<String, ClassTime> classTimeMap = getClassTimeMap();
  127. // 获取节次时间
  128. for (int i = 0; i < classListVos.size(); i++) {
  129. ClassListVo c = classListVos.get(i);
  130. String key = String.format("%d_%d", c.getTimePeriod(), c.getTimeNumber());
  131. ClassTime ct = classTimeMap.get(key);
  132. if (ct != null) {
  133. if (isCurrentSummer) {
  134. c.setStartTime(ct.getSummerStartTime());
  135. c.setEndTime(ct.getSummerEndTime());
  136. } else {
  137. c.setStartTime(ct.getWinterStartTime());
  138. c.setEndTime(ct.getWinterEndTime());
  139. }
  140. }
  141. }
  142. return classListVos;
  143. }
  144. @Override
  145. public CourseTableVo getList(CourseTableDto dto) {
  146. List<ClassTime> classTimes = classTimeMapper.selectList(null);
  147. CourseTableVo tableVo = new CourseTableVo();
  148. tableVo.setClassTimeList(classTimes);
  149. if(dto.getSemesterId() != null){
  150. BaseSemester baseSemester = baseSemesterMapper.selectById(dto.getSemesterId());
  151. tableVo.setSemesterName(baseSemester.getName());
  152. LocalDateTime now = LocalDateTime.now();
  153. //计算本周是第几周
  154. LocalDateTime startDateTime = LocalDateTime.ofInstant(baseSemester.getStartDate().toInstant(), ZoneId.systemDefault());
  155. LocalDateTime endDateTime = LocalDateTime.ofInstant(baseSemester.getEndDate().toInstant(), ZoneId.systemDefault());
  156. Duration between = Duration.between(startDateTime, endDateTime);
  157. long days = between.toDays();
  158. int weeks = (int) Math.ceil((double) days / 7);
  159. for (int i = 0; i < weeks; i ++){
  160. LocalDateTime startDate = startDateTime.plusDays(i * 7).withHour(0).withMinute(0).withSecond(0).withNano(0);
  161. LocalDateTime endDate = startDateTime.plusDays((i + 1) * 7).withHour(23).withMinute(59).withSecond(59).withNano(9999);
  162. if(now.isAfter(startDate) && now.isBefore(endDate)){
  163. tableVo.setWeek("第" + (i + 1) + "周");
  164. }
  165. }
  166. }
  167. if(!StrUtil.isEmpty(dto.getTeacherName())){
  168. List<XjrUser> userList = teacherbaseManagerService.list(
  169. new QueryWrapper<XjrUser>().lambda()
  170. .like(!StrUtil.isEmpty(dto.getTeacherName()), XjrUser::getName, dto.getTeacherName())
  171. .like(!StrUtil.isEmpty(dto.getJobNumber()), XjrUser::getCode, dto.getJobNumber())
  172. );
  173. if(userList != null && !userList.isEmpty()){
  174. XjrUser xjrUser = userList.get(0);
  175. dto.setTeacherId(xjrUser.getId());
  176. tableVo.setTeacherName(xjrUser.getName());
  177. }
  178. }
  179. List<CourseDetailVo> list = courseTableMapper.getList(dto);
  180. tableVo.setCourseList(list);
  181. tableVo.setClassHour(list.size());
  182. if(dto.getClassId() != null){
  183. BaseClass baseClass = baseClassService.getById(dto.getClassId());
  184. tableVo.setClassName(baseClass.getName());
  185. }
  186. return tableVo;
  187. }
  188. /**
  189. * 获取节次
  190. *
  191. * @return
  192. */
  193. private Map<String, ClassTime> getClassTimeMap() {
  194. List<ClassTime> classTimes = classTimeMapper.selectList(null);
  195. Map<String, ClassTime> result = new HashMap<>();
  196. for (ClassTime item : classTimes) {
  197. String key = String.format("%d_%d", item.getTimePeriod(), item.getNumber());
  198. result.put(key, item);
  199. }
  200. return result;
  201. }
  202. /**
  203. * 当前时间是否在夏季
  204. *
  205. * @return
  206. */
  207. private Boolean isCurrentSummer() {
  208. DateTime now = DateUtil.date();
  209. DateTime summerStart = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getSummerStart()));
  210. DateTime summerEnd = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getSummerEnd()));
  211. DateTime winterStart = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getWinterStart()));
  212. DateTime winterEnd = DateUtil.parse(String.format("%d-%s", now.year(), timetableConfig.getWinterEnd()));
  213. // 如果开始时间大于结束时间,开始时间增加1年
  214. if (DateUtil.compare(summerStart, summerEnd) > 0) {
  215. summerEnd = DateUtil.offset(summerEnd, DateField.DAY_OF_YEAR, 1);
  216. }
  217. if (DateUtil.compare(winterStart, winterEnd) > 0) {
  218. winterEnd = DateUtil.offset(winterEnd, DateField.DAY_OF_YEAR, 1);
  219. }
  220. if (DateUtil.compare(summerStart, now) > 0 && DateUtil.compare(summerEnd, now) < 0) {
  221. return true;
  222. }
  223. return false;
  224. }
  225. /**
  226. * 解析word课表
  227. *
  228. * @param inputStream
  229. * @return
  230. * @throws IOException
  231. */
  232. private List<CourseTableParse> courseTableWordParses(InputStream inputStream) throws IOException {
  233. XWPFDocument doc = new XWPFDocument(inputStream);
  234. List<XWPFParagraph> paras = doc.getParagraphs();
  235. String semester = null;
  236. List<String> cNames = new ArrayList<>();
  237. //获取标题
  238. for (int i = 0; i < paras.size(); i++) {
  239. String txt = paras.get(i).getText();
  240. if (i == 0) {
  241. semester = txt;
  242. continue;
  243. }
  244. txt = txt.replaceAll("总课程表", "").replace("\n", "").trim();
  245. if (!txt.equals("") && !txt.equals(semester)) {
  246. cNames.add(txt);
  247. }
  248. }
  249. List<CourseTableParse> result = new ArrayList<>();
  250. //获取文档中所有的表格
  251. List<XWPFTable> tables = doc.getTables();
  252. int tNum = 0;
  253. for (XWPFTable table : tables) {
  254. int rNum = 0;
  255. String timePeriod = null;
  256. List<String> weeks = new ArrayList<>();
  257. List<XWPFTableRow> rows = table.getRows();
  258. for (XWPFTableRow row : rows) {
  259. //获取行对应的单元格
  260. List<XWPFTableCell> cells = row.getTableCells();
  261. String timeNumber = null;
  262. for (int i = 0; i < cells.size(); i++) {
  263. String cellText = cells.get(i).getText();
  264. if (cellText.equals("") || rNum < 1) continue;
  265. if (rNum == 1) {
  266. weeks.add(cellText);
  267. continue;
  268. }
  269. if (i == 0) {
  270. timePeriod = cellText;
  271. continue;
  272. }
  273. if (i == 1) {
  274. timeNumber = cellText;
  275. continue;
  276. }
  277. List<XWPFParagraph> cParagraph = cells.get(i).getParagraphs();
  278. CourseTableParse item = new CourseTableParse();
  279. item.setSemester(semester);
  280. item.setTimePeriod(TimePeriodEnum.getCode(timePeriod));
  281. item.setTimeNumber(TimeNumberEnum.getCode(timeNumber));
  282. String week = weeks.get(Math.max(i - 2, 0));
  283. item.setWeeksCn(week);
  284. item.setClassName(cNames.get(tNum));
  285. for (int j = 0; j < cParagraph.size(); j++) {
  286. cellText = cParagraph.get(j).getText().trim();
  287. switch (j) {
  288. case 0:
  289. item.setCourseName(cellText);
  290. break;
  291. case 1:
  292. item.setTeacherName(cellText);
  293. break;
  294. case 2:
  295. item.setSiteName(cellText);
  296. break;
  297. }
  298. }
  299. result.add(item);
  300. }
  301. rNum++;
  302. }
  303. tNum++;
  304. }
  305. inputStream.close();
  306. return result;
  307. }
  308. }