“djh”
2024-12-27 3aae8ddd5b9624626921abdcc33122dccdcd5c61
exam-system/src/main/java/com/gkhy/exam/institutionalaccess/service/serviceImpl/TripartiteInterfaceServiceImpl.java
@@ -3,6 +3,7 @@
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.gkhy.exam.institutionalaccess.entity.*;
@@ -11,6 +12,7 @@
import com.gkhy.exam.institutionalaccess.model.resp.ThErrorDataRespDTO;
import com.gkhy.exam.institutionalaccess.model.vo.ThCourseChapterVO;
import com.gkhy.exam.institutionalaccess.service.*;
import com.gkhy.exam.institutionalaccess.utils.ValidatorUtils;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.InstitutionUser;
@@ -63,89 +65,79 @@
    private ThBatchCourseChapterService batchCourseChapterService;
    @Autowired
    private ThSubjectTypeService subjectTypeService;
    @Autowired
    private ThCertService certService;
    @Override
    public boolean receiveQuestionBank(JSONObject jsonObject) {
    public AjaxResult receiveQuestionBank(JSONObject jsonObject) throws Exception {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        List<ThQuestionBankReqDTO> questionBankReqDTO =  decryptData(jsonObject, new TypeReference<List<ThQuestionBankReqDTO>>() {},"题库数据");
        if(CollectionUtils.isEmpty(questionBankReqDTO)){
            throw new BusinessException(this.getClass(),ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"题库数据不可为空");
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        List<ThErrorDataRespDTO> errorDataRespDTOS = new ArrayList<>();
        List<ThQuestionBankReqDTO> thQuestionBankReqDTOS = new ArrayList<>();
        for (ThQuestionBankReqDTO thQuestionBankReqDTO : questionBankReqDTO) {
            String valdateMessage=ValidatorUtils.validateFast(thQuestionBankReqDTO);
            if(!StringUtils.isEmpty(valdateMessage)){
//                throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,valdateMessage);
                errorDataRespDTOS.add(new ThErrorDataRespDTO(thQuestionBankReqDTO.getUuid(),valdateMessage));
                continue;
            }
            thQuestionBankReqDTOS.add(thQuestionBankReqDTO);
        }
        //反序列化
        ThQuestionBankReqDTO questionBankReqDTO = null;
        try {
            questionBankReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThQuestionBankReqDTO>() {});
        }catch (Exception e){
            logger.error("组卷反序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        List<ThQuestionBank> savethQuestionBanks = new ArrayList<>();
        List<ThQuestionBank> updatethQuestionBanks = new ArrayList<>();
        for (ThQuestionBankReqDTO thQuestionBankReqDTO : thQuestionBankReqDTOS) {
            //根据uuid查询数据
            ThQuestionBank qb = questionBankService.getQuestionInfoByUuid(thQuestionBankReqDTO.getUuid());
            if(qb == null){
                //新增
                qb = new ThQuestionBank();
                BeanUtils.copyProperties(thQuestionBankReqDTO, qb);
                qb.setUuid(thQuestionBankReqDTO.getUuid());
                qb.setInstitutionId(institutionUser.getId());
                qb.setInstitutionName(institutionUser.getInstitutionalName());
                qb.setCreateBy(institutionUser.getInstitutionalName());
                qb.setUpdateBy(institutionUser.getInstitutionalName());
                savethQuestionBanks.add(qb);
            }else {
                //修改
                BeanUtils.copyProperties(thQuestionBankReqDTO, qb);
                qb.setUpdateBy(institutionUser.getInstitutionalName());
                updatethQuestionBanks.add(qb);
            }
        }
        //参数校验
        validateQuestion(questionBankReqDTO);
        //根据uuid查询数据
        ThQuestionBank qb = questionBankService.getQuestionInfoByUuid(questionBankReqDTO.getUuid());
        boolean i = true;
        if(qb == null){
            //新增
            qb = new ThQuestionBank();
            BeanUtils.copyProperties(questionBankReqDTO, qb);
            qb.setUuid(questionBankReqDTO.getUuid());
            qb.setInstitutionId(institutionUser.getId());
            qb.setInstitutionName(institutionUser.getInstitutionalName());
            qb.setCreateTime(LocalDateTime.now());
            qb.setUpdateTime(LocalDateTime.now());
            qb.setCreateBy(institutionUser.getInstitutionalName());
            qb.setUpdateBy(institutionUser.getInstitutionalName());
            //qb.setDelFlag(DeleteStatusEnum.NO.getStatus());
            i = questionBankService.save(qb);
        }else {
            //修改
            BeanUtils.copyProperties(questionBankReqDTO, qb);
            i = questionBankService.updateById(qb);
        }
        return i;
        questionBankService.saveBatch(savethQuestionBanks);
        questionBankService.updateBatchById(updatethQuestionBanks);
        return AjaxResult.success(errorDataRespDTOS);
    }
    @Transactional
    @Override
    public AjaxResult receiveCourse(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        List<ThCourseReqDTO> courseReqDTOList = new ArrayList<>();
        List<ThCourseReqDTO> courseReqDTOList =
                decryptData(jsonObject, new TypeReference<List<ThCourseReqDTO>>() {},"课程");
//        List<ThCourseReqDTO> courseReqDTOList = new ArrayList<>();
        //反序列化
        try {
            courseReqDTOList = JSONObject.parseObject(decrypt, new TypeReference<List<ThCourseReqDTO>>() {});
        }catch (Exception e){
            logger.error("课程反序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        try {
//            courseReqDTOList = JSONObject.parseObject(decrypt, new TypeReference<List<ThCourseReqDTO>>() {});
//
//        }catch (Exception e){
//            logger.error("课程反序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//
//        }
        if(CollectionUtils.isEmpty(courseReqDTOList)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送不可以为空");
        }
        //暂时不限制不能超过1000条
        //暂时限制不能超过1000条
        if (courseReqDTOList.size() > 1000){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送数据量过大");
        }
        List<String> reqAllCourseIds = new ArrayList<>();
        List<String> reqAllChapterIds = new ArrayList<>();
        List<ThErrorDataRespDTO> errorDataRespDTOS = new ArrayList<>();
@@ -445,22 +437,22 @@
        }
        //数据插入
        //课程插入
        List<List<ThCourse>> splitSaveCourseList = ListUtil.split(saveCourseList, 500);
        List<List<ThCourse>> splitSaveCourseList = ListUtil.split(saveCourseList, 200);
        for(List<ThCourse> courseList : splitSaveCourseList){
            courseService.insertBatch(courseList);
        }
        //修改课程
        List<List<ThCourse>> splitUpdateCourseList = ListUtil.split(updateCourseList, 500);
        List<List<ThCourse>> splitUpdateCourseList = ListUtil.split(updateCourseList, 200);
        for(List<ThCourse> courseList : splitUpdateCourseList){
            courseService.updateBatch(courseList);
        }
        //插入章节
        List<List<ThCourseChapter>> splitSaveChapterList = ListUtil.split(saveCourseChapterList, 500);
        List<List<ThCourseChapter>> splitSaveChapterList = ListUtil.split(saveCourseChapterList, 200);
        for(List<ThCourseChapter> chapterList : splitSaveChapterList){
            courseChapterService.insertBatch(chapterList);
        }
        //修改章节
        List<List<ThCourseChapter>> splitUpdateChapterList = ListUtil.split(updateCourseChapterList, 500);
        List<List<ThCourseChapter>> splitUpdateChapterList = ListUtil.split(updateCourseChapterList, 200);
        for(List<ThCourseChapter> chapterList : splitUpdateChapterList){
            courseChapterService.updateBatch(chapterList);
        }
@@ -472,28 +464,25 @@
    public AjaxResult receiveStudent(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        List<ThStudentReqDTO> studentReqDTOs =
                decryptData(jsonObject, new TypeReference<List<ThStudentReqDTO>>() {},"学员");
        //反序列化
        List<ThStudentReqDTO> studentReqDTOs = new ArrayList<>();
        try {
            studentReqDTOs = JSONObject.parseObject(decrypt, new TypeReference<List<ThStudentReqDTO>>() {});
        }catch (Exception e){
            logger.error("学员序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        List<ThStudentReqDTO> studentReqDTOs = new ArrayList<>();
//        try {
//            studentReqDTOs = JSONObject.parseObject(decrypt, new TypeReference<List<ThStudentReqDTO>>() {});
//        }catch (Exception e){
//            logger.error("学员序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//        }
        //参数校验
        if(CollectionUtils.isEmpty(studentReqDTOs)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"学生信息不可为空");
        }
        //限制数据量不超过1000条
        if (studentReqDTOs.size() > 1000){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送数据量过大");
        }
        List<String> idcardList = new ArrayList<>();
@@ -567,7 +556,7 @@
        List<ThStudentBatch> updateThStudentBatchList = new ArrayList<>();
        for (ThStudentReqDTO studentReqDTO : saveStudentReqDTOList) {
            //学生表中过滤
            List<ThStudent> collect = students.stream().filter(s -> s.getIdcard().equals(studentReqDTO.getIdcard())).collect(Collectors.toList());
            List<ThStudent> collect = students.stream().filter(s -> s.getIdcard().equals(studentReqDTO.getIdcard()) && s.getInstitutionId().equals(institutionUser.getId()) ).collect(Collectors.toList());
            if(collect.size() > 0){
                ThStudent student = collect.get(0);
                //修改
@@ -629,23 +618,23 @@
            }
        }
        //学生表新增
        List<List<ThStudent>> splitSaveStudentList = ListUtil.split(saveSudentList, 500);
        List<List<ThStudent>> splitSaveStudentList = ListUtil.split(saveSudentList, 200);
        for (List<ThStudent> studentList : splitSaveStudentList) {
            studentService.insertBatch(studentList);
        }
        //学生表更新
        List<List<ThStudent>> splitUpdateStudentList = ListUtil.split(updateStudentList, 500);
        List<List<ThStudent>> splitUpdateStudentList = ListUtil.split(updateStudentList, 200);
        for (List<ThStudent> studentList : splitUpdateStudentList) {
            studentService.updateBatch(studentList);
        }
        //学生关联班级表
        List<List<ThStudentBatch>> splitSaveThStudentBatchList = ListUtil.split(saveThStudentBatchList, 500);
        List<List<ThStudentBatch>> splitSaveThStudentBatchList = ListUtil.split(saveThStudentBatchList, 200);
        for (List<ThStudentBatch> studentBatcheList : splitSaveThStudentBatchList) {
            studentBatchService.insertBatch(studentBatcheList);
        }
        //学生关联班级表修改
        List<List<ThStudentBatch>> splitUpdateThStudentBatchList = ListUtil.split(updateThStudentBatchList, 500);
        List<List<ThStudentBatch>> splitUpdateThStudentBatchList = ListUtil.split(updateThStudentBatchList, 200);
        for (List<ThStudentBatch> studentBatcheList : splitUpdateThStudentBatchList) {
            studentBatchService.updateBatch(studentBatcheList);
        }
@@ -662,29 +651,24 @@
    public AjaxResult receiveBatch(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        List<ThBatchReqDTO> batchReqDTOList = decryptData(jsonObject, new TypeReference<List<ThBatchReqDTO>>() {},"班级");
        //反序列化
        List<ThBatchReqDTO> batchReqDTOList = new ArrayList<>();
        try {
            batchReqDTOList = JSONObject.parseObject(decrypt, new TypeReference<List<ThBatchReqDTO>>() {});
        }catch (Exception e){
            logger.error("班级序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        List<ThBatchReqDTO> batchReqDTOList = new ArrayList<>();
//        try {
//            batchReqDTOList = JSONObject.parseObject(decrypt, new TypeReference<List<ThBatchReqDTO>>() {});
//
//        }catch (Exception e){
//            logger.error("班级序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//
//        }
        if(CollectionUtils.isEmpty(batchReqDTOList)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"批次(班级)集合不可为空");
        }
        //限制数据量不超过1000条
        if (batchReqDTOList.size() > 1000){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送数据量过大");
        }
        //过滤出本次请求所有班级课程章节
        List<String> reqAllBatchUuids = new ArrayList<>();
@@ -1257,12 +1241,12 @@
        }
        //插入章节
        List<List<ThBatchCourseChapter>> splitSaveBatchCourseChapterList = ListUtil.split(saveBatchCourseChapterList, 500);
        List<List<ThBatchCourseChapter>> splitSaveBatchCourseChapterList = ListUtil.split(saveBatchCourseChapterList, 200);
        for (List<ThBatchCourseChapter> chapterList : splitSaveBatchCourseChapterList) {
            batchCourseChapterService.insertBatch(chapterList);
        }
        //修改章节
        List<List<ThBatchCourseChapter>> splitUpdateBatchCourseChapterList = ListUtil.split(updateBatchCourseChapterList, 500);
        List<List<ThBatchCourseChapter>> splitUpdateBatchCourseChapterList = ListUtil.split(updateBatchCourseChapterList, 200);
        for (List<ThBatchCourseChapter> chapterList : splitUpdateBatchCourseChapterList) {
            batchCourseChapterService.updateBatch(chapterList);
        }
@@ -1275,28 +1259,23 @@
    public AjaxResult receiveStudyDetail(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        List<ThStudyDetailReqDTO> thStudyDetailReqDTOS = decryptData(jsonObject, new TypeReference<List<ThStudyDetailReqDTO>>() {},"学习记录");
        //反序列化
        List<ThStudyDetailReqDTO> thStudyDetailReqDTOS = new ArrayList<>();
        try {
           thStudyDetailReqDTOS = JSONObject.parseObject(decrypt, new TypeReference<List<ThStudyDetailReqDTO>>() {});
        }catch (Exception e){
            logger.error("学习记录序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        List<ThStudyDetailReqDTO> thStudyDetailReqDTOS = new ArrayList<>();
//        try {
//           thStudyDetailReqDTOS = JSONObject.parseObject(decrypt, new TypeReference<List<ThStudyDetailReqDTO>>() {});
//        }catch (Exception e){
//            logger.error("学习记录序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//        }
        //参数校验
        if(CollectionUtils.isEmpty(thStudyDetailReqDTOS)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"学习记录清单不可为空");
        }
        //限制数据量不超过1000条
        if (thStudyDetailReqDTOS.size() > 1000){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送数据量过大");
        }
        //获取班级学生以及章节
        List<String> chapterUuids = new ArrayList<>();
@@ -1384,20 +1363,20 @@
                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"结束位置不可为空"));
                continue;
            }
            if(StringUtils.isEmpty(studentDetailReqDTO.getLessonReportUrl())){
                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学时报告不可为空"));
                continue;
            }
//            if(StringUtils.isEmpty(studentDetailReqDTO.getLessonReportUrl())){
//                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学时报告不可为空"));
//                continue;
//            }
            //认证记录集合
//            if(CollectionUtils.isEmpty(studentDetailReqDTO.getAuthList())){
//                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"认证记录集合不可为空"));
//                continue;
//            }
            //学习轨迹集合
            if(CollectionUtils.isEmpty(studentDetailReqDTO.getTrackList())){
                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹集合不可为空"));
                continue;
            }
//            if(CollectionUtils.isEmpty(studentDetailReqDTO.getTrackList())){
//                errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹集合不可为空"));
//                continue;
//            }
            /*boolean authFlag = false;
            for(ThStudytAuthReqDTO item : studentDetailReqDTO.getAuthList()){
@@ -1430,32 +1409,32 @@
            if(authFlag){
                continue;
            }*/
            boolean trackFlag = false;
            for(ThStudyTrackReqDTO item : studentDetailReqDTO.getTrackList()){
                if(StringUtils.isEmpty(item.getUuid()) || !UUID.checkIsUuid(item.getUuid())){
                    trackFlag = true;
                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+")不符合规范"));
                    break;
                }
                if(item.getStartTime() == null){
                    trackFlag = true;
                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),轨迹开始时间不可为空"));
                    break;
                }
                if(item.getEndTime() == null){
                    trackFlag = true;
                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),轨迹结束时间不可为空"));
                    break;
                }
                if(item.getTimeInterval() == null) {
                    trackFlag = true;
                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),时间间隔(秒)不可为空"));
                    break;
                }
            }
            if(trackFlag){
                continue;
            }
//            boolean trackFlag = false;
//            for(ThStudyTrackReqDTO item : studentDetailReqDTO.getTrackList()){
//                if(StringUtils.isEmpty(item.getUuid()) || !UUID.checkIsUuid(item.getUuid())){
//                    trackFlag = true;
//                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+")不符合规范"));
//                    break;
//                }
//                if(item.getStartTime() == null){
//                    trackFlag = true;
//                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),轨迹开始时间不可为空"));
//                    break;
//                }
//                if(item.getEndTime() == null){
//                    trackFlag = true;
//                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),轨迹结束时间不可为空"));
//                    break;
//                }
//                if(item.getTimeInterval() == null) {
//                    trackFlag = true;
//                    errorDataRespDTOS.add(new ThErrorDataRespDTO(studentDetailReqDTO.getUuid(),"学习轨迹uuid("+item.getUuid()+"),时间间隔(秒)不可为空"));
//                    break;
//                }
//            }
//            if(trackFlag){
//                continue;
//            }
            saveStudyDetailReqDTOS.add(studentDetailReqDTO);
            //判断需要修改的批次学生
@@ -1552,27 +1531,27 @@
            }
        }
        //插入学习记录
        List<List<ThStudyDetail>> splitSaveDetailList = ListUtil.split(saveStudyDetailList, 500);
        List<List<ThStudyDetail>> splitSaveDetailList = ListUtil.split(saveStudyDetailList, 200);
        for (List<ThStudyDetail> thStudyDetails : splitSaveDetailList) {
            studyDetailService.insertBatch(thStudyDetails);
        }
        //修改学习记录
        List<List<ThStudyDetail>> splitUpdateDetailList = ListUtil.split(updateStudyDetailList, 500);
        List<List<ThStudyDetail>> splitUpdateDetailList = ListUtil.split(updateStudyDetailList, 200);
        for (List<ThStudyDetail> thStudyDetails : splitUpdateDetailList) {
            studyDetailService.updateBatch(thStudyDetails);
        }
        //插入认证记录
        List<List<ThStudyAuth>> splitSaveAuthList = ListUtil.split(saveStudyAuthList, 500);
        List<List<ThStudyAuth>> splitSaveAuthList = ListUtil.split(saveStudyAuthList, 200);
        for (List<ThStudyAuth> thStudyAuths : splitSaveAuthList) {
            studyAuthService.insetBatch(thStudyAuths);
        }
        //插入学习轨迹
        List<List<ThStudyTrack>> splitSaveTrackList = ListUtil.split(saveStudyTrackList, 500);
        List<List<ThStudyTrack>> splitSaveTrackList = ListUtil.split(saveStudyTrackList, 200);
        for (List<ThStudyTrack> thStudyTracks : splitSaveTrackList) {
            studyTrackService.insertBatch(thStudyTracks);
        }
        //修改学生完成状态
        List<List<ThStudentBatch>> splitUpdateThStudentBatchList = ListUtil.split(updateStudentBatchList, 500);
        List<List<ThStudentBatch>> splitUpdateThStudentBatchList = ListUtil.split(updateStudentBatchList, 200);
        for (List<ThStudentBatch> studentBatcheList : splitUpdateThStudentBatchList) {
            studentBatchService.updateBatch(studentBatcheList);
        }
@@ -1584,27 +1563,22 @@
    public AjaxResult receiveExamRecord(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        List<ThExamRecordReqDTO> examRecordReqDTOS = decryptData(jsonObject, new TypeReference<List<ThExamRecordReqDTO>>() {},"考试记录");
        //反序列化
        List<ThExamRecordReqDTO> examRecordReqDTOS = new ArrayList<>();
        try {
            examRecordReqDTOS = JSONObject.parseObject(decrypt, new TypeReference<List<ThExamRecordReqDTO>>() {});
        }catch (Exception e){
            logger.error("考试记录序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        List<ThExamRecordReqDTO> examRecordReqDTOS = new ArrayList<>();
//        try {
//            examRecordReqDTOS = JSONObject.parseObject(decrypt, new TypeReference<List<ThExamRecordReqDTO>>() {});
//        }catch (Exception e){
//            logger.error("考试记录序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//        }
        if (CollectionUtils.isEmpty(examRecordReqDTOS)) {
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"考试记录不可为空");
        }
        //限制数据量不超过1000条
        if (examRecordReqDTOS.size() > 1000){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR,"数据推送数据量过大");
        }
        List<String> idcards = new ArrayList<>();
        //List<String> batchUuids = new ArrayList<>();
@@ -1706,28 +1680,19 @@
    public AjaxResult receiveCourseDelete(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        ThCourseDeleteReqDTO thCourseDeleteReqDTO = decryptData(jsonObject, new TypeReference<ThCourseDeleteReqDTO>() {},"课程删除");
        //反序列化
        ThCourseDeleteReqDTO thCourseDeleteReqDTO = null;
        try {
            thCourseDeleteReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThCourseDeleteReqDTO>() {});
        }catch (Exception e){
            logger.error("课程删除反序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        ThCourseDeleteReqDTO thCourseDeleteReqDTO = null;
//        try {
//            thCourseDeleteReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThCourseDeleteReqDTO>() {});
//
//        }catch (Exception e){
//            logger.error("课程删除反序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//
//        }
        if(thCourseDeleteReqDTO == null){
            throw new BusinessException(ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
@@ -1766,25 +1731,15 @@
    public AjaxResult receiveBatchOpen(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        ThBatchOpenReqDTO thBatchOpenReqDTO = decryptData(jsonObject, new TypeReference<ThBatchOpenReqDTO>() {},"班级开始");
        //反序列化
        ThBatchOpenReqDTO thBatchOpenReqDTO = null;
        try {
            thBatchOpenReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThBatchOpenReqDTO>() {});
        }catch (Exception e){
            logger.error("班级开始反序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
//        ThBatchOpenReqDTO thBatchOpenReqDTO = null;
//        try {
//            thBatchOpenReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThBatchOpenReqDTO>() {});
//        }catch (Exception e){
//            logger.error("班级开始反序列化失败!");
//            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
//        }
        if(thBatchOpenReqDTO == null){
            throw new BusinessException(this.getClass(),ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"批次(班级)不可为空");
        }
@@ -1809,26 +1764,7 @@
    @Override
    public AjaxResult receiveBatchEnd(JSONObject jsonObject) {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //反序列化
        ThBatchEndReqDTO thBatchEndReqDTO = null;
        try {
            thBatchEndReqDTO = JSONObject.parseObject(decrypt, new TypeReference<ThBatchEndReqDTO>() {});
        }catch (Exception e){
            logger.error("班级结束反序列化失败!");
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
        ThBatchEndReqDTO thBatchEndReqDTO = decryptData(jsonObject, new TypeReference<ThBatchEndReqDTO>() {},"批次(班级)");
        if(thBatchEndReqDTO == null){
            throw new BusinessException(this.getClass(),ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"批次(班级)不可为空");
        }
@@ -1848,6 +1784,99 @@
        return AjaxResult.success();
    }
    @Override
    public AjaxResult receiveCerts(JSONObject jsonObject) throws Exception {
        InstitutionUser institutionUser = ThreeInContextHolder.getContext();
        List<ThCertReqDTO> thCertReqDTOs = decryptData(jsonObject, new TypeReference<List<ThCertReqDTO>>() {},"学时证书");
        if(thCertReqDTOs.isEmpty() ||thCertReqDTOs.size()>50){
            throw new BusinessException(this.getClass(), ResultConstants.RECORD_OVER_MAX);
        }
        //错误
        List<ThErrorDataRespDTO> errorDataRespDTOS = new ArrayList<>();
        List<ThCertReqDTO> saveCertReqDTOList = new ArrayList<>();
        List<String> batchUuidList=thCertReqDTOs.stream().map(ThCertReqDTO::getBatchUuid).filter(batchUuid -> !StringUtils.isEmpty(batchUuid)).distinct().collect(Collectors.toList());
        //获取批次
        List<ThBatch> batchList = batchService.getByUuids(batchUuidList);
        for(ThCertReqDTO thCertReqDTO : thCertReqDTOs){
            String validateMessage=ValidatorUtils.validateFast(thCertReqDTO);
            if(!StringUtils.isEmpty(validateMessage)){
                errorDataRespDTOS.add(new ThErrorDataRespDTO(thCertReqDTO.getUuid(),validateMessage));
                continue;
            }
            List<ThBatch> collect = batchList.stream().filter(batchCourse -> batchCourse.getUuid().equals(thCertReqDTO.getBatchUuid())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(collect)) {
                errorDataRespDTOS.add(new ThErrorDataRespDTO(thCertReqDTO.getUuid(), "批次(班级)不存在,请先添加批次(班级)"));
                continue;
            }
            saveCertReqDTOList.add(thCertReqDTO);
        }
        List<ThCert> saveCertList = new ArrayList<>();
        List<ThCert> updateCertList = new ArrayList<>();
        for (ThCertReqDTO thCertReqDTO : saveCertReqDTOList) {
            ThCert cert=certService.getCertByUuid(thCertReqDTO.getUuid());
            if (cert!=null) {
                //修改
                BeanUtils.copyProperties(thCertReqDTO, cert);
                cert.setUpdateBy(institutionUser.getInstitutionalName());
                cert.setUpdateTime(LocalDateTime.now());
                cert.setInstitutionId(institutionUser.getId());
                cert.setInstitutionName(institutionUser.getInstitutionalName());
                if (cert.getDelFlag()==null) {
                    cert.setDelFlag(DeleteStatusEnum.NO.getStatus());
                }
                updateCertList.add(cert);
            } else {
                //新增
                cert = new ThCert();
                BeanUtils.copyProperties(thCertReqDTO, cert);
                cert.setId(IdUtil.getSnowflake(0, 0).nextId());
                cert.setUpdateBy(institutionUser.getInstitutionalName());
                cert.setUpdateTime(LocalDateTime.now());
                cert.setCreateBy(institutionUser.getInstitutionalName());
                cert.setCreateTime(LocalDateTime.now());
                cert.setInstitutionId(institutionUser.getId());
                cert.setInstitutionName(institutionUser.getInstitutionalName());
                cert.setDelFlag(DeleteStatusEnum.NO.getStatus());
                saveCertList.add(cert);
            }
        }
        //课时证书表新增
        if(!saveCertList.isEmpty()){
            certService.insertBatch(saveCertList);
        }
        //课时证书表更新
        if(!updateCertList.isEmpty()) {
            certService.updateBatch(updateCertList);
        }
        return AjaxResult.success(errorDataRespDTOS);
    }
    /**
     * 解密数据
     * @param jsonObject
     * @param typeReference
     * @return
     * @param <T>
     */
    private <T> T decryptData(JSONObject jsonObject,TypeReference<T> typeReference,String type){
        String data = jsonObject.getString("data");
        if(StringUtils.isEmpty(data)){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        //解密
        String decrypt = "";
        try {
            decrypt = AESUtils.decrypt(data);
        }catch (Exception e){
            throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL);
        }
        try {
            return JSONObject.parseObject(decrypt,typeReference);
        }catch (Exception e){
            logger.error("{}反序列化失败!",type);
            throw new BusinessException(this.getClass(), ResultConstants.SERIALIZE_ERROR);
        }
    }
    private void validateStudyDetail(ThStudyDetailReqDTO studentDetailReqDTO) {
@@ -2075,43 +2104,7 @@
    }
    /**
     * 校验题库组卷数据
     * @param questionBankReqDTO
     */
     private void validateQuestion(ThQuestionBankReqDTO questionBankReqDTO){
         if(questionBankReqDTO == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_ERROR);
         }
         if(StringUtils.isEmpty(questionBankReqDTO.getUuid()) || !UUID.checkIsUuid(questionBankReqDTO.getUuid())){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"题库组卷uuid不符合规范");
         }
         if(StringUtils.isEmpty(questionBankReqDTO.getUrl())){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"题库组卷预览路径不可为空");
         }
         if(questionBankReqDTO.getLastMonthCount() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"上月题库总题目数不可为空");
         }
         if(questionBankReqDTO.getAddCount() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"新增题目数不可为空");
         }
         if(questionBankReqDTO.getReduceCount() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"减少题目数不可为空");
         }
         if(questionBankReqDTO.getBrushRate() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"刷题应用率不可为空");
         }
         if(questionBankReqDTO.getAssemblyRate() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"组卷应用率不可为空");
         }
         if(questionBankReqDTO.getMonth() == null){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"年月不可为空");
         }
         if(questionBankReqDTO.getDelFlag() == null || DeleteStatusEnum.getDeleteStatusEnum(questionBankReqDTO.getDelFlag()) == null ){
             throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL,"删除标识不符合规范");
         }
    }
    private String generateSerialNum() {
        Long count = studyDetailService.getCount();
        String strCount = count.toString();