|
@@ -177,7 +177,18 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
Date applyDate = DateUtils.truncate(new Date(timePeriod.getStartTime()), Calendar.DATE);
|
|
Date applyDate = DateUtils.truncate(new Date(timePeriod.getStartTime()), Calendar.DATE);
|
|
Date canCancelDay = DateUtil.addValues(applyDate, Calendar.DAY_OF_MONTH, -task.getAllowApplyCancelDays());
|
|
Date canCancelDay = DateUtil.addValues(applyDate, Calendar.DAY_OF_MONTH, -task.getAllowApplyCancelDays());
|
|
if (new Date().after(canCancelDay)) {
|
|
if (new Date().after(canCancelDay)) {
|
|
- throw new StatusException("可取消时间已过,无法在取消");
|
|
|
|
|
|
+ throw new StatusException("[cancel] 可取消时间已过,无法在取消");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ StudentEntity student = studentService.getById(studentApplyEntity.getStudentId());
|
|
|
|
+ if(student == null) {
|
|
|
|
+ log.warn("[cancel] 考生不存在, studentId:{} ", studentApplyEntity.getStudentId());
|
|
|
|
+ throw new StatusException("考生不存在");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 教学点管理员,只能取消本教学点的考生
|
|
|
|
+ if (user.getRole().equals(Role.TEACHING) && !user.getCategoryId().equals(student.getCategoryId())) {
|
|
|
|
+ throw new StatusException("[cancel] 只能取消本教学点的考生");
|
|
}
|
|
}
|
|
|
|
|
|
String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApplyEntity.getStudentId());
|
|
String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, studentApplyEntity.getStudentId());
|
|
@@ -187,11 +198,9 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
log.warn("[cancel] 获取锁失败,同一个考生不允许同时操作取消预约, lockKey:{}", studentApplyLockKey);
|
|
log.warn("[cancel] 获取锁失败,同一个考生不允许同时操作取消预约, lockKey:{}", studentApplyLockKey);
|
|
throw new StatusException(Constants.SYSTEM_BUSY);
|
|
throw new StatusException(Constants.SYSTEM_BUSY);
|
|
} else {
|
|
} else {
|
|
- /*
|
|
|
|
- //更新数据库
|
|
|
|
|
|
+ //更新预约取消标志
|
|
studentApplyEntity.setCancel(Boolean.TRUE);
|
|
studentApplyEntity.setCancel(Boolean.TRUE);
|
|
updateById(studentApplyEntity);
|
|
updateById(studentApplyEntity);
|
|
- */
|
|
|
|
|
|
|
|
ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
|
|
ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
|
|
bean.setStudentId(studentApplyEntity.getStudentId());
|
|
bean.setStudentId(studentApplyEntity.getStudentId());
|
|
@@ -203,11 +212,11 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
bean.setBizId(cacheService.increaseBizId());
|
|
bean.setBizId(cacheService.increaseBizId());
|
|
|
|
|
|
// 推送至预约队列
|
|
// 推送至预约队列
|
|
- boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
|
|
|
|
|
|
+ /*boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
|
|
if (!pushSuccess) {
|
|
if (!pushSuccess) {
|
|
log.error("[cancel] 预约消息推送失败,id:{}", id);
|
|
log.error("[cancel] 预约消息推送失败,id:{}", id);
|
|
throw new RuntimeException("取消失败,请稍后再试!");
|
|
throw new RuntimeException("取消失败,请稍后再试!");
|
|
- }
|
|
|
|
|
|
+ }*/
|
|
// 保存至预约缓存
|
|
// 保存至预约缓存
|
|
cacheService.saveStudentApplyRecord(bean);
|
|
cacheService.saveStudentApplyRecord(bean);
|
|
// 某考点某时段的“剩余可约数量”(归还1个被占数量)
|
|
// 某考点某时段的“剩余可约数量”(归还1个被占数量)
|
|
@@ -426,31 +435,75 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
}
|
|
}
|
|
|
|
|
|
//保存数据
|
|
//保存数据
|
|
- int successRow = 0;
|
|
|
|
for (int i = 0; i < applyList.size(); i++) {
|
|
for (int i = 0; i < applyList.size(); i++) {
|
|
StudentImportVO vo = applyList.get(i);
|
|
StudentImportVO vo = applyList.get(i);
|
|
try {
|
|
try {
|
|
- saveStudentApply(i, vo, user.getId());
|
|
|
|
|
|
+ List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
|
|
|
|
+ String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
|
|
|
|
+ RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
|
|
|
|
+ try {
|
|
|
|
+ if (!studentApplyLock.tryLock()) {
|
|
|
|
+ log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
|
|
|
|
+ } else {
|
|
|
|
+ log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
|
|
|
|
+ for (AgentAndTimeVO agentTimeVO : agentTimeList) {
|
|
|
|
+ StudentApplyEntity entity = new StudentApplyEntity();
|
|
|
|
+ entity.setStudentId(vo.getStudentId());
|
|
|
|
+ entity.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
+ entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
+ entity.setCancel(Boolean.FALSE);
|
|
|
|
+ entity.setOperateId(user.getId());
|
|
|
|
+ //保存考生预约
|
|
|
|
+ saveOrUpdateStudentApply(entity);
|
|
|
|
+
|
|
|
|
+ // 队列bean
|
|
|
|
+ ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
|
|
|
|
+ bean.setStudentId(vo.getStudentId());
|
|
|
|
+ bean.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
+ bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
+ bean.setCancel(Boolean.FALSE);
|
|
|
|
+ bean.setOperateId(user.getId());
|
|
|
|
+ bean.setOperateTime(System.currentTimeMillis());
|
|
|
|
+ bean.setBizId(cacheService.increaseBizId());
|
|
|
|
+
|
|
|
|
+ // 某考点某时段的“剩余可约数量”(抢占1个数量)
|
|
|
|
+ boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
|
|
|
|
+ if (!takeSuccess) {
|
|
|
|
+ log.warn("[importPreExam] 预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
|
|
|
|
+ bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
|
|
|
|
+ //考点
|
|
|
|
+ ExamSiteCacheBean examSiteBean = examSiteCacheService.getExamSiteById(bean.getExamSiteId());
|
|
|
|
+ //时段
|
|
|
|
+ TimePeriodEntity timePeriod = timePeriodService.getById(bean.getTimePeriodId());
|
|
|
|
+ String message = MessageFormat.format("第{0}行,预约考点:{1},预约时段:{2}", i + 1, examSiteBean.getExamSiteName(),
|
|
|
|
+ DateUtil.getStartAndEndTime(timePeriod.getStartTime(), timePeriod.getEndTime()));
|
|
|
|
+ throw new StatusException(message);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 保存至预约缓存
|
|
|
|
+ cacheService.saveStudentApplyRecord(bean);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
|
|
|
|
+ throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
|
|
|
|
+ } finally {
|
|
|
|
+ try {
|
|
|
|
+ if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
|
|
|
|
+ studentApplyLock.unlock();
|
|
|
|
+ log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.warn(e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
} catch (StatusException e) {
|
|
} catch (StatusException e) {
|
|
failRecords.add(newError(i + 1, "系统异常"));
|
|
failRecords.add(newError(i + 1, "系统异常"));
|
|
log.error("[importPreExam] 导入异常", e);
|
|
log.error("[importPreExam] 导入异常", e);
|
|
- successRow = i;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // 回滚
|
|
|
|
- if (CollectionUtils.isNotEmpty(failRecords)) {
|
|
|
|
- try {
|
|
|
|
- for (int i = 0; i <= successRow; i++) {
|
|
|
|
- StudentImportVO vo = applyList.get(i);
|
|
|
|
- rollBackStudentApply(vo, user.getId());
|
|
|
|
- }
|
|
|
|
- } catch (StatusException e) {
|
|
|
|
- log.error("[importPreExam] 回滚异常", e);
|
|
|
|
- }
|
|
|
|
- return failRecords;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
} catch (StatusException e) {
|
|
} catch (StatusException e) {
|
|
log.error("[importPreExam] 导入预考失败,msg:{}", e.getMessage());
|
|
log.error("[importPreExam] 导入预考失败,msg:{}", e.getMessage());
|
|
throw new StatusException(e.getMessage());
|
|
throw new StatusException(e.getMessage());
|
|
@@ -468,63 +521,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
return failRecords;
|
|
return failRecords;
|
|
}
|
|
}
|
|
|
|
|
|
- private void rollBackStudentApply(StudentImportVO vo, Long operateId) {
|
|
|
|
- List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
|
|
|
|
- String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
|
|
|
|
- RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
|
|
|
|
- try {
|
|
|
|
- if (!studentApplyLock.tryLock()) {
|
|
|
|
- log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
|
|
|
|
- } else {
|
|
|
|
- log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
|
|
|
|
- for (AgentAndTimeVO agentTimeVO : agentTimeList) {
|
|
|
|
- // 队列bean
|
|
|
|
- ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
|
|
|
|
- bean.setStudentId(vo.getStudentId());
|
|
|
|
- bean.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
- bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
- bean.setCancel(Boolean.TRUE);
|
|
|
|
- bean.setOperateId(operateId);
|
|
|
|
- bean.setOperateTime(System.currentTimeMillis());
|
|
|
|
- bean.setBizId(cacheService.increaseBizId());
|
|
|
|
-
|
|
|
|
- // 某考点某时段 归还1个刚才被占数量
|
|
|
|
- cacheService.increaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
|
|
|
|
-
|
|
|
|
- // 保存至预约缓存
|
|
|
|
- cacheService.saveStudentApplyRecord(bean);
|
|
|
|
-
|
|
|
|
- // 数据写入到数据库
|
|
|
|
- StudentApplyEntity entity = new StudentApplyEntity();
|
|
|
|
- entity.setStudentId(vo.getStudentId());
|
|
|
|
- entity.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
- entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
- entity.setCancel(Boolean.TRUE);
|
|
|
|
- entity.setOperateId(operateId);
|
|
|
|
- // 取消预约
|
|
|
|
- StudentApplyEntity existStudentApply = findStudentApply(entity);
|
|
|
|
- if (existStudentApply != null) {
|
|
|
|
- existStudentApply.setCancel(Boolean.TRUE);
|
|
|
|
- baseMapper.updateById(existStudentApply);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
|
|
|
|
- throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
|
|
|
|
- } finally {
|
|
|
|
- try {
|
|
|
|
- if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
|
|
|
|
- studentApplyLock.unlock();
|
|
|
|
- log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.warn(e.getMessage());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -564,84 +560,6 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
return map;
|
|
return map;
|
|
}
|
|
}
|
|
|
|
|
|
- private void saveStudentApply(int row, StudentImportVO vo, Long userId) {
|
|
|
|
- List<AgentAndTimeVO> agentTimeList = vo.getAgentTimeList();
|
|
|
|
- String studentApplyLockKey = String.format(CacheConstants.LOCK_STUDENT_APPLY, vo.getStudentId());
|
|
|
|
- RLock studentApplyLock = (RLock) concurrentService.getLock(studentApplyLockKey);
|
|
|
|
- try {
|
|
|
|
- if (!studentApplyLock.tryLock()) {
|
|
|
|
- log.warn("[importPreExam] 获取锁失败,考生在同时操作预约,lockKey:{}", studentApplyLockKey);
|
|
|
|
- } else {
|
|
|
|
- log.warn("[importPreExam] 获取锁成功,lockKey:{}", studentApplyLockKey);
|
|
|
|
- for (AgentAndTimeVO agentTimeVO : agentTimeList) {
|
|
|
|
- // 队列bean
|
|
|
|
- ApplyRecordCacheBean bean = new ApplyRecordCacheBean();
|
|
|
|
- bean.setStudentId(vo.getStudentId());
|
|
|
|
- bean.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
- bean.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
- bean.setCancel(Boolean.FALSE);
|
|
|
|
- bean.setOperateId(userId);
|
|
|
|
- bean.setOperateTime(System.currentTimeMillis());
|
|
|
|
- bean.setBizId(cacheService.increaseBizId());
|
|
|
|
-
|
|
|
|
- // 某考点某时段的“剩余可约数量”(抢占1个数量)
|
|
|
|
- boolean takeSuccess = cacheService.decreaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
|
|
|
|
- if (!takeSuccess) {
|
|
|
|
- log.warn("[importPreExam] 预约失败,当前预约时段已约满!examSiteId:{} timePeriodId:{} studentId:{}",
|
|
|
|
- bean.getExamSiteId(), bean.getTimePeriodId(), bean.getStudentId());
|
|
|
|
- //考点
|
|
|
|
- ExamSiteCacheBean examSiteBean = examSiteCacheService.getExamSiteById(bean.getExamSiteId());
|
|
|
|
- //时段
|
|
|
|
- TimePeriodEntity timePeriod = timePeriodService.getById(bean.getTimePeriodId());
|
|
|
|
- String message = MessageFormat.format("第{0}行,预约考点:{1},预约时段:{2}", row + 1, examSiteBean.getExamSiteName(),
|
|
|
|
- DateUtil.getStartAndEndTime(timePeriod.getStartTime(), timePeriod.getEndTime()));
|
|
|
|
- throw new StatusException(message);
|
|
|
|
- }
|
|
|
|
- /*
|
|
|
|
- // 推送至预约队列
|
|
|
|
- boolean pushSuccess = cacheService.pushStudentApplyRecordQueue(bean);
|
|
|
|
- if (!pushSuccess) {
|
|
|
|
- // 推送失败时,归还1个被占数量
|
|
|
|
- cacheService.increaseApplyAvailableCount(bean.getExamSiteId(), bean.getTimePeriodId());
|
|
|
|
- throw new RuntimeException("预约消息推送失败,请稍后再试!");
|
|
|
|
- }*/
|
|
|
|
-
|
|
|
|
- // 保存至预约缓存
|
|
|
|
- cacheService.saveStudentApplyRecord(bean);
|
|
|
|
-
|
|
|
|
- // 数据写入到数据库
|
|
|
|
- StudentApplyEntity entity = new StudentApplyEntity();
|
|
|
|
- entity.setStudentId(vo.getStudentId());
|
|
|
|
- entity.setExamSiteId(agentTimeVO.getAgentId());
|
|
|
|
- entity.setTimePeriodId(agentTimeVO.getTimePeriodId());
|
|
|
|
- entity.setCancel(Boolean.FALSE);
|
|
|
|
- entity.setOperateId(userId);
|
|
|
|
- // 预约是否已经存在
|
|
|
|
- StudentApplyEntity existStudentApply = findStudentApply(entity);
|
|
|
|
- if (existStudentApply != null) {
|
|
|
|
- existStudentApply.setCancel(Boolean.FALSE);
|
|
|
|
- baseMapper.updateById(existStudentApply);
|
|
|
|
- } else {
|
|
|
|
- baseMapper.insert(entity);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.error("[importPreExam] 导入预约失败,msg:{}", e.getMessage());
|
|
|
|
- throw new StatusException("导入预考失败,错误原因:" + e.getMessage());
|
|
|
|
- } finally {
|
|
|
|
- try {
|
|
|
|
- if (studentApplyLock.isLocked() && studentApplyLock.isHeldByCurrentThread()) {
|
|
|
|
- studentApplyLock.unlock();
|
|
|
|
- log.info("[importPreExam] 解锁成功!lockKey:{}", studentApplyLockKey);
|
|
|
|
- }
|
|
|
|
- } catch (Exception e) {
|
|
|
|
- log.warn(e.getMessage());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private StudentApplyEntity findStudentApply(StudentApplyEntity studentApply) {
|
|
private StudentApplyEntity findStudentApply(StudentApplyEntity studentApply) {
|
|
LambdaQueryWrapper<StudentApplyEntity> lm = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<StudentApplyEntity> lm = new LambdaQueryWrapper<>();
|
|
lm.eq(StudentApplyEntity::getExamSiteId, studentApply.getExamSiteId());
|
|
lm.eq(StudentApplyEntity::getExamSiteId, studentApply.getExamSiteId());
|
|
@@ -1216,4 +1134,17 @@ public class StudentApplyServiceImpl extends ServiceImpl<StudentApplyDao, Studen
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Transactional
|
|
|
|
+ @Override
|
|
|
|
+ public void saveOrUpdateStudentApply(StudentApplyEntity studentApply) {
|
|
|
|
+ // 预约是否已经存在
|
|
|
|
+ StudentApplyEntity existStudentApply = findStudentApply(studentApply);
|
|
|
|
+ if (existStudentApply != null) {
|
|
|
|
+ existStudentApply.setCancel(Boolean.FALSE);
|
|
|
|
+ baseMapper.updateById(existStudentApply);
|
|
|
|
+ } else {
|
|
|
|
+ baseMapper.insert(studentApply);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|