xiangpei
2024-07-11 5073a245f53fd5ca936e779be8c6b9b19d42f67d
Merge remote-tracking branch 'origin/dev' into dev
12个文件已修改
2个文件已添加
234 ■■■■ 已修改文件
src/main/java/com/ycl/jxkg/config/CaffeineConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/config/spring/security/RestAuthenticationProvider.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/constants/CaffeineConstant.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/constants/ExamScoreConstant.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/controller/admin/UploadController.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/controller/student/SubjectController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/domain/entity/ExamPaperScore.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/domain/vo/admin/education/EducationResourceVO.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/job/StudyRecordJob.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/service/impl/EducationResourceServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/EducationResourceMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ycl/jxkg/config/CaffeineConfig.java
@@ -26,7 +26,7 @@
                .build();
        // 初始化认证缓存、学习时长缓存
        caffeineCache.put(CaffeineConstant.AUTH, new HashMap<>(128));
        caffeineCache.put(CaffeineConstant.AUTH, new HashMap<>(128));
        caffeineCache.put(CaffeineConstant.STUDY_RECORD, new HashMap<>(128));
        return caffeineCache;
    }
}
src/main/java/com/ycl/jxkg/config/spring/security/RestAuthenticationProvider.java
@@ -1,7 +1,6 @@
package com.ycl.jxkg.config.spring.security;
import com.github.benmanes.caffeine.cache.Cache;
import com.ycl.jxkg.constants.CaffeineConstant;
import com.ycl.jxkg.context.WebContext;
import com.ycl.jxkg.enums.RoleEnum;
src/main/java/com/ycl/jxkg/constants/CaffeineConstant.java
@@ -14,4 +14,9 @@
     */
    public final static String AUTH = "AUTH";
    /**
     * 记录学习时长
     *
     */
    public final static String STUDY_RECORD ="STUDY_RECORD";
}
src/main/java/com/ycl/jxkg/constants/ExamScoreConstant.java
New file
@@ -0,0 +1,22 @@
package com.ycl.jxkg.constants;
/**
 * 成绩状态
 *
 * @author:flq
 * @date:2024/7/10 11:36
 */
public class ExamScoreConstant {
    /**
     * 考了
     *
     */
    public final static Integer PRESENT = 0;
    /**
     * 缺考
     *
     */
    public final static Integer ABSENT =1;
}
src/main/java/com/ycl/jxkg/controller/admin/UploadController.java
@@ -12,6 +12,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -41,6 +42,8 @@
    private final UserService userService;
    private final RuoYiConfig ruoYiConfig;
    @Autowired
    public UploadController(FileUpload fileUpload, SystemConfig systemConfig, UserService userService, RuoYiConfig ruoYiConfig) {
        this.fileUpload = fileUpload;
src/main/java/com/ycl/jxkg/controller/student/SubjectController.java
New file
@@ -0,0 +1,31 @@
package com.ycl.jxkg.controller.student;
import com.github.pagehelper.PageInfo;
import com.ycl.jxkg.base.BaseApiController;
import com.ycl.jxkg.base.Result;
import com.ycl.jxkg.domain.entity.Subject;
import com.ycl.jxkg.domain.vo.admin.education.SubjectEditRequestVO;
import com.ycl.jxkg.domain.vo.admin.education.SubjectPageRequestVO;
import com.ycl.jxkg.domain.vo.admin.education.SubjectResponseVO;
import com.ycl.jxkg.service.SubjectService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RequiredArgsConstructor
@RestController("StudentSubjectController")
@RequestMapping(value = "/api/student/subject")
public class SubjectController extends BaseApiController {
    private final SubjectService subjectService;
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Result<List<Subject>> list() {
        List<Subject> subjects = subjectService.allSubject();
        return Result.ok(subjects);
    }
}
src/main/java/com/ycl/jxkg/domain/entity/ExamPaperScore.java
@@ -62,7 +62,7 @@
    private Integer doTime;
    /**
     * 试卷状态(1待判分 2完成)
     * 试卷状态(0正常 1缺考)
     */
    @TableField("status")
    private Integer status;
src/main/java/com/ycl/jxkg/domain/vo/admin/education/EducationResourceVO.java
@@ -62,6 +62,7 @@
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    private String visitUrl;
    @Data
    public static class UploadFile {
src/main/java/com/ycl/jxkg/job/StudyRecordJob.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.benmanes.caffeine.cache.Cache;
import com.ycl.jxkg.constants.CaffeineConstant;
import com.ycl.jxkg.domain.entity.StudyRecord;
import com.ycl.jxkg.mapper.StudyRecordMapper;
import com.ycl.jxkg.service.StudyRecordService;
@@ -36,15 +37,13 @@
    private void updateStudyRecord() {
        log.info("开始存学习时长");
        List<StudyRecord> cacheList = new ArrayList<>();
        // 取出所有缓存项
        // 取出所有学习记录缓存项
        ConcurrentMap<String, Object> map = caffeineCache.asMap();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            if (key.startsWith("STUDENT_")) {
                StudyRecord studyRecord = (StudyRecord) entry.getValue();
                cacheList.add(studyRecord);
            }
        Map<String,StudyRecord> studyMap = (Map<String, StudyRecord>) map.get(CaffeineConstant.STUDY_RECORD);
        for (Map.Entry<String, StudyRecord> entry : studyMap.entrySet()) {
            cacheList.add(entry.getValue());
        }
        List<Integer> studentIds = cacheList.stream().map(StudyRecord::getStudentId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(studentIds)) {
            //数据库中已经存在的学生数据
@@ -62,7 +61,7 @@
            }
            studyRecordService.saveOrUpdateBatch(cacheList);
        }
        caffeineCache.invalidateAll(map.keySet());
        caffeineCache.invalidate(CaffeineConstant.STUDY_RECORD);
        log.info("结束存学习时长");
    }
}
src/main/java/com/ycl/jxkg/service/impl/EducationResourceServiceImpl.java
@@ -5,6 +5,7 @@
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycl.jxkg.base.Result;
import com.ycl.jxkg.constants.CaffeineConstant;
import com.ycl.jxkg.context.WebContext;
import com.ycl.jxkg.domain.entity.EducationResource;
import com.ycl.jxkg.domain.entity.Subject;
@@ -18,13 +19,11 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.*;
/**
 * @author:flq
@@ -35,12 +34,16 @@
@Slf4j
public class EducationResourceServiceImpl implements EducationResourceService {
    private final EducationResourceMapper mapper;
    private final SubjectMapper subjectMapper;
    private final WebContext webContext;
    private final ClassesUserMapper classesUserMapper;
    @Autowired
    private Cache<String, Object> caffeineCache;
    @Value("${spring.config.url}")
    private String url;
    @Override
    public Result add(EducationResourceVO form) {
        EducationResource educationResource = new EducationResource();
@@ -86,6 +89,7 @@
        page.getList().stream().forEach(item -> {
            item.setContentUrl(JSON.parseObject(item.getContentUrlString(), EducationResourceVO.UploadFile.class));
            item.setAttachment(JSON.parseArray(item.getAttachmentString(), EducationResourceVO.UploadFile.class));
            item.setVisitUrl(url + "/api/files/" + item.getContentUrl().getUrl());
        });
        return Result.ok(page.getList()).put("total", page.getTotal());
    }
@@ -114,27 +118,32 @@
        List<Subject> subjects = subjectMapper.allSubject();
        return Result.ok(subjects);
    }
    //记录视频时长
    @Override
    public Result recordTime(Integer userId) {
        if (userId ==null){
        if (userId == null) {
            throw new RuntimeException("用户id为空");
        }
        StudyRecord studyRecord = (StudyRecord) caffeineCache.getIfPresent("STUDENT_"+userId);
        if (studyRecord != null) {
            //存在缓存
            Date lastTime = studyRecord.getLastTime();
            Date now = new Date();
            studyRecord.setStudyTime(studyRecord.getStudyTime()+(now.getTime()-lastTime.getTime())/1000);
            studyRecord.setLastTime(now);
        }else {
            //不存在缓存
            studyRecord = new StudyRecord();
            studyRecord.setStudentId(userId);
            studyRecord.setStudyTime(0L);
            studyRecord.setLastTime(new Date());
        Map<String, StudyRecord> studyMap = (Map<String, StudyRecord>) caffeineCache.getIfPresent(CaffeineConstant.STUDY_RECORD);
        if (!CollectionUtils.isEmpty(studyMap)) {
            StudyRecord studyRecord = studyMap.get(userId + "");
            if (studyRecord != null) {
                //存在缓存
                Date lastTime = studyRecord.getLastTime();
                Date now = new Date();
                studyRecord.setStudyTime(studyRecord.getStudyTime() + (now.getTime() - lastTime.getTime()) / 1000);
                studyRecord.setLastTime(now);
            } else {
                //不存在缓存
                studyRecord = new StudyRecord();
                studyRecord.setStudentId(userId);
                studyRecord.setStudyTime(0L);
                studyRecord.setLastTime(new Date());
            }
            studyMap.put(userId + "", studyRecord);
            caffeineCache.put(CaffeineConstant.STUDY_RECORD, studyMap);
        }
        caffeineCache.put("STUDENT_" + userId, studyRecord);
        return Result.ok();
    }
}
src/main/java/com/ycl/jxkg/service/impl/ExamServiceImpl.java
@@ -9,6 +9,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.jxkg.base.Result;
import com.ycl.jxkg.base.SystemCode;
import com.ycl.jxkg.constants.ExamScoreConstant;
import com.ycl.jxkg.context.WebContext;
import com.ycl.jxkg.domain.base.AbsVo;
import com.ycl.jxkg.domain.entity.*;
@@ -561,14 +562,21 @@
        for (StudentExamInfoVO studentExamInfoVO : studentExamList) {
            Integer userId = studentExamInfoVO.getUserId();
            Optional<ExamSubmitTemp> first = examSubmitTempList.stream().filter(examSubmitTemp -> examSubmitTemp.getUserId().equals(userId)).findFirst();
            if(first.isPresent()){
            if (first.isPresent()) {
                ExamSubmitTemp examSubmitTemp = first.get();
                studentExamInfoVO.setMarkPaperStatus(examSubmitTemp.getMarkPaperStatus());
                studentExamInfoVO.setStatus(examSubmitTemp.getStatus());
                studentExamInfoVO.setDoTime(examSubmitTemp.getDoTime());
            }else {
                studentExamInfoVO.setMarkPaperStatus(ExamSubmitTempStatusEnum.temp);
            } else {
                //不存在考试记录
                studentExamInfoVO.setStatus(ExamSubmitTempStatusEnum.temp);
                //根据Score表判断
                ExamPaperScore paperScore = examPaperScoreMapper.getByExamIdUserId(exam.getId(), userId);
                if(paperScore==null) {
                    studentExamInfoVO.setMarkPaperStatus(ExamSubmitTempStatusEnum.temp);
                }else {
                    studentExamInfoVO.setMarkPaperStatus(ExamSubmitTempStatusEnum.finish);
                }
                studentExamInfoVO.setDoTime(0);
            }
        }
@@ -589,20 +597,22 @@
    @Override
    public Result getMarkPaperInfo(Integer examId, Integer userId) {
        //如果已经阅过卷了,查成绩表
        Result<ExamPaperMarkVO> paperMarkVO1 = checkHasJudge(examId, userId);
        if (paperMarkVO1 != null) return paperMarkVO1;
        User student = userMapper.getUserById(userId);
        ExamVO exam = examMapper.getById(examId);
        //学生答题表
        ExamSubmitTemp userExam = new LambdaQueryChainWrapper<>(examSubmitTempMapper)
                .eq(ExamSubmitTemp::getExamId, examId)
                .eq(ExamSubmitTemp::getUserId, userId)
                .one();
        if (Objects.isNull(userExam)) {
            throw new RuntimeException("该学员考试记录不存在");
            //缺考,学生没有做题信息
            ExamPaperMarkVO paperMarkVO = createVO(null, exam, student);
            return Result.ok(paperMarkVO);
        }
        //如果已经阅过卷了,查成绩表
        Result<ExamPaperMarkVO> paperMarkVO1 = checkHasJudge(examId, userId, userExam);
        if (paperMarkVO1 != null) return paperMarkVO1;
        User student = userMapper.getUserById(userId);
        ExamVO exam = examMapper.getById(examId);
        //封装阅卷基本数据
        ExamPaperMarkVO paperMarkVO = createVO(userExam, exam, student);
        List<QuestionAnswerCopyVO> answerList = JSONArray.parseArray(userExam.getQuestionAnswerCopy(), QuestionAnswerCopyVO.class);
@@ -633,16 +643,20 @@
    }
    //检查是否阅卷
    private Result<ExamPaperMarkVO> checkHasJudge(Integer examId, Integer userId, ExamSubmitTemp userExam) {
        if (ExamSubmitTempStatusEnum.finish.equals(userExam.getMarkPaperStatus())) {
            ExamPaperScore examPaperScore = examPaperScoreMapper.getByExamIdUserId(examId, userId);
    private Result<ExamPaperMarkVO> checkHasJudge(Integer examId, Integer userId) {
        ExamPaperScore examPaperScore = examPaperScoreMapper.getByExamIdUserId(examId, userId);
        if (examPaperScore != null) {
            ExamPaperMarkVO paperMarkVO = new ExamPaperMarkVO();
            BeanUtils.copyProperties(examPaperScore, paperMarkVO);
            paperMarkVO.setTotalScore(examPaperScore.getTotalScore() + "");
            paperMarkVO.setScore(examPaperScore.getScore() + "");
            List<PaperFixQuestionVO> paperFixQuestionVOS = JSONArray.parseArray(examPaperScore.getPaperContent(), PaperFixQuestionVO.class);
            paperMarkVO.setTitleItems(paperFixQuestionVOS);
            paperMarkVO.setNavbar(JSONArray.parseArray(examPaperScore.getNavbar(), ExamPaperMarkNavbarVO.class));
            if (!StringUtils.isEmpty(examPaperScore.getPaperContent())) {
                List<PaperFixQuestionVO> paperFixQuestionVOS = JSONArray.parseArray(examPaperScore.getPaperContent(), PaperFixQuestionVO.class);
                paperMarkVO.setTitleItems(paperFixQuestionVOS);
            }
            if (!StringUtils.isEmpty(examPaperScore.getNavbar())) {
                paperMarkVO.setNavbar(JSONArray.parseArray(examPaperScore.getNavbar(), ExamPaperMarkNavbarVO.class));
            }
            return Result.ok(paperMarkVO);
        }
        return null;
@@ -820,16 +834,23 @@
    //封装阅卷返回数据
    private ExamPaperMarkVO createVO(ExamSubmitTemp userExam, ExamVO exam, User student) {
        Integer paperId = exam.getExamPaperId();
        ExamPaper examPaper = examPaperMapper.selectById(paperId);
        ExamPaperMarkVO paperMarkVO = new ExamPaperMarkVO();
        BeanUtils.copyProperties(userExam, paperMarkVO);
        paperMarkVO.setPaperId(exam.getExamPaperId());
        paperMarkVO.setExamName(exam.getExamName());
        paperMarkVO.setPaperType(exam.getExamPaperType());
        paperMarkVO.setSubmitTime(userExam.getUpdateTime());
        if (userExam != null) {
            BeanUtils.copyProperties(userExam, paperMarkVO);
            paperMarkVO.setSubmitTime(userExam.getUpdateTime());
            paperMarkVO.setTitleItems(JSON.parseArray(userExam.getExamSubmit(), PaperFixQuestionVO.class));
        } else {
            //缺考,学生没有做题信息
            paperMarkVO.setExamId(exam.getExamPaperId());
            paperMarkVO.setUserId(student.getId());
            paperMarkVO.setScore(BigDecimal.ZERO + "");
            paperMarkVO.setDoTime(0);
        }
        paperMarkVO.setUserName(student.getRealName());
        paperMarkVO.setTitleItems(JSON.parseArray(userExam.getExamSubmit(), PaperFixQuestionVO.class));
        paperMarkVO.setExamName(exam.getExamName());
        paperMarkVO.setPaperId(exam.getExamPaperId());
        paperMarkVO.setPaperType(exam.getExamPaperType());
        ExamPaper examPaper = examPaperMapper.selectById(exam.getExamPaperId());
        paperMarkVO.setTotalScore(examPaper.getScore() + "");
        paperMarkVO.setDeductType(examPaper.getDeductType());
        paperMarkVO.setDeductScore(examPaper.getDeductTypeScore());
@@ -848,13 +869,24 @@
        examPaperScore.setTotalScore(new BigDecimal(examPaperMark.getTotalScore()));
        examPaperScore.setJudgeUser(userId);
        examPaperScore.setJudgeTime(new Date());
        examPaperScore.setPaperContent(JSON.toJSONString(examPaperMark.getTitleItems()));
        examPaperScore.setNavbar(JSON.toJSONString(examPaperMark.getNavbar()));
        if (!StringUtils.isEmpty(examPaperMark.getTitleItems())) {
            examPaperScore.setPaperContent(JSON.toJSONString(examPaperMark.getTitleItems()));
        }
        if (!StringUtils.isEmpty(examPaperMark.getNavbar())) {
            examPaperScore.setNavbar(JSON.toJSONString(examPaperMark.getNavbar()));
        }
        long questionCorrect = 0;
        long questionCount = 0;
        if (!CollectionUtils.isEmpty(examPaperMark.getNavbar())) {
            examPaperScore.setStatus(ExamScoreConstant.PRESENT);
            questionCorrect = examPaperMark.getNavbar().stream().filter(vo -> vo.getRight() != null && vo.getRight()).count();
            questionCount = examPaperMark.getNavbar().size();
        } else {
            //缺考查试卷配置
            Integer paperId = examPaperMark.getPaperId();
            ExamPaper examPaper = examPaperMapper.selectById(paperId);
            questionCount = examPaper.getNum();
            examPaperScore.setStatus(ExamScoreConstant.ABSENT);
        }
        examPaperScore.setQuestionCorrect(Integer.valueOf(questionCorrect + ""));
        examPaperScore.setQuestionCount(Integer.valueOf(questionCount + ""));
@@ -870,8 +902,10 @@
                    .eq(ExamSubmitTemp::getExamId, examPaperMark.getExamId())
                    .eq(ExamSubmitTemp::getUserId, examPaperMark.getUserId())
                    .one();
            userExam.setMarkPaperStatus(ExamSubmitTempStatusEnum.finish);
            examSubmitTempMapper.updateById(userExam);
            if (userExam != null) {
                userExam.setMarkPaperStatus(ExamSubmitTempStatusEnum.finish);
                examSubmitTempMapper.updateById(userExam);
            }
        }
        return Result.ok();
    }
@@ -885,7 +919,7 @@
    @Override
    public Result addTime(AddTimeForm form) {
        if (! websocketServer.checkUserOnline(form.getUserId())) {
        if (!websocketServer.checkUserOnline(form.getUserId())) {
            throw new RuntimeException("该学员不在线,无法执行该操作");
        }
        WebsocketDataVO websocket = new WebsocketDataVO();
@@ -900,7 +934,7 @@
    @Override
    public Result forceSubmit(ForceSubmitForm form) {
        if (! websocketServer.checkUserOnline(form.getUserId())) {
        if (!websocketServer.checkUserOnline(form.getUserId())) {
            throw new RuntimeException("该学员不在线,无法执行该操作");
        }
        WebsocketDataVO websocket = new WebsocketDataVO();
src/main/resources/application-dev.yml
@@ -5,7 +5,10 @@
  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
  url: D:/ycl/file
spring:
  config:
    url: http://localhost:8000
  datasource:
    url: jdbc:mysql://42.193.1.25:3306/xzs?useSSL=true&useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&allowMultiQueries=true
    username: root
src/main/resources/application-prod.yml
@@ -6,6 +6,8 @@
  url: E:/ycl/file
spring:
  config:
    url: https://42.193.1.25:8000
  datasource:
    url: jdbc:mysql://42.193.1.25:3306/xzs?useSSL=true&useUnicode=true&serverTimezone=GMT%2B8&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&allowMultiQueries=true
    username: root
src/main/resources/mapper/EducationResourceMapper.xml
@@ -32,6 +32,9 @@
            <if test="query.classId != null">
                AND ter.class_id = #{query.classId}
            </if>
            <if test="query.contentType != null and query.contentType != '' ">
                AND ter.content_type = #{query.contentType}
            </if>
        </where>
        ORDER BY
        ter.create_time DESC
@@ -65,6 +68,9 @@
            <if test="query.subjectId != null">
                AND ter.subject_id = #{query.subjectId}
            </if>
            <if test="query.contentType != null and query.contentType != '' ">
                AND ter.content_type = #{query.contentType}
            </if>
        </where>
        ORDER BY
        ter.create_time DESC