【修改】 考点服务器绑定专业sql增加查询条件
This commit is contained in:
@@ -48,485 +48,479 @@ import static pc.exam.pp.module.system.enums.ErrorCodeConstants.MONITOR_NOT_EXIS
|
||||
@Service
|
||||
@Validated
|
||||
public class MonitorServiceImpl implements MonitorService {
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
@Resource
|
||||
private MonitorMapper monitorMapper;
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
private ExamQuestionMapper examQuestionMapper;
|
||||
@Resource
|
||||
private EducationPaperMapper educationPaperMapper;
|
||||
@Resource
|
||||
private EducationPaperPersonMapper educationPaperPersonMapper;
|
||||
@Resource
|
||||
private EducationPaperTaskMapper educationPaperTaskMapper;
|
||||
@Resource
|
||||
private EducationPaperParamMapper educationPaperParamMapper;
|
||||
@Resource
|
||||
private EducationPaperSessionMapper educationPaperSessionMapper;
|
||||
@Resource
|
||||
private EducationPaperSchemeMapper educationPaperSchemeMapper;
|
||||
@Resource
|
||||
private ExamSpecialtyMapper examSpecialtyMapper;
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
@Resource
|
||||
private MonitorMapper monitorMapper;
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
private ExamQuestionMapper examQuestionMapper;
|
||||
@Resource
|
||||
private EducationPaperMapper educationPaperMapper;
|
||||
@Resource
|
||||
private EducationPaperPersonMapper educationPaperPersonMapper;
|
||||
@Resource
|
||||
private EducationPaperTaskMapper educationPaperTaskMapper;
|
||||
@Resource
|
||||
private EducationPaperParamMapper educationPaperParamMapper;
|
||||
@Resource
|
||||
private EducationPaperSessionMapper educationPaperSessionMapper;
|
||||
@Resource
|
||||
private EducationPaperSchemeMapper educationPaperSchemeMapper;
|
||||
@Resource
|
||||
private ExamSpecialtyMapper examSpecialtyMapper;
|
||||
|
||||
|
||||
// @Resource
|
||||
// @Resource
|
||||
// private FileService fileService;
|
||||
@Override
|
||||
public String createMonitor(MonitorSaveReqVO createReqVO) {
|
||||
@Override
|
||||
public String createMonitor(MonitorSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
MonitorDO monitor = BeanUtils.toBean(createReqVO, MonitorDO.class);
|
||||
monitorMapper.insert(monitor);
|
||||
// 返回
|
||||
return monitor.getMonitorId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMonitor(MonitorSaveReqVO updateReqVO) {
|
||||
@Override
|
||||
public void updateMonitor(MonitorSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateMonitorExists(updateReqVO.getMonitorId());
|
||||
// 更新
|
||||
MonitorDO updateObj = BeanUtils.toBean(updateReqVO, MonitorDO.class);
|
||||
monitorMapper.updateById(updateObj);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMonitor(String id) {
|
||||
@Override
|
||||
public void deleteMonitor(String id) {
|
||||
// 校验存在
|
||||
validateMonitorExists(id);
|
||||
// 删除
|
||||
monitorMapper.deleteById(id);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateMonitorExists(String id) {
|
||||
private void validateMonitorExists(String id) {
|
||||
if (monitorMapper.selectById(id) == null) {
|
||||
throw exception(MONITOR_NOT_EXISTS);
|
||||
}
|
||||
throw exception(MONITOR_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MonitorDO getMonitor(String id) {
|
||||
@Override
|
||||
public MonitorDO getMonitor(String id) {
|
||||
return monitorMapper.selectById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<MonitorDO> getMonitorPage(MonitorPageReqVO pageReqVO) {
|
||||
@Override
|
||||
public PageResult<MonitorDO> getMonitorPage(MonitorPageReqVO pageReqVO) {
|
||||
return monitorMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) throws RuntimeException {
|
||||
String key = "userCache:" + stuMonitorPaperVo.getTaskId() + ":" + stuMonitorPaperVo.getStuId();
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||
if (info == null) {
|
||||
return 0L;
|
||||
}
|
||||
@Override
|
||||
public long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) throws RuntimeException {
|
||||
String key = "userCache:"+stuMonitorPaperVo.getTaskId()+":" + stuMonitorPaperVo.getStuId();
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
||||
if (info==null){
|
||||
return 0L;
|
||||
}
|
||||
//获取属性 判断 专业/课程点位
|
||||
Long loginTenantId = SecurityFrameworkUtils.getLoginTenantId();
|
||||
//获取属性 判断 专业/课程点位
|
||||
Long loginTenantId = SecurityFrameworkUtils.getLoginTenantId();
|
||||
|
||||
if (!"1".equals(String.valueOf(loginTenantId))) {
|
||||
// 查询授权课程/专业列表
|
||||
List<TentSpecialy> tentSpecialyList = monitorMapper.selectTent(loginTenantId);
|
||||
List<TentSpecialy> tentSpecialies = filterSpecialtyList(tentSpecialyList);
|
||||
if (!"1".equals(String.valueOf(loginTenantId))) {
|
||||
// 查询授权课程/专业列表
|
||||
List<TentSpecialy> tentSpecialyList = monitorMapper.selectTent(loginTenantId);
|
||||
List<TentSpecialy> tentSpecialies = filterSpecialtyList(tentSpecialyList);
|
||||
|
||||
if (tentSpecialies.isEmpty()) {
|
||||
throw new MonitorSpecialtyException("授权课程的点位为空,请增加课程点位!");
|
||||
}
|
||||
if (tentSpecialies.isEmpty()) {
|
||||
throw new MonitorSpecialtyException("授权课程的点位为空,请增加课程点位!");
|
||||
}
|
||||
|
||||
// 构建授权数量映射:specialtyId -> 授权个数
|
||||
Map<String, Integer> authMap = tentSpecialies.stream()
|
||||
.collect(Collectors.toMap(
|
||||
TentSpecialy::getSpecialtyId,
|
||||
t -> {
|
||||
try {
|
||||
return Integer.parseInt(t.getPoints());
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
// 构建授权数量映射:specialtyId -> 授权个数
|
||||
Map<String, Integer> authMap = tentSpecialies.stream()
|
||||
.collect(Collectors.toMap(
|
||||
TentSpecialy::getSpecialtyId,
|
||||
t -> {
|
||||
try {
|
||||
return Integer.parseInt(t.getPoints());
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
));
|
||||
}
|
||||
));
|
||||
|
||||
// 查询 exam_specialty 所有 sp_id -> parent_id 映射(用来判断是否为专业)
|
||||
List<IdParentPair> pairList = examSpecialtyMapper.selectAllIdToParent(loginTenantId);
|
||||
// 查询 exam_specialty 所有 sp_id -> parent_id 映射(用来判断是否为专业)
|
||||
List<IdParentPair> pairList = examSpecialtyMapper.selectAllIdToParent(loginTenantId);
|
||||
|
||||
// 转换为 Map<String, String>
|
||||
Map<String, String> idToParentMap = pairList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
p -> String.valueOf(p.getSpId()),
|
||||
p -> p.getParentId() == null ? null : String.valueOf(p.getParentId())
|
||||
));
|
||||
// 转换为 Map<String, String>
|
||||
Map<String, String> idToParentMap = pairList.stream()
|
||||
.collect(Collectors.toMap(
|
||||
p -> String.valueOf(p.getSpId()),
|
||||
p -> p.getParentId() == null ? null : String.valueOf(p.getParentId())
|
||||
));
|
||||
|
||||
// 分类授权:哪些是专业,哪些是课程
|
||||
Set<String> authSpecialtyIds = new HashSet<>();
|
||||
Set<String> authCourseIds = new HashSet<>();
|
||||
for (TentSpecialy t : tentSpecialies) {
|
||||
String specialtyId = t.getSpecialtyId();
|
||||
String parentId = idToParentMap.get(specialtyId);
|
||||
if (parentId == null || "0".equals(parentId)) {
|
||||
authSpecialtyIds.add(specialtyId); // 是专业
|
||||
} else {
|
||||
authCourseIds.add(specialtyId); // 是课程
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 只有授权了“专业”,才去查 taskInVo 并校验
|
||||
if (!authSpecialtyIds.isEmpty()) {
|
||||
//查询 该试卷任务 设计的 专业
|
||||
List<SpecialtyVo> taskInVo = educationPaperTaskMapper.selectTaskCounts(stuMonitorPaperVo.getTaskId(),loginTenantId);
|
||||
|
||||
for (SpecialtyVo specialtyVo : taskInVo) {
|
||||
String specialtyId = specialtyVo.getSpecialtyId();
|
||||
if (!authSpecialtyIds.contains(specialtyId)) continue;
|
||||
|
||||
String specialtyName = specialtyVo.getSpecialtyName();
|
||||
Integer currentCount = specialtyVo.getCounts();
|
||||
Integer authCount = authMap.getOrDefault(specialtyId, 0);
|
||||
|
||||
if (currentCount > authCount) {
|
||||
int over = currentCount - authCount;
|
||||
throw new MonitorSpecialtyException("专业: " + specialtyName + " 正在考试数量(" + currentCount + ") 授权数量(" + authCount + "),超出:" + over);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 只有授权了“课程”,才去查 courseInVos 并校验
|
||||
if (!authCourseIds.isEmpty()) {
|
||||
//查询所有正在考试的 试卷id
|
||||
List<String> allInPaperIds = educationPaperMapper.selectSpecilayCounts(loginTenantId);
|
||||
// 所有正在考试的试卷中授权课程的统计信息
|
||||
List<CourseInVo> courseInVos = educationPaperTaskMapper.selectPaperCounts(allInPaperIds, loginTenantId);
|
||||
|
||||
//获取当前学生正在考试的试卷 ID
|
||||
String paperId = stuMonitorPaperVo.getPaperId();
|
||||
|
||||
//查询该试卷涉及的所有课程(课程ID + 名称)
|
||||
List<CourseInVo> courseList = educationPaperTaskMapper.selectPaperCountBypaperId(paperId);
|
||||
|
||||
//将 courseInVos 转为 Map,便于通过 courseId 查询次数
|
||||
Map<String, Integer> courseCountMap = courseInVos.stream()
|
||||
.collect(Collectors.toMap(CourseInVo::getCourseId, CourseInVo::getCounts, (a, b) -> b));
|
||||
|
||||
//校验当前试卷的每门课程是否超过授权限制
|
||||
for (CourseInVo course : courseList) {
|
||||
String courseId = course.getCourseId();
|
||||
if (!authCourseIds.contains(courseId)) continue;
|
||||
|
||||
String courseName = course.getCourseName();
|
||||
Integer currentCount = courseCountMap.getOrDefault(courseId, 0);
|
||||
Integer authCount = authMap.getOrDefault(courseId, 0);
|
||||
|
||||
if (currentCount > authCount) {
|
||||
int over = currentCount - authCount;
|
||||
throw new MonitorSpecialtyException("课程: " + courseName + " 正在考试数量(" + currentCount + ") 授权数量(" + authCount + "),超出:" + over);
|
||||
}
|
||||
}
|
||||
// 分类授权:哪些是专业,哪些是课程
|
||||
Set<String> authSpecialtyIds = new HashSet<>();
|
||||
Set<String> authCourseIds = new HashSet<>();
|
||||
for (TentSpecialy t : tentSpecialies) {
|
||||
String specialtyId = t.getSpecialtyId();
|
||||
String parentId = idToParentMap.get(specialtyId);
|
||||
if (parentId == null || "0".equals(parentId)) {
|
||||
authSpecialtyIds.add(specialtyId); // 是专业
|
||||
} else {
|
||||
authCourseIds.add(specialtyId); // 是课程
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(stuMonitorPaperVo.getPaperId())){
|
||||
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperVo.getPaperId());
|
||||
String counts = educationPaper.getCounts();
|
||||
|
||||
int count = 0;
|
||||
// 只有授权了“专业”,才去查 taskInVo 并校验
|
||||
if (!authSpecialtyIds.isEmpty()) {
|
||||
//查询 该试卷任务 设计的 专业
|
||||
List<SpecialtyVo> taskInVo = educationPaperTaskMapper.selectTaskCounts(stuMonitorPaperVo.getTaskId(), loginTenantId);
|
||||
|
||||
try {
|
||||
count = Integer.parseInt(counts);
|
||||
} catch (NumberFormatException | NullPointerException e) {
|
||||
count = 0; // 默认从 0 开始
|
||||
}
|
||||
count += 1;
|
||||
educationPaper.setCounts(String.valueOf(count));
|
||||
educationPaperMapper.updateById(educationPaper);
|
||||
info.setPaperNum(educationPaper.getNum());
|
||||
for (SpecialtyVo specialtyVo : taskInVo) {
|
||||
String specialtyId = specialtyVo.getSpecialtyId();
|
||||
if (!authSpecialtyIds.contains(specialtyId)) continue;
|
||||
|
||||
String specialtyName = specialtyVo.getSpecialtyName();
|
||||
Integer currentCount = specialtyVo.getCounts();
|
||||
Integer authCount = authMap.getOrDefault(specialtyId, 0);
|
||||
|
||||
if (currentCount > authCount) {
|
||||
int over = currentCount - authCount;
|
||||
throw new MonitorSpecialtyException("专业: " + specialtyName + " 正在考试数量(" + currentCount + ") 授权数量(" + authCount + "),超出:" + over);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info.setExamStatus("1");
|
||||
// 只有授权了“课程”,才去查 courseInVos 并校验
|
||||
if (!authCourseIds.isEmpty()) {
|
||||
//查询所有正在考试的 试卷id
|
||||
List<String> allInPaperIds = educationPaperMapper.selectSpecilayCounts(loginTenantId);
|
||||
// 所有正在考试的试卷中授权课程的统计信息
|
||||
List<CourseInVo> courseInVos = educationPaperTaskMapper.selectPaperCounts(allInPaperIds, loginTenantId);
|
||||
|
||||
info.setIp(stuMonitorPaperVo.getIp());
|
||||
//获取当前学生正在考试的试卷 ID
|
||||
String paperId = stuMonitorPaperVo.getPaperId();
|
||||
|
||||
if (info.getRemainingTime()==null){
|
||||
stringRedisTemplate.opsForValue().set("userCache:"+stuMonitorPaperVo.getTaskId()+":"+stuMonitorPaperVo.getStuId(), JsonUtils.toJsonString(info));
|
||||
monitorMapper.updateById(info);
|
||||
return 24 * 60 * 60L; // (1天)
|
||||
}else {
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(stuMonitorPaperVo.getTaskId());
|
||||
//测评时长
|
||||
Time examTime = educationPaperParam.getExamTime();
|
||||
//查询该试卷涉及的所有课程(课程ID + 名称)
|
||||
List<CourseInVo> courseList = educationPaperTaskMapper.selectPaperCountBypaperId(paperId);
|
||||
|
||||
//判断是否开启测评时长限制
|
||||
//开启测评时长限制 开启场次 判断场次时间 ,,,,没开启测评时长限制 开启场次 -判断场次时间
|
||||
if ("0".equals(educationPaperParam.getIsSession())){
|
||||
//获得场次开始时间, 结束时间 判断是否在 时间范围内
|
||||
//将 courseInVos 转为 Map,便于通过 courseId 查询次数
|
||||
Map<String, Integer> courseCountMap = courseInVos.stream()
|
||||
.collect(Collectors.toMap(CourseInVo::getCourseId, CourseInVo::getCounts, (a, b) -> b));
|
||||
|
||||
EducationPaperPerson educationPaperPerson = educationPaperPersonMapper.selectByTaskIdAndPersonId(stuMonitorPaperVo.getTaskId(), stuMonitorPaperVo.getStuId());
|
||||
EducationPaperSession educationPaperSession = educationPaperSessionMapper.selectEducationPaperSessionBySessionId(educationPaperPerson.getSessionId());
|
||||
//校验当前试卷的每门课程是否超过授权限制
|
||||
for (CourseInVo course : courseList) {
|
||||
String courseId = course.getCourseId();
|
||||
if (!authCourseIds.contains(courseId)) continue;
|
||||
|
||||
if (educationPaperSession == null) {
|
||||
throw new MonitorSpecialtyException("未分配考场,请练习教师!");
|
||||
}
|
||||
//结束时间
|
||||
Date endTime = educationPaperSession.getEndTime();
|
||||
//开始时间
|
||||
Date startTime = educationPaperSession.getStartTime();
|
||||
//开始考试前分钟,允许入场
|
||||
String allowEntry = educationPaperSession.getAllowEntry();
|
||||
//开始考试后分钟,禁止入场
|
||||
String endAllowEntry = educationPaperSession.getEndAllowEntry();
|
||||
String courseName = course.getCourseName();
|
||||
Integer currentCount = courseCountMap.getOrDefault(courseId, 0);
|
||||
Integer authCount = authMap.getOrDefault(courseId, 0);
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime start = DateUtil.toLocalDateTime(startTime);
|
||||
LocalDateTime end = DateUtil.toLocalDateTime(endTime);
|
||||
|
||||
// 考试开始前允许入场时间(分钟)
|
||||
int allowEntryMin = Integer.parseInt(allowEntry);
|
||||
|
||||
// 考试开始后允许入场时间(分钟)
|
||||
int endAllowEntryMin = Integer.parseInt(endAllowEntry);
|
||||
|
||||
// 入场允许范围: [start-allowEntryMin , end + endAllowEntryMin]
|
||||
LocalDateTime entryStart = start.minusMinutes(allowEntryMin);
|
||||
LocalDateTime entryEnd = end.plusMinutes(endAllowEntryMin);
|
||||
//包含边界值
|
||||
boolean isWithinEntryTime = !now.isBefore(entryStart) && !now.isAfter(entryEnd);
|
||||
System.out.println("是否在允许入场时间段内:" + isWithinEntryTime);
|
||||
|
||||
if (isWithinEntryTime){
|
||||
// 1. 计算剩余时间(秒)
|
||||
long remainingSeconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), DateUtil.toLocalDateTime(endTime));
|
||||
remainingSeconds = Math.max(remainingSeconds, 0); // 防止负数
|
||||
|
||||
// 2. 获取测评时长(examTime 是 java.sql.Time)并转换为秒
|
||||
long examDurationSeconds = examTime.toLocalTime().toSecondOfDay(); // 将 HH:mm:ss 转为秒数
|
||||
|
||||
// 3. 规则判断:如果 remainingSeconds > examTime,则限制最大值为 examTime
|
||||
long finalRemaining = Math.min(remainingSeconds, examDurationSeconds);
|
||||
|
||||
// 4. 设置和返回
|
||||
info.setRemainingTime(finalRemaining);
|
||||
|
||||
// 判分后更新记录
|
||||
monitorMapper.updateById(info);
|
||||
return finalRemaining;
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//开启测评时长限制 没开启场次 -直接返回测评时长
|
||||
|
||||
if ("1".equals(educationPaperParam.getIsSession())&&"0".equals(educationPaperParam.getIsTime())){
|
||||
|
||||
info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
stringRedisTemplate.opsForValue().set("userCache:"+stuMonitorPaperVo.getTaskId()+":"+stuMonitorPaperVo.getStuId(), JsonUtils.toJsonString(info));
|
||||
monitorMapper.updateById(info);
|
||||
|
||||
return (long) examTime.toLocalTime().toSecondOfDay();
|
||||
|
||||
}
|
||||
|
||||
return 0L;
|
||||
if (currentCount > authCount) {
|
||||
int over = currentCount - authCount;
|
||||
throw new MonitorSpecialtyException("课程: " + courseName + " 正在考试数量(" + currentCount + ") 授权数量(" + authCount + "),超出:" + over);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateStuMonitor(StuMonitorQuVo stuMonitorQuVo) {
|
||||
String key = "userCache:"+stuMonitorQuVo.getTaskId()+":" + stuMonitorQuVo.getStuId();
|
||||
String keychoice = "keychoice:"+stuMonitorQuVo.getTaskId()+":" + stuMonitorQuVo.getStuId();
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
||||
if (StringUtils.isNotBlank(stuMonitorPaperVo.getPaperId())) {
|
||||
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperVo.getPaperId());
|
||||
String counts = educationPaper.getCounts();
|
||||
|
||||
int count = 0;
|
||||
|
||||
|
||||
if (info != null) {
|
||||
if (!("1".equals(info.getExamStatus()))){
|
||||
return false;
|
||||
}
|
||||
stringRedisTemplate.opsForValue().set(keychoice, JsonUtils.toJsonString(stuMonitorQuVo));
|
||||
// 更新缓存
|
||||
// redisTemplate.opsForValue().set(key, info);
|
||||
// monitorMapper.updateById(info);
|
||||
}
|
||||
return true;
|
||||
|
||||
try {
|
||||
count = Integer.parseInt(counts);
|
||||
} catch (NumberFormatException | NullPointerException e) {
|
||||
count = 0; // 默认从 0 开始
|
||||
}
|
||||
count += 1;
|
||||
educationPaper.setCounts(String.valueOf(count));
|
||||
educationPaperMapper.updateById(educationPaper);
|
||||
info.setPaperNum(educationPaper.getNum());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStuMonitor(StuMonitorPaperEndVo stuMonitorPaperEndVo) {
|
||||
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperEndVo.getPaperId());
|
||||
String taskId = educationPaper.getTaskId();
|
||||
String key = "userCache:" + taskId + ":" + stuMonitorPaperEndVo.getStuId();
|
||||
double score =educationPaperMapper.selctStuScoreByStuIdAndPaperId(stuMonitorPaperEndVo.getStuId(),stuMonitorPaperEndVo.getPaperId());
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
||||
info.setRemainingTime(0L);
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId);
|
||||
EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId);
|
||||
if ("1".equals(educationPaperParam.getSaveGrades())){
|
||||
info.setScore(String.valueOf(score));
|
||||
}else {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(info.getMonitorId());
|
||||
info.setScore(String.valueOf(score));
|
||||
if (StringUtils.isNotBlank(monitorDO.getScore())) {
|
||||
try {
|
||||
double oldScore = Double.parseDouble(monitorDO.getScore());
|
||||
if (score > oldScore) {
|
||||
info.setScore(String.valueOf(score));
|
||||
} else {
|
||||
info.setScore(monitorDO.getScore()); // 保留旧成绩
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果旧分数格式错误,则直接设置新分数
|
||||
info.setScore(String.valueOf(score));
|
||||
}
|
||||
} else {
|
||||
// 如果没有旧成绩,则直接设置
|
||||
info.setScore(String.valueOf(score));
|
||||
}
|
||||
info.setExamStatus("1");
|
||||
|
||||
info.setIp(stuMonitorPaperVo.getIp());
|
||||
|
||||
if (info.getRemainingTime() == null) {
|
||||
stringRedisTemplate.opsForValue().set("userCache:" + stuMonitorPaperVo.getTaskId() + ":" + stuMonitorPaperVo.getStuId(), JsonUtils.toJsonString(info));
|
||||
monitorMapper.updateById(info);
|
||||
return 24 * 60 * 60L; // (1天)
|
||||
} else {
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(stuMonitorPaperVo.getTaskId());
|
||||
//测评时长
|
||||
Time examTime = educationPaperParam.getExamTime();
|
||||
|
||||
//判断是否开启测评时长限制
|
||||
//开启测评时长限制 开启场次 判断场次时间 ,,,,没开启测评时长限制 开启场次 -判断场次时间
|
||||
if ("0".equals(educationPaperParam.getIsSession())) {
|
||||
//获得场次开始时间, 结束时间 判断是否在 时间范围内
|
||||
|
||||
EducationPaperPerson educationPaperPerson = educationPaperPersonMapper.selectByTaskIdAndPersonId(stuMonitorPaperVo.getTaskId(), stuMonitorPaperVo.getStuId());
|
||||
EducationPaperSession educationPaperSession = educationPaperSessionMapper.selectEducationPaperSessionBySessionId(educationPaperPerson.getSessionId());
|
||||
|
||||
if (educationPaperSession == null) {
|
||||
throw new MonitorSpecialtyException("未分配考场,请练习教师!");
|
||||
}
|
||||
//考试下的任务 结束改为 结束 其他为待考
|
||||
if ("1".equals(educationPaperTask.getTaskType())){
|
||||
info.setExamStatus("2");
|
||||
redisTemplate.delete(key);
|
||||
//结束时间
|
||||
Date endTime = educationPaperSession.getEndTime();
|
||||
//开始时间
|
||||
Date startTime = educationPaperSession.getStartTime();
|
||||
//开始考试前分钟,允许入场
|
||||
String allowEntry = educationPaperSession.getAllowEntry();
|
||||
//开始考试后分钟,禁止入场
|
||||
String endAllowEntry = educationPaperSession.getEndAllowEntry();
|
||||
|
||||
}else {
|
||||
info.setExamStatus("0");
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info));
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime start = DateUtil.toLocalDateTime(startTime);
|
||||
LocalDateTime end = DateUtil.toLocalDateTime(endTime);
|
||||
|
||||
// 考试开始前允许入场时间(分钟)
|
||||
int allowEntryMin = Integer.parseInt(allowEntry);
|
||||
|
||||
// 考试开始后允许入场时间(分钟)
|
||||
int endAllowEntryMin = Integer.parseInt(endAllowEntry);
|
||||
|
||||
// 入场允许范围: [start-allowEntryMin , end + endAllowEntryMin]
|
||||
LocalDateTime entryStart = start.minusMinutes(allowEntryMin);
|
||||
LocalDateTime entryEnd = end.plusMinutes(endAllowEntryMin);
|
||||
//包含边界值
|
||||
boolean isWithinEntryTime = !now.isBefore(entryStart) && !now.isAfter(entryEnd);
|
||||
System.out.println("是否在允许入场时间段内:" + isWithinEntryTime);
|
||||
|
||||
if (isWithinEntryTime) {
|
||||
// 1. 计算剩余时间(秒)
|
||||
long remainingSeconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), DateUtil.toLocalDateTime(endTime));
|
||||
remainingSeconds = Math.max(remainingSeconds, 0); // 防止负数
|
||||
|
||||
// 2. 获取测评时长(examTime 是 java.sql.Time)并转换为秒
|
||||
long examDurationSeconds = examTime.toLocalTime().toSecondOfDay(); // 将 HH:mm:ss 转为秒数
|
||||
|
||||
// 3. 规则判断:如果 remainingSeconds > examTime,则限制最大值为 examTime
|
||||
long finalRemaining = Math.min(remainingSeconds, examDurationSeconds);
|
||||
|
||||
// 4. 设置和返回
|
||||
info.setRemainingTime(finalRemaining);
|
||||
|
||||
// 判分后更新记录
|
||||
monitorMapper.updateById(info);
|
||||
return finalRemaining;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//开启测评时长限制 没开启场次 -直接返回测评时长
|
||||
|
||||
if ("1".equals(educationPaperParam.getIsSession()) && "0".equals(educationPaperParam.getIsTime())) {
|
||||
|
||||
info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
stringRedisTemplate.opsForValue().set("userCache:" + stuMonitorPaperVo.getTaskId() + ":" + stuMonitorPaperVo.getStuId(), JsonUtils.toJsonString(info));
|
||||
monitorMapper.updateById(info);
|
||||
|
||||
return (long) examTime.toLocalTime().toSecondOfDay();
|
||||
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EducationPaperTask> getPaperTaskList(String id) {
|
||||
return educationPaperTaskMapper.selectEducationPaperTaskByTaskType(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateStuMonitor(StuMonitorQuVo stuMonitorQuVo) {
|
||||
String key = "userCache:" + stuMonitorQuVo.getTaskId() + ":" + stuMonitorQuVo.getStuId();
|
||||
String keychoice = "keychoice:" + stuMonitorQuVo.getTaskId() + ":" + stuMonitorQuVo.getStuId();
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||
|
||||
|
||||
if (info != null) {
|
||||
if (!("1".equals(info.getExamStatus()))) {
|
||||
return false;
|
||||
}
|
||||
stringRedisTemplate.opsForValue().set(keychoice, JsonUtils.toJsonString(stuMonitorQuVo));
|
||||
// 更新缓存
|
||||
// redisTemplate.opsForValue().set(key, info);
|
||||
// monitorMapper.updateById(info);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStuMonitor(StuMonitorPaperEndVo stuMonitorPaperEndVo) {
|
||||
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperEndVo.getPaperId());
|
||||
String taskId = educationPaper.getTaskId();
|
||||
String key = "userCache:" + taskId + ":" + stuMonitorPaperEndVo.getStuId();
|
||||
double score = educationPaperMapper.selctStuScoreByStuIdAndPaperId(stuMonitorPaperEndVo.getStuId(), stuMonitorPaperEndVo.getPaperId());
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||
info.setRemainingTime(0L);
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId);
|
||||
EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId);
|
||||
if ("1".equals(educationPaperParam.getSaveGrades())) {
|
||||
info.setScore(String.valueOf(score));
|
||||
} else {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(info.getMonitorId());
|
||||
info.setScore(String.valueOf(score));
|
||||
if (StringUtils.isNotBlank(monitorDO.getScore())) {
|
||||
try {
|
||||
double oldScore = Double.parseDouble(monitorDO.getScore());
|
||||
if (score > oldScore) {
|
||||
info.setScore(String.valueOf(score));
|
||||
} else {
|
||||
info.setScore(monitorDO.getScore()); // 保留旧成绩
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果旧分数格式错误,则直接设置新分数
|
||||
info.setScore(String.valueOf(score));
|
||||
}
|
||||
} else {
|
||||
// 如果没有旧成绩,则直接设置
|
||||
info.setScore(String.valueOf(score));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//考试下的任务 结束改为 结束 其他为待考
|
||||
if ("1".equals(educationPaperTask.getTaskType())) {
|
||||
info.setExamStatus("2");
|
||||
redisTemplate.delete(key);
|
||||
|
||||
} else {
|
||||
info.setExamStatus("0");
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo) {
|
||||
String status = stuMonitorStatusVo.getStatus();
|
||||
List<String> monitorIds = stuMonitorStatusVo.getMonitorIds();
|
||||
if ("1".equals(status)||"0".equals(status)){
|
||||
//新增或更新
|
||||
for (String monitorId : monitorIds) {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(monitorId);
|
||||
String taskId = monitorDO.getTaskId();
|
||||
String stuId = monitorDO.getStuId();
|
||||
String key = "userCache:" + taskId+":" +stuId;
|
||||
monitorDO.setExamStatus(status);
|
||||
monitorMapper.updateById(monitorDO);
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId);
|
||||
Time examTime = educationPaperParam.getExamTime();
|
||||
monitorMapper.updateById(info);
|
||||
|
||||
if (info==null){
|
||||
MonitorDO monitorDO1 = monitorMapper.selectOne(
|
||||
new QueryWrapper<MonitorDO>()
|
||||
.eq("stu_id", stuId)
|
||||
.eq("task_id", taskId)
|
||||
);
|
||||
PersonRepDto personRepDto = educationPaperPersonMapper.selectUserById(stuId);
|
||||
String name= educationPaperTaskMapper.selectEducationPaperTaskNameByid(taskId);
|
||||
EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId);
|
||||
monitorDO1.setScore("0");
|
||||
monitorDO1.setTaskId(taskId);
|
||||
monitorDO1.setTaskType(educationPaperTask.getTaskType());
|
||||
monitorDO1.setExamStatus(status);
|
||||
monitorDO1.setPaperNum("");
|
||||
monitorDO1.setIp("");
|
||||
monitorDO1.setStuId(stuId);
|
||||
monitorDO1.setUsername(personRepDto.getUsername());
|
||||
monitorDO1.setNickname(personRepDto.getNickname());
|
||||
}
|
||||
|
||||
//如果开启了 时长限制 或者考场
|
||||
if ("0".equals(educationPaperParam.getIsTime())||"0".equals(educationPaperParam.getIsSession())){
|
||||
monitorDO1.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
}
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO1));
|
||||
monitorMapper.updateById(monitorDO1);
|
||||
}else {
|
||||
//如果开启了 时长限制 或者考场
|
||||
if ("0".equals(educationPaperParam.getIsTime())||"0".equals(educationPaperParam.getIsSession())){
|
||||
info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
}
|
||||
info.setScore("0");
|
||||
info.setPaperNum("");
|
||||
info.setIp("");
|
||||
info.setExamStatus(status);
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info));
|
||||
}
|
||||
@Override
|
||||
public List<EducationPaperTask> getPaperTaskList(String id) {
|
||||
return educationPaperTaskMapper.selectEducationPaperTaskByTaskType(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo) {
|
||||
String status = stuMonitorStatusVo.getStatus();
|
||||
List<String> monitorIds = stuMonitorStatusVo.getMonitorIds();
|
||||
if ("1".equals(status) || "0".equals(status)) {
|
||||
//新增或更新
|
||||
for (String monitorId : monitorIds) {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(monitorId);
|
||||
String taskId = monitorDO.getTaskId();
|
||||
String stuId = monitorDO.getStuId();
|
||||
String key = "userCache:" + taskId + ":" + stuId;
|
||||
monitorDO.setExamStatus(status);
|
||||
monitorMapper.updateById(monitorDO);
|
||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId);
|
||||
Time examTime = educationPaperParam.getExamTime();
|
||||
|
||||
if (info == null) {
|
||||
MonitorDO monitorDO1 = monitorMapper.selectOne(
|
||||
new QueryWrapper<MonitorDO>()
|
||||
.eq("stu_id", stuId)
|
||||
.eq("task_id", taskId)
|
||||
);
|
||||
PersonRepDto personRepDto = educationPaperPersonMapper.selectUserById(stuId);
|
||||
String name = educationPaperTaskMapper.selectEducationPaperTaskNameByid(taskId);
|
||||
EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId);
|
||||
monitorDO1.setScore("0");
|
||||
monitorDO1.setTaskId(taskId);
|
||||
monitorDO1.setTaskType(educationPaperTask.getTaskType());
|
||||
monitorDO1.setExamStatus(status);
|
||||
monitorDO1.setPaperNum("");
|
||||
monitorDO1.setIp("");
|
||||
monitorDO1.setStuId(stuId);
|
||||
monitorDO1.setUsername(personRepDto.getUsername());
|
||||
monitorDO1.setNickname(personRepDto.getNickname());
|
||||
|
||||
|
||||
}
|
||||
|
||||
//如果开启了 时长限制 或者考场
|
||||
if ("0".equals(educationPaperParam.getIsTime()) || "0".equals(educationPaperParam.getIsSession())) {
|
||||
monitorDO1.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
}
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO1));
|
||||
monitorMapper.updateById(monitorDO1);
|
||||
} else {
|
||||
//如果开启了 时长限制 或者考场
|
||||
if ("0".equals(educationPaperParam.getIsTime()) || "0".equals(educationPaperParam.getIsSession())) {
|
||||
info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
|
||||
}
|
||||
info.setScore("0");
|
||||
info.setPaperNum("");
|
||||
info.setIp("");
|
||||
info.setExamStatus(status);
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info));
|
||||
}
|
||||
|
||||
if ("2".equals(status)){
|
||||
//删除
|
||||
for (String monitorId : monitorIds) {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(monitorId);
|
||||
String taskId = monitorDO.getTaskId();
|
||||
String stuId = monitorDO.getStuId();
|
||||
String key = "userCache:" + taskId+":" +stuId;
|
||||
monitorDO.setRemainingTime(0L);
|
||||
if ("0".equals(monitorDO.getTaskType())){
|
||||
monitorDO.setExamStatus("0");
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO));
|
||||
|
||||
}else {
|
||||
monitorDO.setExamStatus(status);
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
monitorMapper.updateById(monitorDO);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
public List<TentSpecialy> filterSpecialtyList(List<TentSpecialy> inputList) {
|
||||
if (inputList == null || inputList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
|
||||
if ("2".equals(status)) {
|
||||
//删除
|
||||
for (String monitorId : monitorIds) {
|
||||
MonitorDO monitorDO = monitorMapper.selectById(monitorId);
|
||||
String taskId = monitorDO.getTaskId();
|
||||
String stuId = monitorDO.getStuId();
|
||||
String key = "userCache:" + taskId + ":" + stuId;
|
||||
monitorDO.setRemainingTime(0L);
|
||||
if ("0".equals(monitorDO.getTaskType())) {
|
||||
monitorDO.setExamStatus("0");
|
||||
stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO));
|
||||
|
||||
} else {
|
||||
monitorDO.setExamStatus(status);
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
|
||||
// 构建传入列表中的 specialtyId Set(这些是传进来的 ID)
|
||||
Set<String> inputSpecialtyIds = inputList.stream()
|
||||
.map(TentSpecialy::getSpecialtyId)
|
||||
.collect(Collectors.toSet());
|
||||
monitorMapper.updateById(monitorDO);
|
||||
|
||||
// 查询所有课程 -> 专业 的关系
|
||||
List<SpecialtyRelation> allRelations = examSpecialtyMapper.selectAllSpecialtyRelations();
|
||||
|
||||
// 构建课程ID -> 父专业ID 的映射
|
||||
Map<String, String> courseToParentMap = allRelations.stream()
|
||||
.filter(r -> r.getParentId() != null)
|
||||
.collect(Collectors.toMap(SpecialtyRelation::getSpId, SpecialtyRelation::getParentId));
|
||||
|
||||
// 开始过滤:只保留以下情况之一
|
||||
return inputList.stream()
|
||||
.filter(item -> {
|
||||
String specialtyId = item.getSpecialtyId();
|
||||
String parentId = courseToParentMap.get(specialtyId);
|
||||
// 1. 如果这个是专业(它不是任何课程的 sp_id) → 保留
|
||||
if (parentId == null) return true;
|
||||
// 2. 如果它是课程,但父级不在输入列表中 → 保留
|
||||
return !inputSpecialtyIds.contains(parentId);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public List<TentSpecialy> filterSpecialtyList(List<TentSpecialy> inputList) {
|
||||
if (inputList == null || inputList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 构建传入列表中的 specialtyId Set(这些是传进来的 ID)
|
||||
Set<String> inputSpecialtyIds = inputList.stream()
|
||||
.map(TentSpecialy::getSpecialtyId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 查询所有课程 -> 专业 的关系
|
||||
List<SpecialtyRelation> allRelations = examSpecialtyMapper.selectAllSpecialtyRelations();
|
||||
|
||||
// 构建课程ID -> 父专业ID 的映射
|
||||
Map<String, String> courseToParentMap = allRelations.stream()
|
||||
.filter(r -> r.getParentId() != null)
|
||||
.collect(Collectors.toMap(SpecialtyRelation::getSpId, SpecialtyRelation::getParentId));
|
||||
|
||||
// 开始过滤:只保留以下情况之一
|
||||
return inputList.stream()
|
||||
.filter(item -> {
|
||||
String specialtyId = item.getSpecialtyId();
|
||||
String parentId = courseToParentMap.get(specialtyId);
|
||||
// 1. 如果这个是专业(它不是任何课程的 sp_id) → 保留
|
||||
if (parentId == null) return true;
|
||||
// 2. 如果它是课程,但父级不在输入列表中 → 保留
|
||||
return !inputSpecialtyIds.contains(parentId);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -126,7 +126,7 @@
|
||||
<select id="selectExamSpecialtyBySpNameOne" parameterType="String" resultType="ExamSpecialty">
|
||||
SELECT *
|
||||
from exam_specialty
|
||||
where sp_name = #{name}
|
||||
where sp_name = #{name} and deleted = 0 and status = 0
|
||||
</select>
|
||||
|
||||
<select id="selectExamSpecialtyBySpName" parameterType="String"
|
||||
|
Reference in New Issue
Block a user