1
0
Эх сурвалжийг харах

创建评卷分组接口、分组数量查询接口、清空评卷分组接口、绑定评卷员接口;

ting.yin 3 жил өмнө
parent
commit
758c57036f

+ 25 - 4
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamQuestion.java

@@ -1,12 +1,21 @@
 package cn.com.qmth.stmms.biz.exam.model;
 
-import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
-
-import javax.persistence.*;
 import java.io.Serializable;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
+import cn.com.qmth.stmms.common.enums.QuestionType;
+
 @Entity
 @Table(name = "eb_exam_question")
 public class ExamQuestion implements Serializable {
@@ -51,12 +60,16 @@ public class ExamQuestion implements Serializable {
     private Double intervalScore;
 
     /**
-     * 客观题判分策略(1-平均,2-最高,3-最低)
+     * 客观题判分策略
      */
     @Column(name = "objective_policy", nullable = true)
     @Enumerated(EnumType.STRING)
     private ObjectivePolicy objectivePolicy;
 
+    @Column(name = "question_type", nullable = true)
+    @Enumerated(EnumType.ORDINAL)
+    private QuestionType type;
+
     @Transient
     private ExamSubject subject;
 
@@ -287,4 +300,12 @@ public class ExamQuestion implements Serializable {
         this.selective = selective;
     }
 
+    public QuestionType getType() {
+        return type;
+    }
+
+    public void setType(QuestionType type) {
+        this.type = type;
+    }
+
 }

+ 2 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/UserService.java

@@ -26,4 +26,6 @@ public interface UserService {
 
     User externalSaveAndUpdate(Integer schoolId, String account, String name, String password, Role role);
 
+    User findByAccount(Integer schoolId, String account);
+
 }

+ 5 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/user/service/impl/UserServiceImpl.java

@@ -196,4 +196,9 @@ public class UserServiceImpl implements UserService {
         return userDao.save(user);
     }
 
+    @Override
+    public User findByAccount(Integer schoolId, String account) {
+        return userDao.findFirstBySchoolIdAndRelatedAccount(schoolId, account);
+    }
+
 }

+ 35 - 0
stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/QuestionType.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.stmms.common.enums;
+
+/**
+ * 题型
+ * 
+ */
+public enum QuestionType {
+    SINGLE("单选", 1), MULTIPLE("多选", 2), TRUR_OR_FALSE("判断", 3);
+
+    private String name;
+
+    private int value;
+
+    private QuestionType(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static QuestionType findByValue(int value) {
+        for (QuestionType c : QuestionType.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 11 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/ObjectiveQuestionDTO.java

@@ -34,6 +34,9 @@ public class ObjectiveQuestionDTO implements QuestionDTO {
     @ExcelField(title = "小题满分", align = 2, sort = 80)
     private Double totalScore;
 
+    @ExcelField(title = "题型(1-单选,2-多选,3-判断)", align = 2, sort = 90)
+    private Integer question;
+
     public ObjectiveQuestionDTO() {
 
     }
@@ -131,4 +134,12 @@ public class ObjectiveQuestionDTO implements QuestionDTO {
         this.paperType = paperType;
     }
 
+    public Integer getQuestion() {
+        return question;
+    }
+
+    public void setQuestion(Integer question) {
+        this.question = question;
+    }
+
 }

+ 10 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/dto/SubjectQuestionDTO.java

@@ -15,6 +15,7 @@ import org.apache.commons.lang.StringUtils;
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
+import cn.com.qmth.stmms.common.enums.QuestionType;
 import cn.com.qmth.stmms.common.utils.BigDecimalUtils;
 
 public class SubjectQuestionDTO {
@@ -140,7 +141,15 @@ public class SubjectQuestionDTO {
                         error.add("[" + subjectCode + "] 有答案为空的记录");
                         return false;
                     }
-
+                    if (objective && question.getType() == null) {
+                        error.add("[" + subjectCode + "] 大题号" + question.getMainNumber() + "有题型为空的记录");
+                        return false;
+                    }
+                    if (QuestionType.TRUR_OR_FALSE.equals(question.getType())
+                            && (!question.getAnswer().contains("A") && !question.getAnswer().contains("B"))) {
+                        error.add("[" + subjectCode + "] 大题号" + question.getMainNumber() + "有判断题标答不为A或B的记录");
+                        return false;
+                    }
                     String title = titleMap.get(question.getMainNumber());
                     if (title != null && !title.equals(question.getMainTitle())) {
                         error.add("[" + subjectCode + "] 大题号" + question.getMainNumber() + "有名称不一致的记录");

+ 3 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/AnswerCheckController.java

@@ -173,8 +173,9 @@ public class AnswerCheckController extends BaseExamController {
                 obj.accumulate("subNumber", q != null ? q.getSubNumber() : 0);
                 obj.accumulate("answer", answer);
                 obj.accumulate("exist", q != null && q.getTotalScore() > 0);
-                obj.accumulate("multi",
-                        q != null && (q.getMainTitle().contains("多选") || q.getMainTitle().contains("多项选择")));
+                // obj.accumulate("multi",
+                // q != null && (q.getMainTitle().contains("多选") ||
+                // q.getMainTitle().contains("多项选择")));
                 array.add(obj);
                 if (q != null) {
                     titles.put(q.getMainNumber(), q.getMainTitle());

+ 167 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/CoreController.java

@@ -1,5 +1,6 @@
 package cn.com.qmth.stmms.api.controller;
 
+import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -13,6 +14,8 @@ import net.sf.json.JSONObject;
 
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.core.task.AsyncTaskExecutor;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -20,7 +23,10 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import cn.com.qmth.stmms.admin.thread.MarkGroupDeleteThread;
+import cn.com.qmth.stmms.api.dto.GroupDTO;
 import cn.com.qmth.stmms.api.dto.PaperDTO;
+import cn.com.qmth.stmms.api.dto.PaperStructureDTO;
 import cn.com.qmth.stmms.api.dto.QuestionDTO;
 import cn.com.qmth.stmms.api.exception.ApiException;
 import cn.com.qmth.stmms.biz.exam.model.Exam;
@@ -28,13 +34,17 @@ import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
 import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
 import cn.com.qmth.stmms.biz.exam.service.ExamService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
 import cn.com.qmth.stmms.biz.file.service.FileService;
+import cn.com.qmth.stmms.biz.lock.LockService;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
 import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.biz.user.service.UserService;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
@@ -42,6 +52,7 @@ import cn.com.qmth.stmms.common.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.domain.ApiUser;
 import cn.com.qmth.stmms.common.enums.ExamStatus;
 import cn.com.qmth.stmms.common.enums.ExamType;
+import cn.com.qmth.stmms.common.enums.LockType;
 import cn.com.qmth.stmms.common.enums.ObjectiveStatus;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.enums.SubjectiveStatus;
@@ -81,6 +92,19 @@ public class CoreController extends BaseApiController {
     @Autowired
     private MarkGroupService groupService;
 
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Autowired
+    private LockService lockService;
+
+    @Qualifier("task-executor")
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
     @RequestMapping(value = "/exam/save", method = RequestMethod.POST)
     @ResponseBody
     @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV })
@@ -626,4 +650,147 @@ public class CoreController extends BaseApiController {
         }
         return false;
     }
+
+    @RequestMapping(value = "/exam/mark_group/delete", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    public JSONObject groupDelete(HttpServletRequest request, @RequestParam Integer examId,
+            @RequestParam String subjectCode) {
+        ApiUser user = RequestUtils.getApiUser(request);
+        JSONObject result = new JSONObject();
+        // 输入字段预处理并初步校验
+        Exam exam = examService.findById(examId);
+        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || exam.getStatus() != ExamStatus.START) {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+        subjectCode = validate("subjectCode", subjectCode, true, 64);
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
+        }
+        List<MarkGroup> groups = groupService.findByExamAndSubject(examId, subjectCode);
+        for (MarkGroup markGroup : groups) {
+            if (markGroup.getMarkedCount() > 0) {
+                throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subject is marking");
+            }
+        }
+        for (MarkGroup group : groups) {
+            if (lockService
+                    .trylock(LockType.GROUP_DELETE, group.getExamId(), group.getSubjectCode(), group.getNumber())) {
+                taskExecutor.submit(new MarkGroupDeleteThread(group, markService, lockService));
+            }
+        }
+        result.accumulate("updateTime", DateUtils.formatDateTime(new Date()));
+        return result;
+    }
+
+    @RequestMapping(value = "/exam/mark_group/count", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    public JSONObject groupCount(HttpServletRequest request, @RequestParam Integer examId,
+            @RequestParam String subjectCode) {
+        ApiUser user = RequestUtils.getApiUser(request);
+        JSONObject result = new JSONObject();
+        // 输入字段预处理并初步校验
+        Exam exam = examService.findById(examId);
+        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || exam.getStatus() != ExamStatus.START) {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+        subjectCode = validate("subjectCode", subjectCode, true, 64);
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
+        }
+        result.accumulate("totalCount", groupService.countByExamAndSubject(examId, subjectCode));
+        return result;
+    }
+
+    @RequestMapping(value = "/exam/mark_group/save", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    public JSONObject groupSave(HttpServletRequest request, @RequestBody PaperStructureDTO dto) {
+        ApiUser user = RequestUtils.getApiUser(request);
+        JSONObject result = new JSONObject();
+        // 输入字段预处理并初步校验
+        Exam exam = examService.findById(dto.getExamId());
+        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || exam.getStatus() != ExamStatus.START) {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+        String subjectCode = validate("subjectCode", dto.getSubjectCode(), true, 64);
+        ExamSubject subject = subjectService.find(dto.getExamId(), subjectCode);
+        if (subject == null) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
+        }
+        long count = groupService.countByExamAndSubject(dto.getExamId(), subjectCode);
+        if (count != 0) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
+        }
+        for (GroupDTO g : dto.getGroups()) {
+            List<ExamQuestion> questionGroup = new ArrayList<ExamQuestion>();
+            BigDecimal totalScore = BigDecimal.ZERO;
+            for (QuestionDTO q : g.getQuestions()) {
+                ExamQuestion old = questionService.findByExamAndSubjectAndObjectiveAndMainNumberAndSubNumber(
+                        dto.getExamId(), dto.getSubjectCode(), false, q.getMainNumber(), q.getSubNumber());
+                if (old == null) {
+                    throw ApiException.QUERY_PARAM_ERROR.appendMessage(": question error");
+                }
+                totalScore = totalScore.add(BigDecimal.valueOf(old.getTotalScore()));
+                old.setGroupNumber(g.getNumber());
+                questionGroup.add(old);
+            }
+            MarkGroup group = new MarkGroup(dto.getExamId(), dto.getSubjectCode(), g.getNumber(), g.getPicConfig(),
+                    totalScore.doubleValue(), g.getDoubleRate(), g.getArbitrateThreshold(), g.getScorePolicy(),
+                    g.getMarkMode(), dto.getTrialCount(), false, g.getEnableAllZero(), null, false);
+            if (!questionGroup.isEmpty()) {
+                questionService.save(questionGroup);
+                groupService.save(group);
+            }
+        }
+        subjectService.updateTrialCount(dto.getExamId(), dto.getSubjectCode(), dto.getTrialCount());
+        studentService.updateSubjectiveStatusAndScoreAndInspectorId(dto.getExamId(), dto.getSubjectCode(),
+                SubjectiveStatus.UNMARK, 0, null, null, null);
+        result.accumulate("updateTime", DateUtils.formatDateTime(new Date()));
+        return result;
+    }
+
+    @RequestMapping(value = "/exam/marker/save", method = RequestMethod.POST)
+    @ResponseBody
+    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCHOOL_DEV, Role.SUBJECT_HEADER })
+    public JSONObject markerSave(HttpServletRequest request, @RequestParam Integer examId,
+            @RequestParam String subjectCode, @RequestParam Integer groupNumber, @RequestParam String account) {
+        ApiUser user = RequestUtils.getApiUser(request);
+        JSONObject result = new JSONObject();
+        // 输入字段预处理并初步校验
+        account = validate("account", account, true, 32);
+        Exam exam = examService.findById(examId);
+        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || exam.getStatus() != ExamStatus.START) {
+            throw ApiException.EXAM_NOT_ACCESSIBLED;
+        }
+        subjectCode = validate("subjectCode", subjectCode, true, 64);
+        ExamSubject subject = subjectService.find(examId, subjectCode);
+        if (subject == null) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": subjectCode error");
+        }
+        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
+        if (group == null) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": groupNumber error");
+        }
+        User u = userService.findByAccount(user.getSchoolId(), account);
+        if (u == null || !Role.MARKER.equals(u.getRole())) {
+            throw ApiException.QUERY_PARAM_ERROR.appendMessage(": account error");
+        }
+        Marker marker = markerService.findByExamAndSubjectAndNumberAndUserId(examId, subjectCode, groupNumber,
+                u.getId());
+        if (marker == null) {
+            marker = new Marker();
+            marker.setExamId(examId);
+            marker.setSubjectCode(subjectCode);
+            marker.setGroupNumber(groupNumber);
+            marker.setUserId(u.getId());
+            marker.setEnable(true);
+            markerService.save(marker);
+        }
+        result.accumulate("updateTime", DateUtils.formatDateTime(new Date()));
+        return result;
+    }
 }

+ 89 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/dto/GroupDTO.java

@@ -0,0 +1,89 @@
+package cn.com.qmth.stmms.api.dto;
+
+import java.util.List;
+
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
+
+public class GroupDTO {
+
+    private Integer number;
+
+    private List<PictureConfigItem> picConfig;
+
+    private Double doubleRate;
+
+    private Double arbitrateThreshold;
+
+    private Integer scorePolicy;
+
+    private Boolean enableAllZero;
+
+    private String markMode;
+
+    private List<QuestionDTO> questions;
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public List<PictureConfigItem> getPicConfig() {
+        return picConfig;
+    }
+
+    public void setPicConfig(List<PictureConfigItem> picConfig) {
+        this.picConfig = picConfig;
+    }
+
+    public Double getDoubleRate() {
+        return doubleRate;
+    }
+
+    public void setDoubleRate(Double doubleRate) {
+        this.doubleRate = doubleRate;
+    }
+
+    public Double getArbitrateThreshold() {
+        return arbitrateThreshold;
+    }
+
+    public void setArbitrateThreshold(Double arbitrateThreshold) {
+        this.arbitrateThreshold = arbitrateThreshold;
+    }
+
+    public Integer getScorePolicy() {
+        return scorePolicy;
+    }
+
+    public void setScorePolicy(Integer scorePolicy) {
+        this.scorePolicy = scorePolicy;
+    }
+
+    public Boolean getEnableAllZero() {
+        return enableAllZero;
+    }
+
+    public void setEnableAllZero(Boolean enableAllZero) {
+        this.enableAllZero = enableAllZero;
+    }
+
+    public String getMarkMode() {
+        return markMode;
+    }
+
+    public void setMarkMode(String markMode) {
+        this.markMode = markMode;
+    }
+
+    public List<QuestionDTO> getQuestions() {
+        return questions;
+    }
+
+    public void setQuestions(List<QuestionDTO> questions) {
+        this.questions = questions;
+    }
+
+}

+ 50 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/api/dto/PaperStructureDTO.java

@@ -0,0 +1,50 @@
+package cn.com.qmth.stmms.api.dto;
+
+import java.util.List;
+
+public class PaperStructureDTO {
+
+    private Integer examId;
+
+    private String subjectCode;
+
+    private Integer trialCount;
+
+    private List<GroupDTO> groups;
+
+    public PaperStructureDTO() {
+    }
+
+    public Integer getExamId() {
+        return examId;
+    }
+
+    public void setExamId(Integer examId) {
+        this.examId = examId;
+    }
+
+    public String getSubjectCode() {
+        return subjectCode;
+    }
+
+    public void setSubjectCode(String subjectCode) {
+        this.subjectCode = subjectCode;
+    }
+
+    public Integer getTrialCount() {
+        return trialCount;
+    }
+
+    public void setTrialCount(Integer trialCount) {
+        this.trialCount = trialCount;
+    }
+
+    public List<GroupDTO> getGroups() {
+        return groups;
+    }
+
+    public void setGroups(List<GroupDTO> groups) {
+        this.groups = groups;
+    }
+
+}

+ 2 - 2
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/checkAnswerEdit.jsp

@@ -194,8 +194,8 @@
                 dom.find('span.num').html('(' + count[q.mainNumber] + ')');
 
                 q.dom = $('<span class="input"><em>' + q.subNumber + '</em><input type="text" value="' + q.answer + '" number="' + i + '"/></span>').appendTo(dom.find('dd'));
-                /* if (title.indexOf('多项选择') >= 0 || title.indexOf('多选') >= 0) { */
-                if(q.multi){
+                if (title.indexOf('多项选择') >= 0 || title.indexOf('多选') >= 0 || title.indexOf('不定项') >= 0) {
+               /*  if(q.multi){ */
                     q.dom.find('input').addClass('large');
                 }
                 q.dom.find('input').on('input', onAnswerInput);