【修改】 监控管理中学生分数不一致的问题

This commit is contained in:
dlaren
2025-08-19 15:20:40 +08:00
parent 59ae05442c
commit b25e354303
17 changed files with 235 additions and 203 deletions

View File

@@ -1,4 +1,5 @@
package pc.exam.pp.module.exam.controller.admin.monitor;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@@ -8,6 +9,7 @@ import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
@@ -22,11 +24,14 @@ import static pc.exam.pp.framework.common.pojo.CommonResult.success;
import pc.exam.pp.framework.excel.core.util.ExcelUtils;
import pc.exam.pp.framework.apilog.core.annotation.ApiAccessLog;
import static pc.exam.pp.framework.apilog.core.enums.OperateTypeEnum.*;
import pc.exam.pp.module.exam.controller.admin.monitor.vo.*;
import pc.exam.pp.module.exam.dal.dataobject.EducationPaperTask;
import pc.exam.pp.module.exam.dal.dataobject.monitor.MonitorDO;
import pc.exam.pp.module.exam.service.monitor.MonitorService;
import static pc.exam.pp.module.infra.enums.ErrorCodeConstants.DEMO03_MONITOR_SESSION_EXISTS;
import static pc.exam.pp.module.infra.enums.ErrorCodeConstants.DEMO03_MONITOR_TIME_EXISTS;
@@ -87,32 +92,30 @@ public class MonitorController {
@PostMapping("/stuMonitor")
@Operation(summary = "学生端进入考试返回值")
public CommonResult getStuMonitor(@Valid @RequestBody StuMonitorPaperVo stuMonitorPaperVo) {
public CommonResult<Long> getStuMonitor(@Valid @RequestBody StuMonitorPaperVo stuMonitorPaperVo) {
long stuMonitor = 0;
try {
stuMonitor = monitorService.getStuMonitor(stuMonitorPaperVo);
} catch (RuntimeException e) {
return error(1-001-606-001,e.getMessage());
return error(1_1_606_001, e.getMessage());
}
if (stuMonitor>0)
{
if (stuMonitor > 0) {
return success(stuMonitor);
}else {
} else {
return error(DEMO03_MONITOR_TIME_EXISTS);
}
}
}
@PostMapping("/stuMonitorQu")
@Operation(summary = "学生端考试过程传试题")
public CommonResult<String> updateStuMonitor(@Valid @RequestBody StuMonitorQuVo stuMonitorQuVo) {
Boolean stuMonitor = monitorService.updateStuMonitor(stuMonitorQuVo);
if (!stuMonitor)
{
if (!stuMonitor) {
return error(DEMO03_MONITOR_SESSION_EXISTS);
}
return success("传值成功");
}
@PostMapping("/endMonitor")
@Operation(summary = "学生端结束考试返回值")
public void endStuMonitor(@Valid @RequestBody StuMonitorPaperEndVo stuMonitorPaperEndVo) {
@@ -123,14 +126,14 @@ public class MonitorController {
@GetMapping("/getPaperTaskList")
@Operation(summary = "根据种类获得试卷任务")
@Parameter(name = "id", description = "试卷种类", required = true, example = "1024")
public CommonResult getPaperTaskList(@RequestParam("id") String id) {
public CommonResult<List<EducationPaperTask>> getPaperTaskList(@RequestParam("id") String id) {
return success(monitorService.getPaperTaskList(id));
}
@PostMapping("/updateMonitorStatus")
@Operation(summary = "改变考生状态")
public CommonResult updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) {
public CommonResult<Boolean> updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) {
return success(monitorService.updateMonitorStatus(stuMonitorStatusVo));
}

View File

@@ -11,23 +11,17 @@ import com.alibaba.excel.annotation.*;
@ExcelIgnoreUnannotated
public class MonitorRespVO {
@Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19828")
@ExcelProperty("主键id")
private String monitorId;
@Schema(description = "用户账号", example = "芋艿")
@ExcelProperty("用户账号")
private String username;
@Schema(description = "用户姓名", example = "赵六")
@ExcelProperty("用户姓名")
private String nickname;
@Schema(description = "班级", example = "芋艿")
@ExcelProperty("班级")
private String className;
@Schema(description = "考试状态", example = "2")
@ExcelProperty("考试状态")
private String examStatus;
@@ -53,7 +47,7 @@ private String ip;
@Schema(description = "剩余时间")
@ExcelProperty("剩余时间")
private LocalDateTime remainingTime;
private String remainingTime;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")

View File

@@ -1,5 +1,6 @@
package pc.exam.pp.module.exam.dal.dataobject.monitor;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@@ -69,5 +70,9 @@ public class MonitorDO extends BaseDO {
* 剩余时间
*/
private Long remainingTime;
/**
* 临时ID
*/
private String temporaryId;
}

View File

@@ -45,4 +45,9 @@ public class StuPaperFileDO extends TenantBaseDO {
* 判分详情,富文本格式
*/
private String content;
/**
* 临时ID对应学生分数得ID
*/
private String temporaryId;
}

View File

@@ -24,23 +24,23 @@ import java.util.Optional;
@Mapper
public interface MonitorMapper extends BaseMapperX<MonitorDO> {
default PageResult<MonitorDO> selectPage(MonitorPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDO>()
.inIfPresent(MonitorDO::getMonitorId, Optional.ofNullable(reqVO.getMonitorId()).map(Arrays::asList).orElse(null))
.likeIfPresent(MonitorDO::getUsername, reqVO.getUsername())
.likeIfPresent(MonitorDO::getTaskId, reqVO.getTaskId())
.likeIfPresent(MonitorDO::getNickname, reqVO.getNickname())
.likeIfPresent(MonitorDO::getClassName, reqVO.getClassName())
.eqIfPresent(MonitorDO::getExamStatus, reqVO.getExamStatus())
.eqIfPresent(MonitorDO::getTaskType, reqVO.getTaskType())
.eqIfPresent(MonitorDO::getScore, reqVO.getScore())
.eqIfPresent(MonitorDO::getPaperNum, reqVO.getPaperNum())
.likeIfPresent(MonitorDO::getTaskName, reqVO.getTaskName())
.eqIfPresent(MonitorDO::getIp, reqVO.getIp())
.betweenIfPresent(MonitorDO::getRemainingTime, reqVO.getRemainingTime())
.betweenIfPresent(MonitorDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MonitorDO::getCreateTime));
}
default PageResult<MonitorDO> selectPage(MonitorPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDO>()
.inIfPresent(MonitorDO::getMonitorId, Optional.ofNullable(reqVO.getMonitorId()).map(Arrays::asList).orElse(null))
.likeIfPresent(MonitorDO::getUsername, reqVO.getUsername())
.likeIfPresent(MonitorDO::getTaskId, reqVO.getTaskId())
.likeIfPresent(MonitorDO::getNickname, reqVO.getNickname())
.likeIfPresent(MonitorDO::getClassName, reqVO.getClassName())
.eqIfPresent(MonitorDO::getExamStatus, reqVO.getExamStatus())
.eqIfPresent(MonitorDO::getTaskType, reqVO.getTaskType())
.eqIfPresent(MonitorDO::getScore, reqVO.getScore())
.eqIfPresent(MonitorDO::getPaperNum, reqVO.getPaperNum())
.likeIfPresent(MonitorDO::getTaskName, reqVO.getTaskName())
.eqIfPresent(MonitorDO::getIp, reqVO.getIp())
.betweenIfPresent(MonitorDO::getRemainingTime, reqVO.getRemainingTime())
.betweenIfPresent(MonitorDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(MonitorDO::getCreateTime));
}
default void removeMonitorByStuIdAndTaskId(DeleteRequestVo vo) {
if (vo.getStudentIds() == null || vo.getStudentIds().isEmpty() || vo.getTaskId() == null) {
@@ -53,7 +53,7 @@ return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDO>()
}
String selectByStuIdAndTaskIdTop(@Param("stuId")Long stuId, @Param("taskId") String taskId);
String selectByStuIdAndTaskIdTop(@Param("stuId") Long stuId, @Param("taskId") String taskId);
String selectByStuIdAndTaskIdNew(Long stuId, String taskId);
@@ -63,6 +63,7 @@ return selectPage(reqVO, new LambdaQueryWrapperX<MonitorDO>()
/**
* 查找授权点位
*
* @return
*/
List<TentSpecialy> selectTent(Long loginTenantId);

View File

@@ -15,7 +15,7 @@ import java.util.List;
*/
@Mapper
public interface StuPaperFileMapper extends BaseMapperX<StuPaperFileDO> {
List<StuPaperFileDO> findByStuIdAndPaperId(@Param("stuId") Long stuId, @Param("paperId") String paperId);
List<StuPaperFileDO> findByStuIdAndPaperId(@Param("stuId") Long stuId, @Param("paperId") String paperId, @Param("temporaryId") String temporaryId);
List<StuPaperFileDO> findOneByStuIdAndPaperId(@Param("stuId")Long stuId, @Param("paperId")String paperId,@Param("type") int type);
}

View File

@@ -13,7 +13,7 @@ import java.util.List;
*
* @author 管理员
*/
public interface MonitorService {
public interface MonitorService {
/**
* 创建监控管理
@@ -52,14 +52,19 @@ import java.util.List;
* @return 监控管理分页
*/
PageResult<MonitorDO> getMonitorPage(MonitorPageReqVO pageReqVO);
//学生端进入考试返回值
long getStuMonitor(StuMonitorPaperVo stuMonitorPaperVo) throws RuntimeException;
//学生端考试过程传试题
Boolean updateStuMonitor(StuMonitorQuVo stuMonitorQuVo);
//学生端结束考试返回值
void endStuMonitor(StuMonitorPaperEndVo stuMonitorPaperEndVo);
//根据种类获得试卷任务
List<EducationPaperTask> getPaperTaskList(String id);
//改变考生状态
Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo);
}

View File

@@ -38,6 +38,8 @@ import pc.exam.pp.module.exam.dal.mysql.specialty.ExamSpecialtyMapper;
import pc.exam.pp.module.exam.dal.mysql.student.StuPaperScoreMapper;
import pc.exam.pp.module.exam.dal.mysql.student.StuScoreVo;
import pc.exam.pp.module.exam.service.monitor.vo.*;
import pc.exam.pp.module.exam.service.paper.IEducationPaperParamService;
import pc.exam.pp.module.exam.service.stuPaperScore.StuPaperScoreService;
//import pc.exam.pp.module.infra.service.file.FileService;
import static pc.exam.pp.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -74,7 +76,9 @@ public class MonitorServiceImpl implements MonitorService {
@Resource
private ExamSpecialtyMapper examSpecialtyMapper;
@Resource
private StuPaperScoreMapper stuPaperScoreMapper;
private StuPaperScoreService stuPaperScoreService;
@Resource
private IEducationPaperParamService educationPaperParamService;
// @Resource
// private FileService fileService;
@@ -140,27 +144,19 @@ public class MonitorServiceImpl implements MonitorService {
}
// 构建授权数量映射specialtyId -> 授权个数
Map<String, Integer> authMap = tentSpecialies.stream()
.collect(Collectors.toMap(
TentSpecialy::getSpecialtyId,
t -> {
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())
));
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<>();
@@ -210,8 +206,7 @@ public class MonitorServiceImpl implements MonitorService {
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));
Map<String, Integer> courseCountMap = courseInVos.stream().collect(Collectors.toMap(CourseInVo::getCourseId, CourseInVo::getCounts, (a, b) -> b));
//校验当前试卷的每门课程是否超过授权限制
for (CourseInVo course : courseList) {
@@ -318,9 +313,7 @@ public class MonitorServiceImpl implements MonitorService {
return 0;
}
}
//开启测评时长限制 没开启场次 -直接返回测评时长
if ("1".equals(educationPaperParam.getIsSession()) && "0".equals(educationPaperParam.getIsTime())) {
info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay());
@@ -330,7 +323,6 @@ public class MonitorServiceImpl implements MonitorService {
return (long) examTime.toLocalTime().toSecondOfDay();
}
return 0L;
}
@@ -341,8 +333,6 @@ public class MonitorServiceImpl implements MonitorService {
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;
@@ -361,27 +351,47 @@ public class MonitorServiceImpl implements MonitorService {
EducationPaper educationPaper = educationPaperMapper.selectEducationPaperByPaperId(stuMonitorPaperEndVo.getPaperId());
String taskId = educationPaper.getTaskId();
String key = "userCache:" + taskId + ":" + stuMonitorPaperEndVo.getStuId();
// double score = educationPaperMapper.selctStuScoreByStuIdAndPaperId(stuMonitorPaperEndVo.getStuId(), stuMonitorPaperEndVo.getPaperId());
BigDecimal score = new BigDecimal(0);
List<StuScoreVo> stuScoreVos = stuPaperScoreMapper.getStuScore(Long.valueOf(stuMonitorPaperEndVo.getStuId()), stuMonitorPaperEndVo.getPaperId(), stuMonitorPaperEndVo.getTemporaryId());
for (StuScoreVo scoreVo : stuScoreVos) {
score = score.add(scoreVo.getScore());
}
// 获取学生分数
StuScoreVo stuScoreVo = stuPaperScoreService.getStuScore(Long.valueOf(stuMonitorPaperEndVo.getStuId()),
stuMonitorPaperEndVo.getPaperId(),
stuMonitorPaperEndVo.getTemporaryId());
BigDecimal score = stuScoreVo.getScore();
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
MonitorDO monitorDOs = null;
if (info != null) {
monitorDOs = getMonitor(info.getMonitorId());
}
if (info != null) {
info.setRemainingTime(0L);
}
EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId);
EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId);
if ("1".equals(educationPaperParam.getSaveGrades())) {
info.setScore(String.valueOf(score));
info.setTemporaryId(stuMonitorPaperEndVo.getTemporaryId());
} 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.doubleValue()> oldScore) {
if (score.doubleValue() > oldScore) {
info.setScore(String.valueOf(score));
info.setTemporaryId(stuMonitorPaperEndVo.getTemporaryId());
} else {
// 保留旧的临时ID
if (monitorDOs != null) {
if (monitorDOs.getTemporaryId() != null) {
info.setTemporaryId(monitorDOs.getTemporaryId());
} else {
info.setTemporaryId(stuMonitorPaperEndVo.getTemporaryId());
}
} else {
// 如果没有旧的临时ID则使用新的
info.setTemporaryId(stuMonitorPaperEndVo.getTemporaryId());
}
info.setScore(monitorDO.getScore()); // 保留旧成绩
}
} catch (NumberFormatException e) {
@@ -392,21 +402,16 @@ public class MonitorServiceImpl implements MonitorService {
// 如果没有旧成绩,则直接设置
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));
}
monitorMapper.updateById(info);
}
@Override
@@ -432,11 +437,7 @@ public class MonitorServiceImpl implements MonitorService {
Time examTime = educationPaperParam.getExamTime();
if (info == null) {
MonitorDO monitorDO1 = monitorMapper.selectOne(
new QueryWrapper<MonitorDO>()
.eq("stu_id", stuId)
.eq("task_id", taskId)
);
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);
@@ -506,29 +507,23 @@ public class MonitorServiceImpl implements MonitorService {
}
// 构建传入列表中的 specialtyId Set这些是传进来的 ID
Set<String> inputSpecialtyIds = inputList.stream()
.map(TentSpecialy::getSpecialtyId)
.collect(Collectors.toSet());
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));
Map<String, String> courseToParentMap = allRelations.stream().filter(r -> r.getParentId() != null).collect(Collectors.toMap(SpecialtyRelation::getSpId, SpecialtyRelation::getParentId));
// 开始过滤:只保留以下情况之一
return inputList.stream()
.filter(item -> {
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());
}).collect(Collectors.toList());
}

View File

@@ -16,7 +16,7 @@ import java.util.List;
*/
public interface StuPaperFileService {
List<StuPaperFileDO> findByStuIDAndPaperId(Long stuID, String paperID);
List<StuPaperFileDO> findByStuIDAndPaperId(Long stuID, String paperID, String temporaryId);
void insertStuPaperFile(StuPaperFileDO stuPaperFileDO);

View File

@@ -21,8 +21,8 @@ public class StuPaperFileServiceImpl implements StuPaperFileService {
private StuPaperFileMapper stuPaperFileMapper;
@Override
public List<StuPaperFileDO> findByStuIDAndPaperId(Long stuID, String paperID) {
return stuPaperFileMapper.findByStuIdAndPaperId(stuID, paperID);
public List<StuPaperFileDO> findByStuIDAndPaperId(Long stuID, String paperID, String temporaryId) {
return stuPaperFileMapper.findByStuIdAndPaperId(stuID, paperID, temporaryId);
}
@Override

View File

@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<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" />
<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
@@ -21,36 +21,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="deleteByTaskId">
UPDATE exam_monitor
SET deleted = '2'
WHERE task_id =#{taskId}
WHERE task_id = #{taskId}
</update>
<select id="selectByStuIdAndTaskIdTop" resultType="java.lang.String">
select score from exam_monitor where stu_id =#{stuId} and task_id=#{taskId} ORDER BY score DESC
LIMIT 1
select score
from exam_monitor
where stu_id = #{stuId}
and task_id = #{taskId}
ORDER BY score DESC LIMIT 1
</select>
<select id="selectByStuIdAndTaskIdNew" resultType="java.lang.String">
select score from exam_monitor where stu_id =#{stuId} and task_id=#{taskId} ORDER BY create_time DESC
LIMIT 1
select score
from exam_monitor
where stu_id = #{stuId}
and task_id = #{taskId}
ORDER BY create_time DESC LIMIT 1
</select>
<select id="selectByStuIdAndTaskId" resultType="java.lang.String">
select task_id from exam_monitor where stu_id = #{stuId} and exam_status !='2'
select task_id
from exam_monitor
where stu_id = #{stuId}
and exam_status !='2'
</select>
<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 id="selectTent" resultMap="TentSpecialyResult">
SELECT
ets.*,
SELECT ets.*,
es.sp_name AS name
FROM
exam_tenant_specialty ets
FROM exam_tenant_specialty ets
LEFT JOIN
exam_specialty es
ON
ets.specialty_id = es.sp_id
WHERE
ets.tenant_id = #{loginTenantId}
WHERE ets.tenant_id = #{loginTenantId}
</select>

View File

@@ -9,11 +9,19 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="findByStuIdAndPaperId" resultType="pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO">
SELECT * FROM exam_stu_paper_fileurl WHERE stu_id = #{stuId} AND paper_id = #{paperId}
SELECT *
FROM exam_stu_paper_fileurl
WHERE stu_id = #{stuId}
AND paper_id = #{paperId}
AND temporary_id = #{temporaryId}
</select>
<select id="findOneByStuIdAndPaperId"
resultType="pc.exam.pp.module.exam.dal.dataobject.student.StuPaperFileDO">
SELECT * FROM exam_stu_paper_fileurl WHERE stu_id = #{stuId} AND paper_id = #{paperId} and type =#{type}
SELECT *
FROM exam_stu_paper_fileurl
WHERE stu_id = #{stuId}
AND paper_id = #{paperId}
and type = #{type}
</select>
</mapper>

View File

@@ -75,12 +75,12 @@ public interface ErrorCodeConstants {
ErrorCode DEMO03_PAPER_SESSION_EXISTS = new ErrorCode(1_001_401_001, "请开启考场设置!");
// ========== 试卷方案 1-001-901-900 ==========
ErrorCode DEMO03_PAPER_TASK_DEL_EXISTS = new ErrorCode(1-001-901-901, "该方案下已有试卷不能删除!");
ErrorCode DEMO03_PAPER_TASK_ADD_EXISTS = new ErrorCode(1-001-901-901, "该方案下已有试卷不能新增!");
ErrorCode DEMO03_PAPER_SCHEMES_ADD_EXISTS = new ErrorCode(1-001-902-902, "该方案下已有相同的题型!");
ErrorCode DEMO03_PAPER_TASK_DEL_EXISTS = new ErrorCode(1_001_901_901, "该方案下已有试卷不能删除!");
ErrorCode DEMO03_PAPER_TASK_ADD_EXISTS = new ErrorCode(1_001_901_901, "该方案下已有试卷不能新增!");
ErrorCode DEMO03_PAPER_SCHEMES_ADD_EXISTS = new ErrorCode(1_001_902_902, "该方案下已有相同的题型!");
// ========== 监控管理 1-001-606-000 ==========
ErrorCode DEMO03_MONITOR_TIME_EXISTS = new ErrorCode(1-001-606-001, "该考试不在考场时间范围内!");
ErrorCode DEMO03_MONITOR_SESSION_EXISTS = new ErrorCode(1-001-606-002, "考生状态未在考试中!请联系管理员");
ErrorCode DEMO03_MONITOR_TIME_EXISTS = new ErrorCode(1_001_606_001, "该考试不在考场时间范围内!");
ErrorCode DEMO03_MONITOR_SESSION_EXISTS = new ErrorCode(1_001_606_002, "考生状态未在考试中!请联系管理员");
}

View File

@@ -71,7 +71,7 @@ public class FileController {
public CommonResult<String> uploadStuFile(StuFileUploadReqVO uploadReqVO) throws Exception {
MultipartFile file = uploadReqVO.getFile();
String path = uploadReqVO.getPath();
return success(fileService.createStuFile(uploadReqVO.getStuId(), uploadReqVO.getPaperId(), file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
return success(fileService.createStuFile(uploadReqVO.getStuId(), uploadReqVO.getPaperId(), uploadReqVO.getTemporaryId(), file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
}
@GetMapping("/{configId}/get/**")

View File

@@ -22,4 +22,7 @@ public class StuFileUploadReqVO {
@Schema(description = "试卷ID")
private String paperId;
@Schema(description = "临时ID每次做题都会变")
private String temporaryId;
}

View File

@@ -36,10 +36,11 @@ public interface FileService {
*
* @param name 文件名称
* @param path 文件路径
* @param temporaryId 临时ID
* @param content 文件内容
* @return 文件路径
*/
String createStuFile(Long stuId, String paperId, String name, String path, byte[] content);
String createStuFile(Long stuId, String paperId, String temporaryId, String name, String path, byte[] content);
/**
* 创建文件

View File

@@ -78,7 +78,7 @@ public class FileServiceImpl implements FileService {
@Override
@SneakyThrows
public String createStuFile(Long stuId, String paperId, String name, String path, byte[] content) {
public String createStuFile(Long stuId, String paperId, String temporaryId, String name, String path, byte[] content) {
// 计算默认的 path 名
String type = FileTypeUtils.getMineType(content, name);
if (StrUtil.isEmpty(path)) {
@@ -88,7 +88,6 @@ public class FileServiceImpl implements FileService {
if (StrUtil.isEmpty(name)) {
name = path;
}
// 上传到文件存储器
FileClient client = fileConfigService.getMasterFileClient();
Assert.notNull(client, "客户端(master) 不能为空");
@@ -105,19 +104,22 @@ public class FileServiceImpl implements FileService {
fileMapper.insert(file);
// 需要更新学生表
// 1、先查询学生试卷 是否已经存在数据
List<StuPaperFileDO> stuPaperFileDOList = stuPaperFileService.findByStuIDAndPaperId(stuId, paperId);
List<StuPaperFileDO> stuPaperFileDOList = stuPaperFileService.findByStuIDAndPaperId(stuId, paperId, temporaryId);
StuPaperFileDO stuPaperFileDO = null;
// 如果查询出来数据得话,需要进行替换
for (StuPaperFileDO fileUrl : stuPaperFileDOList) {
if (fileUrl.getType() == 0) {
stuPaperFileDO = fileUrl;
}
}
// 如果没有查询到,需要新增
if (stuPaperFileDO == null) {
// 说明没有上传过,需要新增进去
StuPaperFileDO stuPaperFile = new StuPaperFileDO();
stuPaperFile.setPaperId(paperId);
stuPaperFile.setStuId(stuId);
stuPaperFile.setUrl(url);
stuPaperFile.setTemporaryId(temporaryId);
stuPaperFile.setType(0);
stuPaperFileService.insertStuPaperFile(stuPaperFile);
} else {