【修改】 考点服务器绑定专业sql增加查询条件

This commit is contained in:
dlaren
2025-08-11 17:17:49 +08:00
parent c07e8910d2
commit 28c75d52c5
2 changed files with 390 additions and 396 deletions

View File

@@ -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());
}
}

View File

@@ -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"