Browse Source

程序优化

haogh 1 year ago
parent
commit
7103016696

+ 8 - 2
src/main/java/com/qmth/exam/reserve/controller/admin/StudentApplyController.java

@@ -96,14 +96,20 @@ public class StudentApplyController extends BaseController {
     @ApiOperation(value = "导入预考")
     @PostMapping(value = "/import")
     public Map<String, Object> importPreExamStd(@ApiParam("教学点ID") @RequestParam Long teachingId,
-            @RequestParam MultipartFile file) {
+            @ApiParam("教学点所在的层级") @RequestParam Integer level, @RequestParam MultipartFile file) {
         LoginUser user = this.curLoginUser();
         if (!Role.TEACHING.equals(user.getRole())) {
             throw new StatusException("没有权限");
         }
+        if (teachingId == null) {
+            throw new StatusException("请选择教学点");
+        }
+        if (!user.getCategoryId().equals(teachingId)) {
+            throw new StatusException("请选择本教学点,不要选择其他教学点");
+        }
         List<Map<String, Object>> failRecords = new ArrayList<Map<String, Object>>();
         try {
-            failRecords = studentApplyService.importPreExam(null, teachingId, file.getInputStream());
+            failRecords = studentApplyService.importPreExam(null, teachingId, level, file.getInputStream());
         } catch (IOException e) {
             throw new StatusException("文件读取出错", e);
         }

+ 0 - 1
src/main/java/com/qmth/exam/reserve/job/AutoArrangeExamJob.java

@@ -12,7 +12,6 @@ public class AutoArrangeExamJob {
     @Autowired
     private StudentApplyService studentApplyService;
 
-    // 0 0/1 * * * ?
     @Scheduled(cron = "0 * 12 * * ?")
     public void autoArrangeExam() {
         studentApplyService.autoLayout(null);

+ 1 - 1
src/main/java/com/qmth/exam/reserve/service/StudentApplyService.java

@@ -17,7 +17,7 @@ public interface StudentApplyService extends IService<StudentApplyEntity> {
 
     void cancel(LoginUser user, Long id);
 
-    List<Map<String, Object>> importPreExam(LoginUser user, Long teachingId, InputStream inputStream);
+    List<Map<String, Object>> importPreExam(LoginUser user, Long teachingId, Integer level, InputStream inputStream);
 
     void autoAssign(Long taskId);
 

+ 0 - 6
src/main/java/com/qmth/exam/reserve/service/impl/OperateLogServiceImpl.java

@@ -1,7 +1,5 @@
 package com.qmth.exam.reserve.service.impl;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -13,13 +11,9 @@ import com.qmth.exam.reserve.service.OperateLogService;
 @Service
 public class OperateLogServiceImpl extends ServiceImpl<OperateLogDao, OperateLogEntity> implements OperateLogService {
 
-    private static final Logger log = LoggerFactory.getLogger(OperateLogServiceImpl.class);
-
     @Override
     public void insertOperateLog(Long operateId, EventType eventType, String content) {
         OperateLogEntity operateLog = new OperateLogEntity();
-        operateLog.setCreateTime(System.currentTimeMillis());
-        operateLog.setUpdateTime(System.currentTimeMillis());
         operateLog.setOperateId(operateId);
         operateLog.setEventType(eventType.toString());
         operateLog.setContent(content);

+ 53 - 47
src/main/java/com/qmth/exam/reserve/service/impl/StudentApplyServiceImpl.java

@@ -10,11 +10,11 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.DateUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -32,6 +32,7 @@ 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.boot.tools.uuid.FastUUID;
 import com.qmth.exam.reserve.bean.login.LoginUser;
 import com.qmth.exam.reserve.bean.stdapply.AgentAndTimeVO;
 import com.qmth.exam.reserve.bean.stdapply.StudentApplyReq;
@@ -114,23 +115,22 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         if (timePeroid == null)
             throw new StatusException("考试时段不存在,请检查考试时段数据!");
         ApplyTaskEntity task = getApplyTask();
-        Date applyDate = DateUtil.parse(DateUtil.getShortDateByLongTime(timePeroid.getStartTime()), "yyyy-MM-dd");
+        Date applyDate = DateUtils.truncate(new Date(timePeroid.getStartTime()), Calendar.DATE);
         Date canCancelDay = DateUtil.addValues(applyDate, Calendar.DAY_OF_MONTH, -task.getAllowApplyCancelDays());
         if (new Date().after(canCancelDay))
             throw new StatusException("可取消时间已过,无法取消!");
         studentApply.setCancel(Boolean.TRUE);
         this.baseMapper.updateById(studentApply);
-        // TODO redis更新:该时段redis已预约的数量减1
-        operateLogService.insertOperateLog(user.getId(), EventType.CANCEL_APPLY, JsonHelper.toJson(studentApply));
-    }
 
-    public static void main(String[] args) {
-        System.out.println(Calendar.DAY_OF_MONTH);
+        // TODO redis更新:该时段redis已预约的数量加1
+
+        operateLogService.insertOperateLog(user.getId(), EventType.CANCEL_APPLY, JsonHelper.toJson(studentApply));
     }
 
     @Transactional
     @Override
-    public List<Map<String, Object>> importPreExam(LoginUser user, Long teachingId, InputStream inputStream) {
+    public List<Map<String, Object>> importPreExam(LoginUser user, Long teachingId, Integer level,
+            InputStream inputStream) {
         checkInOpenTime();
         List<DataMap> lineList = null;
         ExcelReader reader = ExcelReader.create(ExcelType.XLSX, inputStream, 0);
@@ -146,7 +146,7 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             throw new StatusException("Excel无内容");
         }
         List<Map<String, Object>> failRecords = new ArrayList<Map<String, Object>>();
-        Map<String, Long> teachingCache = getTeachingCache();
+        Map<String, Long> teachingCache = getTeachingCache(level);
         Map<String, Long> agentCache = getAgentCache(teachingId);
         Map<String, Long> timeCache = getTimePeriodCache();
         List<StudentImportVO> applyList = new ArrayList<>();
@@ -188,9 +188,12 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             if (categoryId == null) {
                 msg.append(" 所属教学点不存在");
             }
-            if (!student.getCategoryId().equals(categoryId)) {
+            if (categoryId != null && !student.getCategoryId().equals(categoryId)) {
                 msg.append(" 考生所属教学点和库中的考生教学点不匹配");
             }
+            if (categoryId != null && !categoryId.equals(teachingId)) {
+                msg.append(" 不是本教学点的考生");
+            }
 
             String agentName1 = trimAndNullIfBlank(line.get(EXCEL_HEADER[4]));
             if (StringUtils.isBlank(agentName1)) {
@@ -298,41 +301,42 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             try {
                 saveStdApply(user.getId(), vo);
             } catch (StatusException e) {
-                failRecords.add(newError(i + 1, e.getMessage()));
-            } catch (Exception e) {
                 failRecords.add(newError(i + 1, " 系统异常"));
                 log.error("导入异常", e);
             }
         }
         if (CollectionUtils.isNotEmpty(failRecords)) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+            return failRecords;
         }
         if (CollectionUtils.isEmpty(failRecords)) {
-            new Thread(() -> {
-                checkStudentApplyFinish(applyList);
-            }).start();
+            checkStudentApplyFinish(applyList);
         }
-        // TODO 更新redis
+
+        // TODO 导入预考后,更新redis
+
         return failRecords;
 
     }
 
     private void checkStudentApplyFinish(List<StudentImportVO> applyList) {
+        List<StudentEntity> toBeUpdateList = new ArrayList<>();
         for (StudentImportVO importVO : applyList) {
             StudentEntity student = studentService.getById(importVO.getStudentId());
-            List<StudentApplyEntity> haveApplyList = listStudentApply(importVO.getStudentId(), Boolean.TRUE);
+            List<StudentApplyEntity> haveApplyList = listStudentApply(importVO.getStudentId(), Boolean.FALSE);
             if (student.getApplyNumber().intValue() == haveApplyList.size()) {
                 // 更新考生的完成状态
                 student.setApplyFinished(Boolean.TRUE);
-                studentService.updateById(student);
+                toBeUpdateList.add(student);
             }
+            studentService.saveOrUpdateBatch(toBeUpdateList);
         }
     }
 
     private void checkInOpenTime() {
         ApplyTaskEntity task = getApplyTask();
-        Date start = DateUtil.parse(DateUtil.getLongDateByLongTime(task.getOpenApplyStartTime()), null);
-        Date end = DateUtil.parse(DateUtil.getLongDateByLongTime(task.getOpenApplyEndTime()), null);
+        Date start = new Date(task.getSelfApplyStartTime());
+        Date end = new Date(task.getSelfApplyEndTime());
         if (!DateUtil.isBetwwen(start, end)) {
             throw new StatusException("导入预考,必须要在第一阶段导入!");
         }
@@ -341,7 +345,10 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     private ApplyTaskEntity getApplyTask() {
         LambdaQueryWrapper<ApplyTaskEntity> wrapper = new LambdaQueryWrapper<ApplyTaskEntity>()
                 .eq(ApplyTaskEntity::getEnable, Boolean.TRUE);
-        return applyTaskService.getOne(wrapper);
+        ApplyTaskEntity task = applyTaskService.getOne(wrapper);
+        if (task == null)
+            throw new StatusException("未开启预约任务");
+        return task;
     }
 
     private void saveStdApply(Long userId, StudentImportVO vo) {
@@ -353,8 +360,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
         for (AgentAndTimeVO agentTime : agentTimeList) {
             StudentApplyEntity entity = new StudentApplyEntity();
             entity.setStudentId(vo.getStudentId());
-            entity.setCreateTime(System.currentTimeMillis());
-            entity.setUpdateTime(System.currentTimeMillis());
             entity.setExamSiteId(agentTime.getAgentId());
             entity.setTimePeriodId(agentTime.getTimePeriodId());
             entity.setCancel(Boolean.FALSE);
@@ -387,19 +392,18 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     }
 
     private Map<String, Long> getTimePeriodCache() {
-        Map<String, Long> map = new HashMap<>();
         LambdaQueryWrapper<TimePeriodEntity> lm = new LambdaQueryWrapper<>();
+        lm.eq(TimePeriodEntity::getApplyTaskId, getApplyTask().getId());
         List<TimePeriodEntity> timeList = timePeriodService.list(lm);
-        for (TimePeriodEntity time : timeList) {
-            map.put(time.getStartTime() + "-" + time.getEndTime(), time.getId());
-        }
-        return map;
+        return timeList.stream().collect(Collectors.toMap(item -> {
+            return item.getStartTime() + "-" + item.getEndTime();
+        }, TimePeriodEntity::getId));
     }
 
-    private Map<String, Long> getTeachingCache() {
+    private Map<String, Long> getTeachingCache(Integer level) {
         LambdaQueryWrapper<CategoryEntity> lm = new LambdaQueryWrapper<>();
         lm.eq(CategoryEntity::getEnable, Boolean.TRUE);
-        lm.eq(CategoryEntity::getLevel, CategoryLevel.TEACHING.getValue());
+        lm.eq(CategoryEntity::getLevel, level == null ? CategoryLevel.TEACHING.getValue() : level);
         List<CategoryEntity> categoryList = categoryService.list(lm);
         return categoryList.stream().collect(Collectors.toMap(CategoryEntity::getName, CategoryEntity::getId));
     }
@@ -443,7 +447,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     public void autoAssign(Long taskId) {
         checkAfterOpenTime();
         try {
-            redisClient.set(CacheConstants.LOCK_AUTO_APPLY, UUID.randomUUID(), TIMEOUT, TimeUnit.MINUTES);
+            boolean isSuccess = redisClient.tryLock(CacheConstants.LOCK_AUTO_APPLY, FastUUID.get(), TIMEOUT,
+                    TimeUnit.MINUTES);
+            if (!isSuccess) {
+                throw new StatusException("其他老师正在执行自动分配,请不要重复执行!");
+            }
             // 1、未完成预约的考生
             LambdaQueryWrapper<StudentEntity> lm = new LambdaQueryWrapper<>();
             lm.eq(StudentEntity::getApplyFinished, Boolean.FALSE);
@@ -490,8 +498,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
             int toApplyNum = student.getApplyNumber() - studentApplyList.size();
             if (toApplyNum > 0 && !haveApplySameTimePeriod(siteId, timeId, student.getId())) {
                 StudentApplyEntity studentApply = new StudentApplyEntity();
-                studentApply.setCreateTime(System.currentTimeMillis());
-                studentApply.setUpdateTime(System.currentTimeMillis());
                 studentApply.setStudentId(student.getId());
                 studentApply.setExamSiteId(siteId);
                 studentApply.setCancel(Boolean.FALSE);
@@ -528,9 +534,9 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
 
     private void checkAfterOpenTime() {
         ApplyTaskEntity task = getApplyTask();
-        Date openEndTime = DateUtil.parse(DateUtil.getLongDateByLongTime(task.getOpenApplyEndTime()), null);
-        Date selfStartTime = DateUtil.parse(DateUtil.getLongDateByLongTime(task.getSelfApplyStartTime()), null);
-        if (!DateUtil.isBetwwen(openEndTime, selfStartTime)) {
+        Date selfEndTime = new Date(task.getSelfApplyEndTime());
+        Date openStartTime = new Date(task.getOpenApplyStartTime());
+        if (!DateUtil.isBetwwen(selfEndTime, openStartTime)) {
             throw new StatusException("自动分配,时间必须要在第一阶段结束之后,第三阶段开始之前");
         }
     }
@@ -562,7 +568,7 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
                 noApplyNum++;
             } else if (student.getApplyNumber().intValue() > 1) {
                 noApplyNum = noApplyNum
-                        + (student.getApplyNumber() - listStudentApply(student.getId(), Boolean.TRUE).size());
+                        + (student.getApplyNumber() - listStudentApply(student.getId(), Boolean.FALSE).size());
             }
         }
         return noApplyNum;
@@ -597,12 +603,12 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     public void autoLayout(Long teachingId) {
         ApplyTaskEntity applyTask = getApplyTask();
         if (applyTask == null) {
-            log.info("没有开启预约任务");
+            log.info("没有开启预约任务");
             return;
         }
         boolean isSuccess = redisClient.tryLock(
-                CacheConstants.LOCK_ARRANGE_EXAM + DateUtil.formatShortDateString(new Date()), UUID.randomUUID(),
-                TIMEOUT, TimeUnit.MINUTES);
+                CacheConstants.LOCK_ARRANGE_EXAM + DateUtil.formatShortDateString(new Date()), FastUUID.get(), TIMEOUT,
+                TimeUnit.MINUTES);
         try {
             if (isSuccess) {
                 // 1.根据当前日期,查询不能取消的时段
@@ -610,7 +616,7 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
                 List<TimePeriodEntity> noCancelTimePeroidList = listNoCancelApplyTimePeroid(timePeriodList,
                         applyTask.getAllowApplyCancelDays());
                 if (noCancelTimePeroidList.isEmpty()) {
-                    log.info("当前时间,没有取消的时段。");
+                    log.info("当前时间不在取消预约范围内");
                     return;
                 }
                 // 2.查询考试日期的待排考的考生
@@ -679,10 +685,10 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
     }
 
     private List<TimePeriodEntity> listSameDayTimePeroid(List<TimePeriodEntity> timeList, Long startTime) {
-        String day = DateUtil.getShortDateWithoutSplitByLongTime(startTime);
+        Date day = new Date(startTime);
         List<TimePeriodEntity> resultList = new ArrayList<>();
         for (TimePeriodEntity time : timeList) {
-            if (DateUtil.getShortDateWithoutSplitByLongTime(startTime).equals(day))
+            if (DateUtils.isSameDay(day, new Date(time.getStartTime())))
                 resultList.add(time);
         }
         return resultList.stream().sorted(Comparator.comparing(TimePeriodEntity::getStartTime))
@@ -703,18 +709,18 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
 
     private List<TimePeriodEntity> listNoCancelApplyTimePeroid(List<TimePeriodEntity> list,
             Integer allowApplyCancelDays) {
-        String noCancelDate = getNoCancelApplyDate(allowApplyCancelDays);
+        Date noCancelDate = getNoCancelApplyDate(allowApplyCancelDays);
         List<TimePeriodEntity> noCancelTimePeroidList = new ArrayList<>();
         for (TimePeriodEntity time : list) {
-            if (DateUtil.getShortDateWithoutSplitByLongTime(time.getStartTime()).equals(noCancelDate))
+            if (DateUtils.isSameDay(noCancelDate, new Date(time.getStartTime())))
                 noCancelTimePeroidList.add(time);
         }
         return noCancelTimePeroidList;
 
     }
 
-    private String getNoCancelApplyDate(Integer allowApplyCancelDays) {
-        return DateUtil.formatShortDateString(DateUtil.addValues(Calendar.DAY_OF_MONTH, allowApplyCancelDays));
+    private Date getNoCancelApplyDate(Integer allowApplyCancelDays) {
+        return DateUtil.addValues(Calendar.DAY_OF_MONTH, allowApplyCancelDays);
     }
 
 }

+ 17 - 9
src/main/java/com/qmth/exam/reserve/service/impl/StudentImportAsyncServiceImpl.java

@@ -11,6 +11,7 @@ import org.apache.commons.codec.digest.DigestUtils;
 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.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
@@ -123,10 +124,13 @@ public class StudentImportAsyncServiceImpl implements StudentImportAsyncService
             updateStudentImportTask(task, ImportStatus.FAILURE.toString(), failRecords);
             return;
         }
+        List<StudentEntity> toAddStudentList = new ArrayList<>();
         for (int i = 0; i < studentList.size(); i++) {
             StudentEntity studentEntity = studentList.get(i);
             try {
-                saveStudent(studentEntity);
+                StudentEntity student = updateStudent(studentEntity);
+                if (student != null)
+                    toAddStudentList.add(student);
             } catch (StatusException e) {
                 failRecords.add(newError(i + 1, e.getMessage()));
             } catch (Exception e) {
@@ -136,7 +140,14 @@ public class StudentImportAsyncServiceImpl implements StudentImportAsyncService
                 return;
             }
         }
-
+        // 批量写入
+        try {
+            studentService.saveBatch(toAddStudentList);
+        } catch (Exception e) {
+            log.error("导入异常", e);
+            updateStudentImportTask(task, ImportStatus.FAILURE.toString(), failRecords);
+            return;
+        }
         updateStudentImportTask(task, ImportStatus.SUCCESS.toString(), failRecords);
     }
 
@@ -147,21 +158,18 @@ public class StudentImportAsyncServiceImpl implements StudentImportAsyncService
         importTaskService.saveOrUpdate(task);
     }
 
-    private void saveStudent(StudentEntity studentEntity) {
+    private StudentEntity updateStudent(StudentEntity studentEntity) {
         LambdaQueryWrapper<StudentEntity> wrapper = new LambdaQueryWrapper<StudentEntity>()
                 .eq(StudentEntity::getStudentCode, studentEntity.getStudentCode());
         StudentEntity existStudent = studentService.getOne(wrapper);
         if (existStudent != null) {
-            existStudent.setName(studentEntity.getName());
-            existStudent.setIdentityNumber(studentEntity.getIdentityNumber());
-            existStudent.setCategoryId(studentEntity.getCategoryId());
-            existStudent.setApplyNumber(studentEntity.getApplyNumber());
-            existStudent.setPassword(studentEntity.getPassword());
+            BeanUtils.copyProperties(studentEntity, existStudent);
             studentService.updateById(existStudent);
         } else {
             studentEntity.setApplyFinished(Boolean.FALSE);
-            studentService.save(studentEntity);
+            return studentEntity;
         }
+        return null;
     }
 
     private String trimAndNullIfBlank(String s) {