@@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag ;
import jakarta.annotation.Resource ;
import jakarta.servlet.http.HttpServletRequest ;
import org.springframework.beans.BeanUtils ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.data.redis.core.StringRedisTemplate ;
import org.springframework.validation.annotation.Validated ;
@@ -15,7 +16,10 @@ import pc.exam.pp.framework.common.util.servlet.ServletUtils;
import pc.exam.pp.framework.security.config.SecurityProperties ;
import pc.exam.pp.framework.security.core.LoginUser ;
import pc.exam.pp.framework.security.core.util.SecurityFrameworkUtils ;
import pc.exam.pp.module.exam.controller.admin.paper.vo.ExamPaperVo ;
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.student.StuPaperFileDO ;
import pc.exam.pp.module.exam.dal.dataobject.student.StuPaperScoreDO ;
import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperPersonMapper ;
import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperQuMapper ;
@@ -23,16 +27,17 @@ import pc.exam.pp.module.exam.dal.mysql.paper.EducationPaperSessionMapper;
import pc.exam.pp.module.exam.dal.mysql.question.ExamQuestionMapper ;
import pc.exam.pp.module.exam.dal.mysql.student.StuScoreVo ;
import pc.exam.pp.module.exam.service.paper.IEducationPaperParamService ;
import pc.exam.pp.module.exam.service.paper.IEducationPaperQuService ;
import pc.exam.pp.module.exam.service.stuPaperScore.StuPaperScoreService ;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuInTheExam ;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperReqVo ;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuPaperScoreInfoVo ;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.StuTheExamInfo ;
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService ;
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.* ;
import pc.exam.pp.module.judgement.service.TaskManager ;
import pc.exam.pp.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO ;
import java.time.Duration ;
import java.time.Instant ;
import java.time.LocalDateTime ;
import java.time.format.DateTimeFormatter ;
import java.util.Date ;
import java.util.List ;
import java.util.Map ;
@@ -67,6 +72,10 @@ public class AutoToolsController {
IEducationPaperParamService educationPaperParamService ;
@Resource
StringRedisTemplate stringRedisTemplate ;
@Resource
IEducationPaperQuService educationPaperQuService ;
@Resource
StuPaperFileService stuPaperFileService ;
@GetMapping ( " /getStuScoreInfo " )
@Operation ( summary = " 通过学生ID、试卷ID获取 " )
@@ -161,31 +170,120 @@ public class AutoToolsController {
stuTheExamInfo . setTime ( formatLongDuration ( countdown . get ( ) ) ) ;
// 返回数据-上传文件状态 0: 上传; 1: 不上传
stuTheExamInfo . setUpload ( 1 ) ;
// 返回数据-上传文件状态 0: 结束; 1: 不结束
// 返回数据-结束考试 0: 结束; 1: 不结束
stuTheExamInfo . setEndStatus ( 1 ) ;
// 返回数据-网络状态
stuTheExamInfo . setNetwork ( " 强 " ) ;
// 创建对应的线程池
if ( loginUser ! = null ) {
taskManager . startTask ( stuInTheExam , stuTheExamInfo , token , countdown , new AtomicInteger ( 0 ) , String . valueOf ( loginUser . getId ( ) ) ) ;
taskManager . startTask ( stuInTheExam , stuTheExamInfo , token , countdown , new AtomicInteger ( 0 ) , loginUser . getId ( ) + " _ " + stuInTheExam . getTask Id ( ) + " _ " + stuInTheExam . getPaperId ( ) ) ;
}
System . out . println ( " --------------token------------------ " + token ) ;
return CommonResult . success ( token ) ;
}
return CommonResult . success ( " 未登录 " ) ;
}
// 学生端重新登录,判断是否上一次考试没有结束就退出了
@GetMapping ( " /reStartExamStatus " )
public CommonResult < String > reStartExamStatus ( ) {
HttpServletRequest request = ServletUtils . getRequest ( ) ;
// 获取学生ID
LoginUser loginUser = SecurityFrameworkUtils . getLoginUser ( ) ;
if ( loginUser ! = null ) {
long userId = loginUser . getId ( ) ;
String key = taskManager . getTaskById ( String . valueOf ( userId ) ) ;
if ( key = = null ) {
return CommonResult . success ( " 0 " ) ;
}
return CommonResult . success ( key ) ;
}
return CommonResult . success ( " 0 " ) ;
}
// 学生端考试没有结束对出, 继续进行开始( 需要返回下载文件地址, 任务ID)
@PostMapping ( " /reStartExam " )
public CommonResult < ExamRestartPaperVo > reStartExam ( @RequestBody StuInTheExam stuInTheExam ) {
// 获取学生ID
LoginUser loginUser = SecurityFrameworkUtils . getLoginUser ( ) ;
HttpServletRequest request = ServletUtils . getRequest ( ) ;
String token = SecurityFrameworkUtils . obtainAuthorization ( request ,
securityProperties . getTokenHeader ( ) , securityProperties . getTokenParameter ( ) ) ;
ExamRestartPaperVo examRestartPaperVo = new ExamRestartPaperVo ( ) ;
// 如果继续考试, 需要关闭之前的, 重新开始ws
String taskManagerId = loginUser . getId ( ) + " _ " + stuInTheExam . getTaskId ( ) + " _ " + stuInTheExam . getPaperId ( ) ;
taskManager . stopTask ( taskManagerId ) ;
if ( loginUser ! = null ) {
// 获取试卷详情
ExamPaperVo examPaperVo = educationPaperQuService . selectPaperQuListByPaperId ( stuInTheExam . getPaperId ( ) ) ;
// 获取剩余的时间
String key = " userCache: " + stuInTheExam . getTaskId ( ) + " : " + loginUser . getId ( ) ;
MonitorDO info = JsonUtils . parseObject ( stringRedisTemplate . opsForValue ( ) . get ( key ) , MonitorDO . class ) ;
if ( info ! = null ) {
// 获取随机ID
String temporaryId = info . getTemporaryId ( ) ;
// 获取开始时间
String startTimeExam = info . getStartTime ( ) ;
DateTimeFormatter formatter = DateTimeFormatter . ofPattern ( " yyyy-MM-dd HH:mm:ss " ) ;
LocalDateTime targetTime = LocalDateTime . parse ( startTimeExam , formatter ) ;
LocalDateTime currentTime = LocalDateTime . now ( ) ;
Duration duration = Duration . between ( currentTime , targetTime ) ;
// 两者相差的时间
long secondsDifference = duration . getSeconds ( ) ;
// 获取一共要考试多长时间
long remainingTime = info . getRemainingTime ( ) ;
// 判断剩余时间是否大于等于两者相差的时间
long times = remainingTime - secondsDifference ;
// 开启ws
// 获取上传文件时间
String time = examPaperVo . getEducationPaperParam ( ) . getUploadTime ( ) ;
// 将分钟继续转换成秒
stuInTheExam . setTimes ( Integer . parseInt ( time ) * 60 ) ;
// 倒计时
AtomicInteger countdown = new AtomicInteger ( ( int ) times ) ;
// 创建初始返回数据
StuTheExamInfo stuTheExamInfo = new StuTheExamInfo ( ) ;
// 返回数据-剩余时间
stuTheExamInfo . setTime ( formatLongDuration ( countdown . get ( ) ) ) ;
// 返回数据-上传文件状态 0: 上传; 1: 不上传
stuTheExamInfo . setUpload ( 1 ) ;
// 返回数据-结束考试 0: 结束; 1: 不结束
stuTheExamInfo . setEndStatus ( 1 ) ;
// 返回数据-网络状态
stuTheExamInfo . setNetwork ( " 强 " ) ;
taskManager . startTask ( stuInTheExam , stuTheExamInfo , token , countdown , new AtomicInteger ( 0 ) , loginUser . getId ( ) + " _ " + stuInTheExam . getTaskId ( ) + " _ " + stuInTheExam . getPaperId ( ) ) ;
// 将数组的值进行复制
BeanUtils . copyProperties ( examPaperVo , examRestartPaperVo ) ;
examRestartPaperVo . setWsToken ( token ) ;
// 查询学生文件下载地址
examRestartPaperVo . setTemporaryId ( temporaryId ) ;
List < StuPaperFileDO > stuPaperFileS = stuPaperFileService . findByStuIDAndPaperId ( loginUser . getId ( ) , stuInTheExam . getPaperId ( ) , temporaryId ) ;
stuPaperFileS . forEach ( stuPaperFileDO - > {
if ( stuPaperFileDO . getType ( ) = = 0 ) {
// 将文件地址存放,方便前端继续下载处理
examRestartPaperVo . setFileUrl ( stuPaperFileDO . getUrl ( ) ) ;
}
} ) ;
return CommonResult . success ( examRestartPaperVo ) ;
} else {
return CommonResult . error ( 1_0001_001 , " 没有找到对应的考试信息 " ) ;
}
}
return CommonResult . error ( 1_0001_002 , " 没有找到对应的学生信息 " ) ;
}
/**
* 停止考试
*
* @return true
*/
@GetMapping ( " /stopExam " )
public CommonResult < Boolean > stopExam ( ) {
public CommonResult < Boolean > stopExam ( @RequestParam ( " taskId " ) String taskId , @RequestParam ( " paperId " ) String paperId ) {
HttpServletRequest request = ServletUtils . getRequest ( ) ;
String userId = null ;
if ( request ! = null ) {
userId = String . valueOf ( SecurityFrameworkUtils . getLoginUserId ( ) ) ;
// 将userId 拼接 taskId 作为key
// 防止不同试卷ID冲突
userId + = " _ " + taskId + " _ " + paperId ;
// 删除对应的线程池
taskManager . stopTask ( userId ) ;
return CommonResult . success ( true ) ;
@@ -195,10 +293,6 @@ public class AutoToolsController {
// 时间转换
public static String formatLongDuration ( int totalSeconds ) {
int hours = totalSeconds / 3600 ;
int minutes = ( totalSeconds % 3600 ) / 60 ;
int seconds = totalSeconds % 60 ;
return String . format ( " %02d:%02d:%02d " , hours , minutes , seconds ) ;
return TaskManager . formatLongDuration ( totalSeconds ) ;
}
}