Browse Source

3.4.2 update

xiaofei 7 months ago
parent
commit
6594b41de6

+ 0 - 8
distributed-print-business/src/main/resources/db/log/wl.sql

@@ -1,8 +0,0 @@
--- 2024-10-24
-INSERT INTO sys_privilege
-(id, name, url, `type`, parent_id, `sequence`, property, related, enable, default_auth, front_display)
-VALUES(2114, '试卷清除信息', '/api/admin/course/degree/final_score/paper_struct/clear', 'URL', 2006, 1, 'AUTH', NULL, 1, 1, 1);
-
-UPDATE sys_privilege
-SET name='管理成绩', url='Score', `type`='LINK', parent_id=2001, `sequence`=1, property='AUTH', related='2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2029,2030,2031,2032,2033,2034,3018,2111,2114', enable=1, default_auth=0, front_display=1
-WHERE id=2006;

+ 15 - 13
distributed-print/install/mysql/init/teachcloud_db.sql

@@ -1994,6 +1994,20 @@ CREATE TABLE IF NOT EXISTS `obe_course_outline` (
   UNIQUE KEY `obe_course_outline_unique` (`culture_program_id`,`course_id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程大纲表';
 
+-- ----------------------------
+-- Table structure for obe_course_outline_audit_report
+-- ----------------------------
+CREATE TABLE `obe_course_outline_audit_report`  (
+    `id` bigint NOT NULL,
+    `course_outline_id` bigint NOT NULL,
+    `weight_setting_sign` bigint NULL DEFAULT NULL COMMENT '课程权重设置标识',
+    `course_basic_info` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '课程基础信息',
+    `course_target_info` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '课程目标情况',
+    `rationality_evaluation` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '合理性评价',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '课程目标达成情况评价依据合理性审核表';
+
+
 -- ----------------------------
 -- Table structure for obe_course_requirement_dimension
 -- ----------------------------
@@ -2029,19 +2043,6 @@ CREATE TABLE IF NOT EXISTS `obe_course_requirement_matrix` (
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='培养方案毕业要求支撑矩阵';
 
--- ----------------------------
--- Table structure for obe_course_outline_audit_report
--- ----------------------------
-CREATE TABLE `obe_course_outline_audit_report`  (
-      `id` bigint NOT NULL COMMENT '主键',
-      `culture_program_id` bigint NOT NULL COMMENT '培养方案id',
-      `requirement_radar` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '毕业要求雷达报表',
-      `requirement_detail` mediumtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '毕业要求详情报表',
-      `requirement_degree` double NOT NULL COMMENT '毕业要求达成值',
-      PRIMARY KEY (`id`) USING BTREE,
-      UNIQUE INDEX `obe_course_requirement_report_unique`(`culture_program_id` ASC) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '课程毕业要求报表';
-
 -- ----------------------------
 -- Table structure for obe_course_requirement_report
 -- ----------------------------
@@ -3439,6 +3440,7 @@ INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (879, '作废', '/api/admin/exam/task/cancel', 'URL', 42, 8, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (880, '重启流程', '/api/admin/exam/task/restart', 'URL', 42, 9, 'AUTH', NULL, 1, 1, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (881, '打回', 'Restart', 'LINK', 42, 6, 'AUTH', '880', 1, 0, 1);
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (882, '是否开启AB卷', 'OpenAb', 'BUTTON', 40, 13, 'AUTH', NULL, 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (884, '列表', 'List', 'LIST', 491, 1, 'AUTH', '887', 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (885, '查询', 'Select', 'BUTTON', 491, 2, 'AUTH', '887', 1, 0, 1);
 INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (886, '点击评卷', 'Marking', 'LINK', 491, 3, 'AUTH', '888,889,890,891,892,893,894,895,896', 1, 0, 1);

+ 3 - 0
distributed-print/install/mysql/upgrade/3.4.2.sql

@@ -115,3 +115,6 @@ VALUES(2114, '试卷清除信息', '/api/admin/course/degree/final_score/paper_s
 UPDATE sys_privilege
 SET name='管理成绩', url='Score', `type`='LINK', parent_id=2001, `sequence`=1, property='AUTH', related='2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2029,2030,2031,2032,2033,2034,3018,2111,2114', enable=1, default_auth=0, front_display=1
 WHERE id=2006;
+
+INSERT INTO `sys_privilege` (`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `enable`, `default_auth`, `front_display`) VALUES ('882', '是否开启AB卷', 'OpenAb', 'BUTTON', '40', '13', 'AUTH', '1', '0', '1');
+

+ 215 - 0
distributed-print/src/test/java/com/qmth/distributed/print/DealExamTaskDetailDataTest.java

@@ -0,0 +1,215 @@
+package com.qmth.distributed.print;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.qmth.distributed.print.business.entity.ExamDetailCourse;
+import com.qmth.distributed.print.business.entity.ExamTask;
+import com.qmth.distributed.print.business.entity.ExamTaskDetail;
+import com.qmth.distributed.print.business.service.ExamDetailCourseService;
+import com.qmth.distributed.print.business.service.ExamTaskDetailService;
+import com.qmth.distributed.print.business.service.ExamTaskService;
+import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
+import com.qmth.teachcloud.common.contant.SystemConstant;
+import com.qmth.teachcloud.common.entity.MarkQuestion;
+import com.qmth.teachcloud.mark.entity.*;
+import com.qmth.teachcloud.mark.service.*;
+import io.swagger.models.auth.In;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.BeanUtils;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * 处理命题任务详情数据
+ * <p>
+ * 升级3.4.2后,增加了备用卷概念,数据需要处理
+ * 客观题标签单独保存
+ */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class DealExamTaskDetailDataTest {
+    @Resource
+    ExamTaskService examTaskService;
+    @Resource
+    ExamTaskDetailService examTaskDetailService;
+    @Resource
+    MarkQuestionService markQuestionService;
+    @Resource
+    MarkQuestionAnswerService markQuestionAnswerService;
+    @Resource
+    ExamDetailCourseService examDetailCourseService;
+    @Resource
+    MarkPaperService markPaperService;
+    @Resource
+    MarkPaperPackageService markPaperPackageService;
+    @Resource
+    MarkStudentService markStudentService;
+    @Resource
+    ScanAnswerCardService scanAnswerCardService;
+
+    private static String DEFAULT_A = "A";
+
+    @Test
+    public void deal() {
+        List<ExamTaskDetail> examTaskDetailList = new ArrayList<>();
+        // 拆分电子交卷试卷
+        for (ExamTaskDetail examTaskDetail : examTaskDetailList()) {
+            ExamTask examTask = examTaskService.getById(examTaskDetail.getExamTaskId());
+            if(examTask == null){
+                continue;
+            }
+            String paperType = examTaskDetail.getPaperType();
+            // 所有卷型
+            String[] paperTypes = paperType.split(",");
+            // 已曝光集合
+            String exposedPaperType = examTaskDetail.getExposedPaperType();
+            List<String> exposePaperTypes = StringUtils.isNotBlank(exposedPaperType) ? Arrays.asList(exposedPaperType.split(",")) : Collections.emptyList();
+            // 已关联集合
+            String relatePaperType = examTaskDetail.getRelatePaperType();
+            List<String> relatePaperTypes = StringUtils.isNotBlank(relatePaperType) ? Arrays.asList(relatePaperType.split(",")) : Collections.emptyList();
+            // 所有上传卷型试卷信息
+            List<PaperInfoVo> paperInfoVoList = examTaskDetail.getPaperInfoVoList();
+            // 只有一个卷型,不处理
+            if (paperType.length() == 1) {
+                examTaskDetail.setExposed(exposePaperTypes.contains(paperType));
+                examTaskDetail.setExposedExamId(examTaskDetail.getExposed() || relatePaperTypes.contains(paperType) ? examTask.getExamId() : null);
+                examTaskDetailList.add(examTaskDetail);
+            } else {
+                for (String type : paperTypes) {
+                    // 暂时不处理A
+                    if (type.equals(DEFAULT_A)) {
+                        continue;
+                    }
+                    ExamTaskDetail taskDetail = new ExamTaskDetail();
+                    taskDetail.setId(SystemConstant.getDbUuid());
+                    taskDetail.setExamTaskId(examTaskDetail.getExamTaskId());
+                    taskDetail.setSerialNumber(calcSerialNumber(type));
+                    taskDetail.setPaperType(DEFAULT_A);
+                    taskDetail.setPaperAttachmentIds(getPaperTypeIds(paperInfoVoList, type));
+                    taskDetail.setExposed(exposePaperTypes.contains(type));
+                    taskDetail.setExposedExamId(taskDetail.getExposed() || relatePaperTypes.contains(type) ? examTask.getExamId() : null);
+                    taskDetail.setCreateId(examTaskDetail.getCreateId());
+                    taskDetail.setCreateTime(examTaskDetail.getCreateTime());
+                    taskDetail.setUpdateId(examTaskDetail.getUpdateId());
+                    taskDetail.setUpdateTime(examTaskDetail.getUpdateTime());
+                    examTaskDetailList.add(taskDetail);
+
+                }
+
+                // 最后处理A卷,将原数据改为A
+                examTaskDetail.setSerialNumber(1);
+                examTaskDetail.setPaperType(DEFAULT_A);
+                examTaskDetail.setPaperAttachmentIds(getPaperTypeIds(paperInfoVoList, DEFAULT_A));
+                examTaskDetail.setExposed(exposePaperTypes.contains(DEFAULT_A));
+                examTaskDetail.setExposedExamId(examTaskDetail.getExposed() || relatePaperTypes.contains(DEFAULT_A) ? examTask.getExamId() : null);
+                examTaskDetailList.add(examTaskDetail);
+            }
+        }
+        examTaskDetailService.saveOrUpdateBatch(examTaskDetailList);
+
+        // 更新exam_detail_course表serial_number
+        updateExamDetailCourseSerialNumber();
+        // 更新mark_paper表serial_number
+        updateMarkPaperSerialNumber();
+        // 更新mark_paper_package表serial_number
+        updateMarkPaperPackageSerialNumber();
+        // 更新mark_student表serial_number
+        updateMarkStudentSerialNumber();
+        // 更新scan_answer_card表serial_number
+        updateScanAnswerCardSerialNumber();
+
+        // 拆分客观题标答
+        List<MarkQuestionAnswer> markQuestionAnswerList = new ArrayList<>();
+        for (MarkQuestion markQuestion : markQuestionList()) {
+            MarkQuestionAnswer markQuestionAnswer = new MarkQuestionAnswer(markQuestion.getExamId(), markQuestion.getPaperNumber(), markQuestion.getPaperType(), markQuestion.getMainNumber(), markQuestion.getSubNumber());
+            markQuestionAnswer.setAnswer(markQuestion.getAnswer());
+            markQuestionAnswer.setObjectivePolicy(markQuestion.getObjectivePolicy());
+            markQuestionAnswer.setObjectivePolicyScore(markQuestion.getObjectivePolicyScore());
+            markQuestionAnswerList.add(markQuestionAnswer);
+        }
+        if (CollectionUtils.isNotEmpty(markQuestionAnswerList)) {
+            markQuestionAnswerService.saveBatch(markQuestionAnswerList);
+        }
+    }
+
+    private void updateScanAnswerCardSerialNumber() {
+        UpdateWrapper<ScanAnswerCard> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.setSql("serial_number = case paper_type when 'A' then 1 when 'B' then 2 when 'C' then 3 when 'D' then 4 when 'E' then 5 when 'F' then 6 when 'G' then 7 end");
+        updateWrapper.isNull("serial_number");
+        scanAnswerCardService.update(updateWrapper);
+    }
+
+    private void updateMarkStudentSerialNumber() {
+        UpdateWrapper<MarkStudent> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.setSql("serial_number = case paper_type when 'A' then 1 when 'B' then 2 when 'C' then 3 when 'D' then 4 when 'E' then 5 when 'F' then 6 when 'G' then 7 end");
+        updateWrapper.isNull("serial_number");
+        markStudentService.update(updateWrapper);
+    }
+
+    private void updateMarkPaperPackageSerialNumber() {
+        UpdateWrapper<MarkPaperPackage> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.setSql("serial_number = case paper_type when 'A' then 1 when 'B' then 2 when 'C' then 3 when 'D' then 4 when 'E' then 5 when 'F' then 6 when 'G' then 7 end");
+        updateWrapper.isNull("serial_number");
+        markPaperPackageService.update(updateWrapper);
+    }
+
+    private void updateMarkPaperSerialNumber() {
+        UpdateWrapper<MarkPaper> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.setSql("serial_number = case paper_type when 'A' then 1 when 'B' then 2 when 'C' then 3 when 'D' then 4 when 'E' then 5 when 'F' then 6 when 'G' then 7 end");
+        updateWrapper.isNull("serial_number");
+        markPaperService.update(updateWrapper);
+    }
+
+    private void updateExamDetailCourseSerialNumber() {
+        UpdateWrapper<ExamDetailCourse> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.setSql("serial_number = case paper_type when 'A' then 1 when 'B' then 2 when 'C' then 3 when 'D' then 4 when 'E' then 5 when 'F' then 6 when 'G' then 7 end");
+        updateWrapper.isNull("serial_number");
+        examDetailCourseService.update(updateWrapper);
+    }
+
+    /**
+     * 获取需要拆分数据的命题试卷
+     */
+    private List<ExamTaskDetail> examTaskDetailList() {
+        // paper_attachment_ids为null,是3.4.2增加AB卷没传值
+        QueryWrapper<ExamTaskDetail> queryWrapper = new QueryWrapper<>();
+        queryWrapper.isNotNull("paper_confirm_attachment_ids");
+        return examTaskDetailService.list(queryWrapper);
+    }
+
+    /**
+     * 获取所有客观题试卷结构
+     */
+    private List<MarkQuestion> markQuestionList() {
+        // 所有客观题标答,都拆分出来单独存表
+        QueryWrapper<MarkQuestion> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(MarkQuestion::getObjective, true)
+                .orderByAsc(MarkQuestion::getExamId, MarkQuestion::getPaperNumber);
+        return markQuestionService.list(queryWrapper);
+    }
+
+    private String getPaperTypeIds(List<PaperInfoVo> paperInfoVoList, String oldPaperType) {
+        PaperInfoVo paperInfoVo = paperInfoVoList.stream().filter(m -> m.getName().equals(oldPaperType)).findFirst().get();
+        paperInfoVo.setName("A");
+
+        List<PaperInfoVo> list = new ArrayList<>();
+        list.add(paperInfoVo);
+        return JSON.toJSONString(list);
+    }
+
+    private Integer calcSerialNumber(String paperType) {
+        String[] letter = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"};
+        List<String> letterList = Arrays.asList(letter);
+        return letterList.indexOf(paperType) + 1;
+    }
+}

+ 30 - 30
teachcloud-common/src/main/java/com/qmth/teachcloud/common/entity/MarkQuestion.java

@@ -54,9 +54,9 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     @ApiModelProperty(value = "大题名称")
     private String mainTitle;
 
-//    @ApiModelProperty(value = "正确答案")
-//    @TableField(updateStrategy = FieldStrategy.IGNORED)
-//    private String answer;
+    @ApiModelProperty(value = "正确答案")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String answer;
     @ApiModelProperty(value = "客观题答案数量")
     private Integer optionCount;
 
@@ -67,13 +67,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     @TableField(updateStrategy = FieldStrategy.IGNORED)
     private Double intervalScore;
 
-//    @ApiModelProperty(value = "客观题判分策略")
-//    @TableField(updateStrategy = FieldStrategy.IGNORED)
-//    private ObjectivePolicy objectivePolicy;
+    @ApiModelProperty(value = "客观题判分策略")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private ObjectivePolicy objectivePolicy;
 
-//    @ApiModelProperty(value = "客观题判分策略计分")
-//    @TableField(updateStrategy = FieldStrategy.IGNORED)
-//    private Double objectivePolicyScore;
+    @ApiModelProperty(value = "客观题判分策略计分")
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private Double objectivePolicyScore;
 
     @ApiModelProperty(value = "题型")
     private Integer questionType;
@@ -143,13 +143,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     public void setMainTitle(String mainTitle) {
         this.mainTitle = mainTitle;
     }
-//    public String getAnswer() {
-//        return answer;
-//    }
-//
-//    public void setAnswer(String answer) {
-//        this.answer = answer;
-//    }
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
 
     public Integer getOptionCount() {
         return optionCount;
@@ -173,13 +173,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
     public void setIntervalScore(Double intervalScore) {
         this.intervalScore = intervalScore;
     }
-//    public ObjectivePolicy getObjectivePolicy() {
-//        return objectivePolicy;
-//    }
-//
-//    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
-//        this.objectivePolicy = objectivePolicy;
-//    }
+    public ObjectivePolicy getObjectivePolicy() {
+        return objectivePolicy;
+    }
+
+    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
+        this.objectivePolicy = objectivePolicy;
+    }
     public Integer getQuestionType() {
         return questionType;
     }
@@ -233,13 +233,13 @@ public class MarkQuestion extends BaseEntity implements Serializable {
         "}";
     }
 
-//    public Double getObjectivePolicyScore() {
-//        return objectivePolicyScore;
-//    }
-//
-//    public void setObjectivePolicyScore(Double objectivePolicyScore) {
-//        this.objectivePolicyScore = objectivePolicyScore;
-//    }
+    public Double getObjectivePolicyScore() {
+        return objectivePolicyScore;
+    }
+
+    public void setObjectivePolicyScore(Double objectivePolicyScore) {
+        this.objectivePolicyScore = objectivePolicyScore;
+    }
 
     @Override
     public boolean equals(Object o) {