【新增】专业/课程 点位判断
【修改】模板库复制修改试卷编号
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
package pc.exam.pp.module.exam.controller.admin.exception;
|
||||||
|
|
||||||
|
public class MonitorSpecialtyException extends RuntimeException {
|
||||||
|
|
||||||
|
public MonitorSpecialtyException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -88,7 +88,12 @@ public class MonitorController {
|
|||||||
@PostMapping("/stuMonitor")
|
@PostMapping("/stuMonitor")
|
||||||
@Operation(summary = "学生端进入考试返回值")
|
@Operation(summary = "学生端进入考试返回值")
|
||||||
public CommonResult getStuMonitor(@Valid @RequestBody StuMonitorPaperVo stuMonitorPaperVo) {
|
public CommonResult getStuMonitor(@Valid @RequestBody StuMonitorPaperVo stuMonitorPaperVo) {
|
||||||
long stuMonitor = monitorService.getStuMonitor(stuMonitorPaperVo);
|
long stuMonitor = 0;
|
||||||
|
try {
|
||||||
|
stuMonitor = monitorService.getStuMonitor(stuMonitorPaperVo);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
return error(1-001-606-001,e.getMessage());
|
||||||
|
}
|
||||||
if (stuMonitor>0)
|
if (stuMonitor>0)
|
||||||
{
|
{
|
||||||
return success(stuMonitor);
|
return success(stuMonitor);
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package pc.exam.pp.module.exam.dal.dataobject.monitor;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import pc.exam.pp.framework.tenant.core.db.TenantBaseDO;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@TableName(value = "exam_tenant_specialty")
|
||||||
|
@Accessors(chain = true)
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class TentSpecialy extends TenantBaseDO {
|
||||||
|
private String id;
|
||||||
|
private String specialtyId;
|
||||||
|
private String points;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private String name;
|
||||||
|
}
|
||||||
@@ -8,7 +8,9 @@ import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
|||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import pc.exam.pp.module.exam.controller.admin.monitor.vo.MonitorPageReqVO;
|
import pc.exam.pp.module.exam.controller.admin.monitor.vo.MonitorPageReqVO;
|
||||||
import pc.exam.pp.module.exam.controller.admin.paper.vo.DeleteRequestVo;
|
import pc.exam.pp.module.exam.controller.admin.paper.vo.DeleteRequestVo;
|
||||||
|
import pc.exam.pp.module.exam.dal.dataobject.EducationPaper;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.monitor.MonitorDO;
|
import pc.exam.pp.module.exam.dal.dataobject.monitor.MonitorDO;
|
||||||
|
import pc.exam.pp.module.exam.dal.dataobject.monitor.TentSpecialy;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -58,4 +60,15 @@ return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDO>()
|
|||||||
List<String> selectByStuIdAndTaskId(Long stuId);
|
List<String> selectByStuIdAndTaskId(Long stuId);
|
||||||
|
|
||||||
List<String> selectStuIdByTaskId(String taskId);
|
List<String> selectStuIdByTaskId(String taskId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找授权点位
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<TentSpecialy> selectTent(Long loginTenantId);
|
||||||
|
|
||||||
|
void deleteByTaskIds(@Param("taskIds") String[] taskIds);
|
||||||
|
|
||||||
|
void deleteByTaskId(String taskId);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
import pc.exam.pp.framework.common.pojo.PageResult;
|
import pc.exam.pp.framework.common.pojo.PageResult;
|
||||||
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import pc.exam.pp.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import pc.exam.pp.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import pc.exam.pp.framework.tenant.core.aop.TenantIgnore;
|
||||||
import pc.exam.pp.module.exam.controller.admin.paper.dto.EducationPaperStuDto;
|
import pc.exam.pp.module.exam.controller.admin.paper.dto.EducationPaperStuDto;
|
||||||
import pc.exam.pp.module.exam.controller.admin.paper.dto.PaperIdAndNum;
|
import pc.exam.pp.module.exam.controller.admin.paper.dto.PaperIdAndNum;
|
||||||
import pc.exam.pp.module.exam.controller.admin.paper.vo.PaperPageVo;
|
import pc.exam.pp.module.exam.controller.admin.paper.vo.PaperPageVo;
|
||||||
@@ -177,6 +178,9 @@ public interface EducationPaperMapper extends BaseMapperX<EducationPaper>
|
|||||||
|
|
||||||
List<String> selectTaskNumByids(@Param("cannotDeleteTaskIds")List<String> cannotDeleteTaskIds);
|
List<String> selectTaskNumByids(@Param("cannotDeleteTaskIds")List<String> cannotDeleteTaskIds);
|
||||||
|
|
||||||
|
// //查询所有正在考试的 试卷id
|
||||||
|
@TenantIgnore
|
||||||
|
List<String> selectSpecilayCounts(Long loginTenantId);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import pc.exam.pp.module.exam.controller.admin.paper.vo.PaperTaskPageVo;
|
|||||||
import pc.exam.pp.module.exam.dal.dataobject.ExamPaperKnowledgePoints;
|
import pc.exam.pp.module.exam.dal.dataobject.ExamPaperKnowledgePoints;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.EducationPaperTask;
|
import pc.exam.pp.module.exam.dal.dataobject.EducationPaperTask;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.ExamPaperKnowledgePoints;
|
import pc.exam.pp.module.exam.dal.dataobject.ExamPaperKnowledgePoints;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.CourseInVo;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.SpecialtyVo;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.TaskInVo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 试卷任务Mapper接口
|
* 试卷任务Mapper接口
|
||||||
@@ -146,4 +149,13 @@ public interface EducationPaperTaskMapper extends BaseMapperX<EducationPaperTask
|
|||||||
*/
|
*/
|
||||||
String selectPaperQuByPaperId(String taskId);
|
String selectPaperQuByPaperId(String taskId);
|
||||||
|
|
||||||
|
List<SpecialtyVo> selectTaskCounts(@Param("taskId")String taskId
|
||||||
|
,@Param("loginTenantId") long loginTenantId);
|
||||||
|
|
||||||
|
//所有正在考试的试卷中授权课程的统计信息
|
||||||
|
List<CourseInVo> selectPaperCounts(@Param("allInPaperIds") List<String> allInPaperIds
|
||||||
|
,@Param("loginTenantId") long loginTenantId);
|
||||||
|
//查询该试卷涉及的所有课程(课程ID + 名称)
|
||||||
|
List<CourseInVo> selectPaperCountBypaperId(@Param("paperId") String paperId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
package pc.exam.pp.module.exam.dal.mysql.specialty;
|
package pc.exam.pp.module.exam.dal.mysql.specialty;
|
||||||
|
import org.apache.ibatis.annotations.MapKey;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
import pc.exam.pp.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import pc.exam.pp.module.exam.controller.admin.specialty.vo.SpecialtListReqVo;
|
import pc.exam.pp.module.exam.controller.admin.specialty.vo.SpecialtListReqVo;
|
||||||
import pc.exam.pp.module.exam.controller.admin.specialty.vo.SpecialtyQueryVo;
|
import pc.exam.pp.module.exam.controller.admin.specialty.vo.SpecialtyQueryVo;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.knowledge.ExamKnowledgePoints;
|
import pc.exam.pp.module.exam.dal.dataobject.knowledge.ExamKnowledgePoints;
|
||||||
|
import pc.exam.pp.module.exam.dal.dataobject.monitor.TentSpecialy;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.specialty.ExamSpecialty;
|
import pc.exam.pp.module.exam.dal.dataobject.specialty.ExamSpecialty;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.IdParentPair;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.SpecialtyRelation;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,4 +119,12 @@ public interface ExamSpecialtyMapper extends BaseMapperX<ExamSpecialty>
|
|||||||
, @Param("chapteridDictText")String chapteridDictText
|
, @Param("chapteridDictText")String chapteridDictText
|
||||||
, @Param("pointNames") String pointNames);
|
, @Param("pointNames") String pointNames);
|
||||||
|
|
||||||
|
List<SpecialtyRelation> selectAllSpecialtyRelations(); // 返回 sp_id 和 parent_id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<IdParentPair> selectAllIdToParent(Long loginTenantId);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
PageResult<MonitorDO> getMonitorPage(MonitorPageReqVO pageReqVO);
|
PageResult<MonitorDO> getMonitorPage(MonitorPageReqVO pageReqVO);
|
||||||
//学生端进入考试返回值
|
//学生端进入考试返回值
|
||||||
long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo);
|
long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) throws RuntimeException;
|
||||||
//学生端考试过程传试题
|
//学生端考试过程传试题
|
||||||
Boolean updateStuMonitor(StuMonitorQuVo stuMonitorQuVo);
|
Boolean updateStuMonitor(StuMonitorQuVo stuMonitorQuVo);
|
||||||
//学生端结束考试返回值
|
//学生端结束考试返回值
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package pc.exam.pp.module.exam.service.monitor;
|
package pc.exam.pp.module.exam.service.monitor;
|
||||||
|
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
|
||||||
import com.alibaba.excel.util.StringUtils;
|
import com.alibaba.excel.util.StringUtils;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -11,32 +10,29 @@ import org.springframework.stereotype.Service;
|
|||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Date;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.function.Function;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import pc.exam.pp.framework.common.pojo.PageResult;
|
import pc.exam.pp.framework.common.pojo.PageResult;
|
||||||
import pc.exam.pp.framework.common.util.json.JsonUtils;
|
import pc.exam.pp.framework.common.util.json.JsonUtils;
|
||||||
import pc.exam.pp.framework.common.util.object.BeanUtils;
|
import pc.exam.pp.framework.common.util.object.BeanUtils;
|
||||||
|
|
||||||
|
import pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils;
|
||||||
|
import pc.exam.pp.module.exam.controller.admin.exception.MonitorSpecialtyException;
|
||||||
import pc.exam.pp.module.exam.controller.admin.monitor.vo.*;
|
import pc.exam.pp.module.exam.controller.admin.monitor.vo.*;
|
||||||
import pc.exam.pp.module.exam.controller.admin.paper.dto.PersonRepDto;
|
import pc.exam.pp.module.exam.controller.admin.paper.dto.PersonRepDto;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.*;
|
import pc.exam.pp.module.exam.dal.dataobject.*;
|
||||||
import pc.exam.pp.module.exam.dal.dataobject.monitor.MonitorDO;
|
import pc.exam.pp.module.exam.dal.dataobject.monitor.MonitorDO;
|
||||||
|
import pc.exam.pp.module.exam.dal.dataobject.monitor.TentSpecialy;
|
||||||
import pc.exam.pp.module.exam.dal.mysql.monitor.MonitorMapper;
|
import pc.exam.pp.module.exam.dal.mysql.monitor.MonitorMapper;
|
||||||
import pc.exam.pp.module.exam.dal.mysql.paper.*;
|
import pc.exam.pp.module.exam.dal.mysql.paper.*;
|
||||||
import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionMapper;
|
import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionMapper;
|
||||||
import pc.exam.pp.module.exam.utils.uuid.IdUtils;
|
import pc.exam.pp.module.exam.dal.mysql.specialty.ExamSpecialtyMapper;
|
||||||
|
import pc.exam.pp.module.exam.service.monitor.vo.*;
|
||||||
//import pc.exam.pp.module.infra.service.file.FileService;
|
//import pc.exam.pp.module.infra.service.file.FileService;
|
||||||
|
|
||||||
import static pc.exam.pp.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static pc.exam.pp.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
@@ -68,6 +64,11 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
private EducationPaperParamMapper educationPaperParamMapper;
|
private EducationPaperParamMapper educationPaperParamMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private EducationPaperSessionMapper educationPaperSessionMapper;
|
private EducationPaperSessionMapper educationPaperSessionMapper;
|
||||||
|
@Resource
|
||||||
|
private EducationPaperSchemeMapper educationPaperSchemeMapper;
|
||||||
|
@Resource
|
||||||
|
private ExamSpecialtyMapper examSpecialtyMapper;
|
||||||
|
|
||||||
|
|
||||||
// @Resource
|
// @Resource
|
||||||
// private FileService fileService;
|
// private FileService fileService;
|
||||||
@@ -113,12 +114,116 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
return monitorMapper.selectPage(pageReqVO);
|
return monitorMapper.selectPage(pageReqVO);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) {
|
public long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) throws RuntimeException {
|
||||||
String key = "userCache:"+stuMonitorPaperVo.getTaskId()+":" + stuMonitorPaperVo.getStuId();
|
String key = "userCache:"+stuMonitorPaperVo.getTaskId()+":" + stuMonitorPaperVo.getStuId();
|
||||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key),MonitorDO.class);
|
||||||
if (info==null){
|
if (info==null){
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
|
//获取属性 判断 专业/课程点位
|
||||||
|
Long loginTenantId = SecurityFrameworkUtils.getLoginTenantId();
|
||||||
|
|
||||||
|
if (!"1".equals(String.valueOf(loginTenantId))) {
|
||||||
|
// 查询授权课程/专业列表
|
||||||
|
List<TentSpecialy> tentSpecialyList = monitorMapper.selectTent(loginTenantId);
|
||||||
|
List<TentSpecialy> tentSpecialies = filterSpecialtyList(tentSpecialyList);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
// 查询 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())
|
||||||
|
));
|
||||||
|
|
||||||
|
// 分类授权:哪些是专业,哪些是课程
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(stuMonitorPaperVo.getPaperId())){
|
if (StringUtils.isNotBlank(stuMonitorPaperVo.getPaperId())){
|
||||||
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperVo.getPaperId());
|
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperVo.getPaperId());
|
||||||
String counts = educationPaper.getCounts();
|
String counts = educationPaper.getCounts();
|
||||||
@@ -216,7 +321,6 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
|
|
||||||
return (long) examTime.toLocalTime().toSecondOfDay();
|
return (long) examTime.toLocalTime().toSecondOfDay();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0L;
|
return 0L;
|
||||||
@@ -394,5 +498,38 @@ public class MonitorServiceImpl implements MonitorService {
|
|||||||
return true;
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package pc.exam.pp.module.exam.service.monitor.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class CourseInVo {
|
||||||
|
//试卷id
|
||||||
|
private String courseId;
|
||||||
|
|
||||||
|
private String courseName;
|
||||||
|
//个数
|
||||||
|
private Integer counts;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package pc.exam.pp.module.exam.service.monitor.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class IdParentPair {
|
||||||
|
private Long spId;
|
||||||
|
private Long parentId;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package pc.exam.pp.module.exam.service.monitor.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpecialtyRelation {
|
||||||
|
private String spId;
|
||||||
|
private String parentId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package pc.exam.pp.module.exam.service.monitor.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpecialtyVo {
|
||||||
|
|
||||||
|
//专业id
|
||||||
|
private String specialtyId;
|
||||||
|
|
||||||
|
private String specialtyName;
|
||||||
|
//个数
|
||||||
|
private Integer counts;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package pc.exam.pp.module.exam.service.monitor.vo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TaskInVo {
|
||||||
|
//试卷任务id
|
||||||
|
private String taskId;
|
||||||
|
|
||||||
|
//个数
|
||||||
|
private Integer counts;
|
||||||
|
}
|
||||||
@@ -215,6 +215,7 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
// 3. 执行删除操作
|
// 3. 执行删除操作
|
||||||
educationPaperTaskMapper.deleteEducationPaperTaskByTaskIds(
|
educationPaperTaskMapper.deleteEducationPaperTaskByTaskIds(
|
||||||
canDeleteTaskIds.toArray(new String[0]));
|
canDeleteTaskIds.toArray(new String[0]));
|
||||||
|
monitorMapper.deleteByTaskIds(canDeleteTaskIds.toArray(new String[0]));
|
||||||
if (!cannotDeleteTaskIds.isEmpty()){
|
if (!cannotDeleteTaskIds.isEmpty()){
|
||||||
List<String> taskNum= educationPaperMapper.selectTaskNumByids(cannotDeleteTaskIds);
|
List<String> taskNum= educationPaperMapper.selectTaskNumByids(cannotDeleteTaskIds);
|
||||||
return ("以下任务下有试卷:"+taskNum+",不能删除!");
|
return ("以下任务下有试卷:"+taskNum+",不能删除!");
|
||||||
@@ -233,6 +234,7 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int deleteEducationPaperTaskByTaskId(String taskId) {
|
public int deleteEducationPaperTaskByTaskId(String taskId) {
|
||||||
|
monitorMapper.deleteByTaskId(taskId);
|
||||||
return educationPaperTaskMapper.deleteEducationPaperTaskByTaskId(taskId);
|
return educationPaperTaskMapper.deleteEducationPaperTaskByTaskId(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +353,10 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
//获得 试卷试题
|
//获得 试卷试题
|
||||||
List<EducationPaperQu> educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(paperId);
|
List<EducationPaperQu> educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(paperId);
|
||||||
|
|
||||||
|
int number=educationPaperMapper.selectCountPaperList();
|
||||||
|
|
||||||
|
// 格式化为8位,不足前面补0
|
||||||
|
String formattedNumber = String.format("%08d", ++number);
|
||||||
String newpaperId = IdUtils.simpleUUID();
|
String newpaperId = IdUtils.simpleUUID();
|
||||||
|
|
||||||
//不为空,构建新试卷试题
|
//不为空,构建新试卷试题
|
||||||
@@ -361,14 +366,16 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
|
|
||||||
//插入数据库
|
//插入数据库
|
||||||
educationPaperQuMapper.insertEducationPaperQuList(educationPaperQus);
|
educationPaperQuMapper.insertEducationPaperQuList(educationPaperQus);
|
||||||
|
educationPaper.setCounts("0");
|
||||||
educationPaper.setPaperId(newpaperId);
|
educationPaper.setPaperId(newpaperId);
|
||||||
educationPaper.setTaskId(newtaskId);
|
educationPaper.setTaskId(newtaskId);
|
||||||
|
educationPaper.setNum(formattedNumber);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//构建新试卷
|
//构建新试卷
|
||||||
educationPaperMapper.insertEducationPaperList(educationPapers);
|
educationPaperMapper.insertEducationPaper(educationPaper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.contains("3")) {
|
if (options.contains("3")) {
|
||||||
@@ -404,6 +411,10 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
Map<String, String> paperIdMapping = new HashMap<>();
|
Map<String, String> paperIdMapping = new HashMap<>();
|
||||||
if (educationPapers!=null&&educationPapers.size()>0){
|
if (educationPapers!=null&&educationPapers.size()>0){
|
||||||
for (EducationPaper paper : educationPapers) {
|
for (EducationPaper paper : educationPapers) {
|
||||||
|
int number=educationPaperMapper.selectCountPaperList();
|
||||||
|
|
||||||
|
// 格式化为8位,不足前面补0
|
||||||
|
String formattedNumber = String.format("%08d", ++number);
|
||||||
String newPaperId = IdUtils.simpleUUID();
|
String newPaperId = IdUtils.simpleUUID();
|
||||||
paperIdMapping.put(paper.getPaperId(), newPaperId);
|
paperIdMapping.put(paper.getPaperId(), newPaperId);
|
||||||
|
|
||||||
@@ -411,7 +422,8 @@ public class EducationPaperTaskServiceImpl implements IEducationPaperTaskService
|
|||||||
List<EducationPaperQu> questions = educationPaperQuMapper.selectPaperQuListByPaperId(paper.getPaperId());
|
List<EducationPaperQu> questions = educationPaperQuMapper.selectPaperQuListByPaperId(paper.getPaperId());
|
||||||
questions.forEach(qu -> qu.setPaperId(newPaperId));
|
questions.forEach(qu -> qu.setPaperId(newPaperId));
|
||||||
educationPaperQuMapper.insertEducationPaperQuList(questions);
|
educationPaperQuMapper.insertEducationPaperQuList(questions);
|
||||||
|
paper.setNum(formattedNumber);
|
||||||
|
paper.setCounts("0");
|
||||||
paper.setPaperId(newPaperId);
|
paper.setPaperId(newPaperId);
|
||||||
paper.setTaskId(newtaskId);
|
paper.setTaskId(newtaskId);
|
||||||
educationPaperMapper.insertEducationPaper(paper);
|
educationPaperMapper.insertEducationPaper(paper);
|
||||||
|
|||||||
@@ -137,6 +137,14 @@ select task_id from education_paper where paper_id=#{paperId}
|
|||||||
#{taskId}
|
#{taskId}
|
||||||
</foreach>
|
</foreach>
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectSpecilayCounts" resultType="java.lang.String">
|
||||||
|
SELECT ep.paper_id
|
||||||
|
FROM exam_monitor em
|
||||||
|
JOIN education_paper ep ON ep.num = em.paper_num
|
||||||
|
WHERE em.exam_status = '1'
|
||||||
|
AND em.tenant_id = #{loginTenantId}
|
||||||
|
ORDER BY em.paper_num;
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<insert id="insertEducationPaper" parameterType="EducationPaper">
|
<insert id="insertEducationPaper" parameterType="EducationPaper">
|
||||||
|
|||||||
@@ -134,6 +134,65 @@
|
|||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectPaperCounts" resultType="pc.exam.pp.module.exam.service.monitor.vo.CourseInVo">
|
||||||
|
SELECT
|
||||||
|
course.sp_id AS courseId,
|
||||||
|
course.sp_name AS courseName,
|
||||||
|
COUNT(*) AS counts
|
||||||
|
FROM exam_question eq
|
||||||
|
JOIN exam_specialty course ON eq.course_name = course.sp_name
|
||||||
|
LEFT JOIN exam_specialty major ON course.parent_id = major.sp_id
|
||||||
|
WHERE eq.qu_id IN (
|
||||||
|
SELECT qu_id
|
||||||
|
FROM education_paper_qu
|
||||||
|
WHERE paper_id IN
|
||||||
|
<foreach collection="allInPaperIds" item="id" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
and eq.tenant_id =#{loginTenantId}
|
||||||
|
and course.deleted ='0'
|
||||||
|
|
||||||
|
GROUP BY course.sp_id, course.sp_name, major.sp_name
|
||||||
|
</select>
|
||||||
|
<select id="selectTaskCounts" resultType="pc.exam.pp.module.exam.service.monitor.vo.SpecialtyVo">
|
||||||
|
SELECT
|
||||||
|
s.sp_id AS specialtyId,
|
||||||
|
s.sp_name AS specialtyName,
|
||||||
|
COUNT(*) AS counts
|
||||||
|
FROM exam_monitor em
|
||||||
|
INNER JOIN education_paper_task ept
|
||||||
|
ON em.task_id = ept.task_id AND ept.deleted = '0'
|
||||||
|
INNER JOIN exam_specialty s
|
||||||
|
ON ept.task_specialty = s.sp_name AND s.deleted = '0'
|
||||||
|
WHERE em.exam_status = '1'
|
||||||
|
AND em.deleted = '0'
|
||||||
|
AND s.sp_name = (
|
||||||
|
SELECT task_specialty
|
||||||
|
FROM education_paper_task
|
||||||
|
WHERE task_id = #{taskId}
|
||||||
|
AND deleted = '0'
|
||||||
|
LIMIT 1
|
||||||
|
)
|
||||||
|
and em.tenant_id =#{loginTenantId}
|
||||||
|
GROUP BY s.sp_id, s.sp_name
|
||||||
|
</select>
|
||||||
|
<select id="selectPaperCountBypaperId" resultType="pc.exam.pp.module.exam.service.monitor.vo.CourseInVo">
|
||||||
|
SELECT
|
||||||
|
course.sp_id AS courseId,
|
||||||
|
course.sp_name AS courseName
|
||||||
|
FROM exam_question eq
|
||||||
|
JOIN exam_specialty course ON eq.course_name = course.sp_name
|
||||||
|
LEFT JOIN exam_specialty major ON course.parent_id = major.sp_id
|
||||||
|
WHERE eq.qu_id IN (
|
||||||
|
SELECT qu_id
|
||||||
|
FROM education_paper_qu
|
||||||
|
WHERE paper_id =#{paperId}
|
||||||
|
)
|
||||||
|
and course.deleted ='0'
|
||||||
|
GROUP BY course.sp_id, course.sp_name, major.sp_name
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<insert id="insertEducationPaperTask" parameterType="EducationPaperTask">
|
<insert id="insertEducationPaperTask" parameterType="EducationPaperTask">
|
||||||
insert into education_paper_task
|
insert into education_paper_task
|
||||||
|
|||||||
@@ -4,6 +4,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="pc.exam.pp.module.exam.dal.mysql.monitor.MonitorMapper">
|
<mapper namespace="pc.exam.pp.module.exam.dal.mysql.monitor.MonitorMapper">
|
||||||
|
|
||||||
|
<resultMap type="TentSpecialy" id="TentSpecialyResult">
|
||||||
|
<result property="id" column="id" />
|
||||||
|
<result property="specialtyId" column="specialty_id" />
|
||||||
|
<result property="points" column="points" />
|
||||||
|
<result property="tenantId" column="tenant_id" />
|
||||||
|
</resultMap>
|
||||||
|
<update id="deleteByTaskIds">
|
||||||
|
UPDATE exam_monitor
|
||||||
|
SET deleted = '2'
|
||||||
|
WHERE task_id IN
|
||||||
|
<foreach item="taskId" collection="taskIds" open="(" separator="," close=")">
|
||||||
|
#{taskId}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
|
<update id="deleteByTaskId">
|
||||||
|
UPDATE exam_monitor
|
||||||
|
SET deleted = '2'
|
||||||
|
WHERE task_id =#{taskId}
|
||||||
|
</update>
|
||||||
|
|
||||||
<select id="selectByStuIdAndTaskIdTop" resultType="java.lang.String">
|
<select id="selectByStuIdAndTaskIdTop" resultType="java.lang.String">
|
||||||
select score from exam_monitor where stu_id =#{stuId} and task_id=#{taskId} ORDER BY score DESC
|
select score from exam_monitor where stu_id =#{stuId} and task_id=#{taskId} ORDER BY score DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
@@ -18,4 +38,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<select id="selectStuIdByTaskId" resultType="java.lang.String">
|
<select id="selectStuIdByTaskId" resultType="java.lang.String">
|
||||||
select stu_id from exam_monitor where task_id =#{taskId} and deleted ='0' and exam_status ='0'
|
select stu_id from exam_monitor where task_id =#{taskId} and deleted ='0' and exam_status ='0'
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectTent" resultMap="TentSpecialyResult">
|
||||||
|
SELECT
|
||||||
|
ets.*,
|
||||||
|
es.sp_name AS name
|
||||||
|
FROM
|
||||||
|
exam_tenant_specialty ets
|
||||||
|
LEFT JOIN
|
||||||
|
exam_specialty es
|
||||||
|
ON
|
||||||
|
ets.specialty_id = es.sp_id
|
||||||
|
WHERE
|
||||||
|
ets.tenant_id = #{loginTenantId}
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -137,6 +137,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
AND q3.deleted = '0'
|
AND q3.deleted = '0'
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
</select>
|
</select>
|
||||||
|
<select id="selectAllSpecialtyRelations"
|
||||||
|
resultType="pc.exam.pp.module.exam.service.monitor.vo.SpecialtyRelation">
|
||||||
|
SELECT sp_id AS spId, parent_id AS parentId
|
||||||
|
FROM exam_specialty
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<select id="selectAllIdToParent" resultType="pc.exam.pp.module.exam.service.monitor.vo.IdParentPair">
|
||||||
|
SELECT sp_id AS spId, parent_id AS parentId
|
||||||
|
FROM exam_specialty
|
||||||
|
WHERE deleted = '0' and status ='0' and tenant_id =#{loginTenantId}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<update id="deleteExamSpecialtyBySpId" parameterType="Long">
|
<update id="deleteExamSpecialtyBySpId" parameterType="Long">
|
||||||
|
|||||||
Reference in New Issue
Block a user