ExamRoomServiceImpl.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package com.qmth.exam.reserve.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  4. import com.baomidou.mybatisplus.core.metadata.IPage;
  5. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  6. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7. import com.qmth.boot.core.collection.PageResult;
  8. import com.qmth.boot.core.exception.StatusException;
  9. import com.qmth.boot.tools.excel.ExcelReader;
  10. import com.qmth.boot.tools.excel.enums.ExcelType;
  11. import com.qmth.boot.tools.excel.model.DataMap;
  12. import com.qmth.exam.reserve.bean.login.LoginUser;
  13. import com.qmth.exam.reserve.bean.room.ExamRoomReq;
  14. import com.qmth.exam.reserve.bean.room.ExamRoomSaveReq;
  15. import com.qmth.exam.reserve.bean.room.ExamRoomVO;
  16. import com.qmth.exam.reserve.cache.impl.ApplyTaskCacheService;
  17. import com.qmth.exam.reserve.dao.ExamRoomDao;
  18. import com.qmth.exam.reserve.entity.ExamRoomEntity;
  19. import com.qmth.exam.reserve.entity.ExamSiteEntity;
  20. import com.qmth.exam.reserve.service.CategoryService;
  21. import com.qmth.exam.reserve.service.ExamRoomService;
  22. import com.qmth.exam.reserve.service.ExamSiteService;
  23. import com.qmth.exam.reserve.util.PageUtil;
  24. import org.apache.commons.collections4.CollectionUtils;
  25. import org.apache.commons.lang3.StringUtils;
  26. import org.slf4j.Logger;
  27. import org.slf4j.LoggerFactory;
  28. import org.springframework.beans.BeanUtils;
  29. import org.springframework.beans.factory.annotation.Autowired;
  30. import org.springframework.stereotype.Service;
  31. import org.springframework.transaction.annotation.Transactional;
  32. import org.springframework.transaction.interceptor.TransactionAspectSupport;
  33. import java.io.InputStream;
  34. import java.util.*;
  35. @Service
  36. public class ExamRoomServiceImpl extends ServiceImpl<ExamRoomDao, ExamRoomEntity> implements ExamRoomService {
  37. private static final Logger log = LoggerFactory.getLogger(ExamRoomServiceImpl.class);
  38. private static final String[] EXCEL_HEADER = new String[]{"考场号", "考场名称", "考场地址", "考场容量", "所属考点代码", "所属考点名称"};
  39. @Autowired
  40. private ExamSiteService examSiteService;
  41. @Autowired
  42. private CategoryService categoryService;
  43. @Autowired
  44. private ApplyTaskCacheService cacheService;
  45. @Override
  46. public PageResult<ExamRoomVO> pageExamRoom(ExamRoomReq req) {
  47. IPage<ExamRoomVO> iPage = baseMapper.pageExamRoom(new Page<>(req.getPageNumber(), req.getPageSize()),
  48. req);
  49. return PageUtil.of(iPage);
  50. }
  51. @Transactional
  52. @Override
  53. public void saveExamRoom(LoginUser user, ExamRoomSaveReq req) {
  54. checkExamRoom(req);
  55. ExamRoomEntity examRoomEntity = new ExamRoomEntity();
  56. BeanUtils.copyProperties(req, examRoomEntity);
  57. ExamRoomEntity beforeUpdateRoom = new ExamRoomEntity();
  58. if (req.getId() == null) {
  59. examRoomEntity.setEnable(Boolean.TRUE);
  60. save(examRoomEntity);
  61. } else {
  62. beforeUpdateRoom = getById(req.getId());
  63. updateById(examRoomEntity);
  64. }
  65. //更新考点容量和教学点容量
  66. updateExamSiteAndTeachingCapacity(req.getExamSiteId());
  67. if(req.getId() != null && !req.getExamSiteId().equals(beforeUpdateRoom.getExamSiteId())) {
  68. updateExamSiteAndTeachingCapacity(beforeUpdateRoom.getExamSiteId());
  69. }
  70. }
  71. @Transactional
  72. @Override
  73. public void enable(Long id, Boolean enable) {
  74. ExamRoomEntity examRoom = getById(id);
  75. LambdaUpdateWrapper<ExamRoomEntity> wrapper = new LambdaUpdateWrapper<>();
  76. wrapper.set(ExamRoomEntity::getEnable, enable);
  77. wrapper.eq(ExamRoomEntity::getId, id);
  78. update(null, wrapper);
  79. updateExamSiteAndTeachingCapacity(examRoom.getExamSiteId());
  80. }
  81. @Override
  82. public List<Map<String, Object>> importExamRoom(LoginUser user, InputStream inputStream) {
  83. List<DataMap> lineList = null;
  84. ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
  85. try {
  86. lineList = reader.getDataMapList();
  87. } catch (Exception e) {
  88. throw new StatusException("Excel 解析失败");
  89. }
  90. if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(lineList)) {
  91. throw new StatusException("Excel无内容");
  92. }
  93. List<Map<String, Object>> failRecords = new ArrayList<>();
  94. List<ExamRoomEntity> examRoomList = new ArrayList<>();
  95. Long teachingId = user.getCategoryId();
  96. for (int i = 0; i < lineList.size(); i++) {
  97. DataMap line = lineList.get(i);
  98. ExamRoomEntity room = new ExamRoomEntity();
  99. StringBuilder msg = new StringBuilder();
  100. String code = trimAndNullIfBlank(line.get(EXCEL_HEADER[0]));
  101. if (StringUtils.isBlank(code)) {
  102. msg.append(" 考场号不能为空");
  103. } else if(code.length() > 20) {
  104. msg.append(" 考场号不能超过20个字符");
  105. } else {
  106. room.setCode(code);
  107. }
  108. String name = trimAndNullIfBlank(line.get(EXCEL_HEADER[1]));
  109. if (StringUtils.isBlank(name)) {
  110. msg.append(" 考场名称不能为空");
  111. } else if (name.length() > 50) {
  112. msg.append(" 考场名称不能超过50个字符");
  113. } else {
  114. room.setName(name);
  115. }
  116. String address = trimAndNullIfBlank(line.get(EXCEL_HEADER[2]));
  117. if (StringUtils.isBlank(address)) {
  118. msg.append(" 考场地址不能为空");
  119. } else if (address.length() > 100) {
  120. msg.append(" 考场地址不能超过100个字符");
  121. } else {
  122. room.setAddress(address);
  123. }
  124. String capacity = trimAndNullIfBlank(line.get(EXCEL_HEADER[3]));
  125. if (StringUtils.isBlank(capacity) || !capacity.matches("\\d+") || Integer.parseInt(capacity) <= 0 || Integer.parseInt(capacity) > 99999) {
  126. msg.append(" 考场容量必须为大于0且小于100000的整数");
  127. } else {
  128. room.setCapacity(Integer.parseInt(capacity));
  129. }
  130. String examSiteCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[4]));
  131. if (StringUtils.isBlank(examSiteCode)) {
  132. msg.append(" 所属考点代码不能为空");
  133. }
  134. String examSiteName = trimAndNullIfBlank(line.get(EXCEL_HEADER[5]));
  135. if (StringUtils.isBlank(examSiteName)) {
  136. msg.append(" 所属考点名称不能为空");
  137. }
  138. List<ExamSiteEntity> examSiteList = listExamSite(examSiteCode, examSiteName, teachingId);
  139. if (examSiteList.isEmpty()) {
  140. msg.append(" 找不到所属考点");
  141. }
  142. if (examSiteList.size() > 1) {
  143. msg.append(" 找到的所属考点大于1个");
  144. }
  145. if (examSiteList.size() == 1) {
  146. // ExamRoomEntity examRoom = getExamRoom(examSiteList.get(0).getId(), code);
  147. // if (examRoom != null) {
  148. // msg.append(" 当前考点下已经存在考场代码为:").append(code).append("的考场");
  149. // } else {
  150. room.setExamSiteId(examSiteList.get(0).getId());
  151. room.setEnable(Boolean.TRUE);
  152. // }
  153. }
  154. if (msg.length() > 0) {
  155. failRecords.add(newError(i + 1, msg.toString()));
  156. } else {
  157. examRoomList.add(room);
  158. }
  159. }
  160. if (!failRecords.isEmpty())
  161. return failRecords;
  162. for (int i = 0; i < examRoomList.size(); i++) {
  163. ExamRoomEntity examRoomEntity = examRoomList.get(i);
  164. try {
  165. saveRoom(examRoomEntity);
  166. } catch (Exception e) {
  167. failRecords.add(newError(i + 1, " 系统异常"));
  168. log.error("导入异常", e);
  169. }
  170. }
  171. if (CollectionUtils.isNotEmpty(failRecords)) {
  172. TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  173. return failRecords;
  174. }
  175. return failRecords;
  176. }
  177. @Override
  178. public List<ExamRoomEntity> listExamRoom(Long examSiteId) {
  179. LambdaQueryWrapper<ExamRoomEntity> wrapper = new LambdaQueryWrapper<>();
  180. wrapper.eq(ExamRoomEntity::getExamSiteId, examSiteId);
  181. wrapper.eq(ExamRoomEntity::getEnable, Boolean.TRUE);
  182. wrapper.orderByAsc(ExamRoomEntity::getCode);
  183. return list(wrapper);
  184. }
  185. private void saveRoom(ExamRoomEntity room) {
  186. ExamRoomEntity examRoom = getExamRoom(room.getExamSiteId(), room.getCode());
  187. if (examRoom != null) {
  188. examRoom.setCapacity(room.getCapacity());
  189. LambdaUpdateWrapper<ExamRoomEntity> wrapper = new LambdaUpdateWrapper<>();
  190. wrapper.set(ExamRoomEntity::getName, room.getName());
  191. wrapper.set(ExamRoomEntity::getAddress, room.getAddress());
  192. wrapper.set(ExamRoomEntity::getCapacity, room.getCapacity());
  193. wrapper.set(ExamRoomEntity::getEnable, Boolean.TRUE);
  194. wrapper.eq(ExamRoomEntity::getId, examRoom.getId());
  195. update(null, wrapper);
  196. } else {
  197. save(room);
  198. }
  199. updateExamSiteAndTeachingCapacity(room.getExamSiteId());
  200. }
  201. private List<ExamSiteEntity> listExamSite(String examSiteCode, String examSiteName, Long categoryId) {
  202. ExamSiteEntity examSiteEntity = null;
  203. LambdaQueryWrapper<ExamSiteEntity> wrapper = new LambdaQueryWrapper<>();
  204. wrapper.eq(ExamSiteEntity::getCode, examSiteCode);
  205. wrapper.eq(ExamSiteEntity::getName, examSiteName);
  206. wrapper.eq(categoryId != null, ExamSiteEntity::getCategoryId, categoryId);
  207. return examSiteService.list(wrapper);
  208. }
  209. private void updateExamSiteAndTeachingCapacity(Long examSiteId) {
  210. examSiteService.updateExamSiteCapacity(examSiteId);
  211. ExamSiteEntity examSite = examSiteService.getById(examSiteId);
  212. categoryService.updateTeachingCapacity(examSite.getCategoryId());
  213. //清空考点容量缓存
  214. cacheService.clearApplyTotalCountCache(examSiteId);
  215. }
  216. private void checkExamRoom(ExamRoomSaveReq req) {
  217. if (StringUtils.isEmpty(req.getCode())) {
  218. throw new StatusException("考场代码不能为空");
  219. }
  220. if (StringUtils.isEmpty(req.getName())) {
  221. throw new StatusException("考场名称不能为空");
  222. }
  223. if (StringUtils.isEmpty(req.getAddress())) {
  224. throw new StatusException("考场地址不能为空");
  225. }
  226. if (req.getCapacity() == null || req.getCapacity() <= 0) {
  227. throw new StatusException("考场容量必须大于0");
  228. }
  229. if (req.getExamSiteId() == null) {
  230. throw new StatusException("请选择考点");
  231. }
  232. checkExamRoomExist(req, req.getId() != null);
  233. }
  234. private void checkExamRoomExist(ExamRoomSaveReq req, boolean idFlag) {
  235. LambdaQueryWrapper<ExamRoomEntity> wrapper = new LambdaQueryWrapper<>();
  236. wrapper.eq(ExamRoomEntity::getExamSiteId, req.getExamSiteId());
  237. wrapper.eq(ExamRoomEntity::getCode, req.getCode());
  238. wrapper.notIn(idFlag, ExamRoomEntity::getId, req.getId());
  239. ExamRoomEntity examRoomEntity = baseMapper.selectOne(wrapper);
  240. if (examRoomEntity != null) {
  241. ExamSiteEntity site = examSiteService.getById(req.getExamSiteId());
  242. throw new StatusException(site.getName() + "下已存在代码为:" + req.getCode() + "的考场");
  243. }
  244. }
  245. private ExamRoomEntity getExamRoom(Long examSiteId, String roomCode) {
  246. LambdaQueryWrapper<ExamRoomEntity> wrapper = new LambdaQueryWrapper<>();
  247. wrapper.eq(ExamRoomEntity::getExamSiteId, examSiteId);
  248. wrapper.eq(ExamRoomEntity::getCode, roomCode);
  249. return baseMapper.selectOne(wrapper);
  250. }
  251. private String trimAndNullIfBlank(String s) {
  252. if (StringUtils.isBlank(s)) {
  253. return null;
  254. }
  255. return s.trim();
  256. }
  257. private Map<String, Object> newError(int lineNum, String msg) {
  258. Map<String, Object> map = new HashMap<>();
  259. map.put("lineNum", lineNum);
  260. map.put("msg", msg);
  261. return map;
  262. }
  263. }