package com.qmth.exam.reserve.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.qmth.boot.core.collection.PageResult; import com.qmth.boot.core.exception.StatusException; import com.qmth.boot.tools.excel.ExcelReader; import com.qmth.boot.tools.excel.enums.ExcelType; import com.qmth.boot.tools.excel.model.DataMap; import com.qmth.exam.reserve.bean.login.LoginUser; import com.qmth.exam.reserve.bean.room.ExamRoomReq; import com.qmth.exam.reserve.bean.room.ExamRoomSaveReq; import com.qmth.exam.reserve.bean.room.ExamRoomVO; import com.qmth.exam.reserve.cache.impl.ApplyTaskCacheService; import com.qmth.exam.reserve.dao.ExamRoomDao; import com.qmth.exam.reserve.entity.ExamRoomEntity; import com.qmth.exam.reserve.entity.ExamSiteEntity; import com.qmth.exam.reserve.service.CategoryService; import com.qmth.exam.reserve.service.ExamRoomService; import com.qmth.exam.reserve.service.ExamSiteService; import com.qmth.exam.reserve.util.PageUtil; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.io.InputStream; import java.util.*; @Service public class ExamRoomServiceImpl extends ServiceImpl implements ExamRoomService { private static final Logger log = LoggerFactory.getLogger(ExamRoomServiceImpl.class); private static final String[] EXCEL_HEADER = new String[]{"考场号", "考场名称", "考场地址", "考场容量", "所属考点代码", "所属考点名称"}; @Autowired private ExamSiteService examSiteService; @Autowired private CategoryService categoryService; @Autowired private ApplyTaskCacheService cacheService; @Override public PageResult pageExamRoom(ExamRoomReq req) { IPage iPage = baseMapper.pageExamRoom(new Page<>(req.getPageNumber(), req.getPageSize()), req); return PageUtil.of(iPage); } @Transactional @Override public void saveExamRoom(LoginUser user, ExamRoomSaveReq req) { checkExamRoom(req); ExamRoomEntity examRoomEntity = new ExamRoomEntity(); BeanUtils.copyProperties(req, examRoomEntity); ExamRoomEntity beforeUpdateRoom = new ExamRoomEntity(); if (req.getId() == null) { examRoomEntity.setEnable(Boolean.TRUE); save(examRoomEntity); } else { beforeUpdateRoom = getById(req.getId()); updateById(examRoomEntity); } //更新考点容量和教学点容量 updateExamSiteAndTeachingCapacity(req.getExamSiteId()); if(req.getId() != null && !req.getExamSiteId().equals(beforeUpdateRoom.getExamSiteId())) { updateExamSiteAndTeachingCapacity(beforeUpdateRoom.getExamSiteId()); } } @Transactional @Override public void enable(Long id, Boolean enable) { ExamRoomEntity examRoom = getById(id); LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.set(ExamRoomEntity::getEnable, enable); wrapper.eq(ExamRoomEntity::getId, id); update(null, wrapper); updateExamSiteAndTeachingCapacity(examRoom.getExamSiteId()); } @Override public List> importExamRoom(LoginUser user, InputStream inputStream) { List lineList = null; ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0); try { lineList = reader.getDataMapList(); } catch (Exception e) { throw new StatusException("Excel 解析失败"); } if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(lineList)) { throw new StatusException("Excel无内容"); } List> failRecords = new ArrayList<>(); List examRoomList = new ArrayList<>(); Long teachingId = user.getCategoryId(); for (int i = 0; i < lineList.size(); i++) { DataMap line = lineList.get(i); ExamRoomEntity room = new ExamRoomEntity(); StringBuilder msg = new StringBuilder(); String code = trimAndNullIfBlank(line.get(EXCEL_HEADER[0])); if (StringUtils.isBlank(code)) { msg.append(" 考场号不能为空"); } else if(code.length() > 20) { msg.append(" 考场号不能超过20个字符"); } else { room.setCode(code); } String name = trimAndNullIfBlank(line.get(EXCEL_HEADER[1])); if (StringUtils.isBlank(name)) { msg.append(" 考场名称不能为空"); } else if (name.length() > 50) { msg.append(" 考场名称不能超过50个字符"); } else { room.setName(name); } String address = trimAndNullIfBlank(line.get(EXCEL_HEADER[2])); if (StringUtils.isBlank(address)) { msg.append(" 考场地址不能为空"); } else if (address.length() > 100) { msg.append(" 考场地址不能超过100个字符"); } else { room.setAddress(address); } String capacity = trimAndNullIfBlank(line.get(EXCEL_HEADER[3])); if (StringUtils.isBlank(capacity) || !capacity.matches("\\d+") || Integer.parseInt(capacity) <= 0 || Integer.parseInt(capacity) > 99999) { msg.append(" 考场容量必须为大于0且小于100000的整数"); } else { room.setCapacity(Integer.parseInt(capacity)); } String examSiteCode = trimAndNullIfBlank(line.get(EXCEL_HEADER[4])); if (StringUtils.isBlank(examSiteCode)) { msg.append(" 所属考点代码不能为空"); } String examSiteName = trimAndNullIfBlank(line.get(EXCEL_HEADER[5])); if (StringUtils.isBlank(examSiteName)) { msg.append(" 所属考点名称不能为空"); } List examSiteList = listExamSite(examSiteCode, examSiteName, teachingId); if (examSiteList.isEmpty()) { msg.append(" 找不到所属考点"); } if (examSiteList.size() > 1) { msg.append(" 找到的所属考点大于1个"); } if (examSiteList.size() == 1) { // ExamRoomEntity examRoom = getExamRoom(examSiteList.get(0).getId(), code); // if (examRoom != null) { // msg.append(" 当前考点下已经存在考场代码为:").append(code).append("的考场"); // } else { room.setExamSiteId(examSiteList.get(0).getId()); room.setEnable(Boolean.TRUE); // } } if (msg.length() > 0) { failRecords.add(newError(i + 1, msg.toString())); } else { examRoomList.add(room); } } if (!failRecords.isEmpty()) return failRecords; for (int i = 0; i < examRoomList.size(); i++) { ExamRoomEntity examRoomEntity = examRoomList.get(i); try { saveRoom(examRoomEntity); } catch (Exception e) { failRecords.add(newError(i + 1, " 系统异常")); log.error("导入异常", e); } } if (CollectionUtils.isNotEmpty(failRecords)) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return failRecords; } return failRecords; } @Override public List listExamRoom(Long examSiteId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ExamRoomEntity::getExamSiteId, examSiteId); wrapper.eq(ExamRoomEntity::getEnable, Boolean.TRUE); wrapper.orderByAsc(ExamRoomEntity::getCode); return list(wrapper); } private void saveRoom(ExamRoomEntity room) { ExamRoomEntity examRoom = getExamRoom(room.getExamSiteId(), room.getCode()); if (examRoom != null) { examRoom.setCapacity(room.getCapacity()); LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.set(ExamRoomEntity::getName, room.getName()); wrapper.set(ExamRoomEntity::getAddress, room.getAddress()); wrapper.set(ExamRoomEntity::getCapacity, room.getCapacity()); wrapper.set(ExamRoomEntity::getEnable, Boolean.TRUE); wrapper.eq(ExamRoomEntity::getId, examRoom.getId()); update(null, wrapper); } else { save(room); } updateExamSiteAndTeachingCapacity(room.getExamSiteId()); } private List listExamSite(String examSiteCode, String examSiteName, Long categoryId) { ExamSiteEntity examSiteEntity = null; LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ExamSiteEntity::getCode, examSiteCode); wrapper.eq(ExamSiteEntity::getName, examSiteName); wrapper.eq(categoryId != null, ExamSiteEntity::getCategoryId, categoryId); return examSiteService.list(wrapper); } private void updateExamSiteAndTeachingCapacity(Long examSiteId) { ExamSiteEntity oldExamSite = examSiteService.getById(examSiteId); examSiteService.updateExamSiteCapacity(examSiteId); ExamSiteEntity newExamSite = examSiteService.getById(examSiteId); categoryService.updateTeachingCapacity(newExamSite.getCategoryId()); /*//清空考点容量缓存 cacheService.clearApplyTotalCountCache(examSiteId);*/ //清空考点容量缓存 cacheService.initApplyAvailableCountCache(examSiteId, oldExamSite.getCapacity(), newExamSite.getCapacity()); } private void checkExamRoom(ExamRoomSaveReq req) { if (StringUtils.isEmpty(req.getCode())) { throw new StatusException("考场代码不能为空"); } if (StringUtils.isEmpty(req.getName())) { throw new StatusException("考场名称不能为空"); } if (StringUtils.isEmpty(req.getAddress())) { throw new StatusException("考场地址不能为空"); } if (req.getCapacity() == null || req.getCapacity() <= 0) { throw new StatusException("考场容量必须大于0"); } if (req.getExamSiteId() == null) { throw new StatusException("请选择考点"); } checkExamRoomExist(req, req.getId() != null); } private void checkExamRoomExist(ExamRoomSaveReq req, boolean idFlag) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ExamRoomEntity::getExamSiteId, req.getExamSiteId()); wrapper.eq(ExamRoomEntity::getCode, req.getCode()); wrapper.notIn(idFlag, ExamRoomEntity::getId, req.getId()); ExamRoomEntity examRoomEntity = baseMapper.selectOne(wrapper); if (examRoomEntity != null) { ExamSiteEntity site = examSiteService.getById(req.getExamSiteId()); throw new StatusException(site.getName() + "下已存在代码为:" + req.getCode() + "的考场"); } } private ExamRoomEntity getExamRoom(Long examSiteId, String roomCode) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ExamRoomEntity::getExamSiteId, examSiteId); wrapper.eq(ExamRoomEntity::getCode, roomCode); return baseMapper.selectOne(wrapper); } private String trimAndNullIfBlank(String s) { if (StringUtils.isBlank(s)) { return null; } return s.trim(); } private Map newError(int lineNum, String msg) { Map map = new HashMap<>(); map.put("lineNum", lineNum); map.put("msg", msg); return map; } }