Browse Source

新增客观题判分策略;原图遮盖设置;

ting.yin 5 years ago
parent
commit
3d503b4f53
21 changed files with 385 additions and 44 deletions
  1. 19 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Exam.java
  2. 19 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamQuestion.java
  3. 18 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamSubject.java
  4. 5 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamQuestionService.java
  5. 20 0
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamQuestionServiceImpl.java
  6. 19 7
      stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/ScoreCalculateUtil.java
  7. 35 0
      stmms-common/src/main/java/cn/com/qmth/stmms/common/enums/ObjectivePolicy.java
  8. 18 0
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/BaseExamController.java
  9. 57 1
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ExamController.java
  10. 26 2
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/PaperController.java
  11. 17 11
      stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/SubjectController.java
  12. 13 0
      stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/BaseController.java
  13. 26 1
      stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java
  14. 9 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/examEdit.jsp
  15. 11 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/paperDetail.jsp
  16. 2 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/paperList.jsp
  17. 33 0
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/questionEdit.jsp
  18. 16 14
      stmms-web/src/main/webapp/WEB-INF/views/modules/exam/subjectEdit.jsp
  19. 2 1
      stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markNew.jsp
  20. 2 1
      stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markTrack.jsp
  21. 18 6
      stmms-web/src/main/webapp/static/mark-new/js/modules/sheet-view.js

+ 19 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Exam.java

@@ -97,6 +97,12 @@ public class Exam implements Serializable {
      */
     @Column(name = "sas_config", nullable = true)
     private String sasConfig;
+    
+    /**
+     * 原图遮盖配置
+     */
+    @Column(name = "sheet_config", nullable = true)
+    private String sheetConfig;
 
     public Integer getId() {
         return id;
@@ -230,4 +236,17 @@ public class Exam implements Serializable {
         this.sasConfig = sasConfig;
     }
 
+    
+    public String getSheetConfig() {
+        return sheetConfig;
+    }
+    
+    public void setSheetConfig(String sheetConfig) {
+        this.sheetConfig = sheetConfig;
+    }
+    
+    public List<PictureConfigItem> getSheetConfigList() {
+        return PictureConfigItem.parse(sheetConfig);
+    }
+
 }

+ 19 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamQuestion.java

@@ -6,11 +6,15 @@ 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;
+
 @Entity
 @Table(name = "eb_exam_question")
 public class ExamQuestion implements Serializable {
@@ -60,6 +64,13 @@ public class ExamQuestion implements Serializable {
     @Column(name = "total_count", nullable = true)
     private Integer totalCount;
 
+    /**
+     * 客观题判分策略(1-平均,2-最高,3-最低)
+     */
+    @Column(name = "objective_policy", nullable = true)
+    @Enumerated(EnumType.STRING)
+    private ObjectivePolicy objectivePolicy;
+
     @Transient
     private ExamSubject subject;
 
@@ -273,4 +284,12 @@ public class ExamQuestion implements Serializable {
         this.groupNumber = groupNumber;
     }
 
+    public ObjectivePolicy getObjectivePolicy() {
+        return objectivePolicy;
+    }
+
+    public void setObjectivePolicy(ObjectivePolicy objectivePolicy) {
+        this.objectivePolicy = objectivePolicy;
+    }
+
 }

+ 18 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/ExamSubject.java

@@ -61,6 +61,12 @@ public class ExamSubject implements Serializable {
      */
     @Column(name = "slice_config", nullable = true)
     private String sliceConfig;
+    
+    /**
+     * 原图遮盖配置
+     */
+    @Column(name = "sheet_config", nullable = true)
+    private String sheetConfig;
 
     /**
      * 大题数量
@@ -212,4 +218,16 @@ public class ExamSubject implements Serializable {
     public List<PictureConfigItem> getSliceConfigList() {
         return PictureConfigItem.parse(sliceConfig);
     }
+
+    public String getSheetConfig() {
+        return sheetConfig;
+    }
+
+    public void setSheetConfig(String sheetConfig) {
+        this.sheetConfig = sheetConfig;
+    }
+    
+    public List<PictureConfigItem> getSheetConfigList() {
+        return PictureConfigItem.parse(sheetConfig);
+    }
 }

+ 5 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/ExamQuestionService.java

@@ -4,6 +4,7 @@ import java.util.List;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamQuestionSearchQuery;
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
 
 public interface ExamQuestionService {
 
@@ -46,4 +47,8 @@ public interface ExamQuestionService {
 
     List<String> getPaperTypeWitnNull(Integer examId, String subjectCode);
 
+    ExamQuestion updateObjectivePolicy(Integer questionId, ObjectivePolicy objectivePolicy);
+
+    ExamQuestion findById(Integer questionId);
+
 }

+ 20 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/ExamQuestionServiceImpl.java

@@ -20,13 +20,17 @@ import cn.com.qmth.stmms.biz.common.BaseQueryService;
 import cn.com.qmth.stmms.biz.exam.dao.ExamQuestionDao;
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 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.query.ExamQuestionSearchQuery;
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
 
 @Service
 public class ExamQuestionServiceImpl extends BaseQueryService<ExamQuestion> implements ExamQuestionService {
 
     @Autowired
     private ExamQuestionDao questionDao;
+    @Autowired
+    private ExamService examService;
 
     @Transactional
     @Override
@@ -169,4 +173,20 @@ public class ExamQuestionServiceImpl extends BaseQueryService<ExamQuestion> impl
         return questionDao.getPaperTypeWitnNull(examId, subjectCode, true);
     }
 
+    @Transactional
+    @Override
+    public ExamQuestion updateObjectivePolicy(Integer questionId, ObjectivePolicy objectivePolicy) {
+        ExamQuestion question = questionDao.findOne(questionId);
+        question.setObjectivePolicy(objectivePolicy);
+        questionDao.save(question);
+     // 修改后需要重新统分
+        examService.updateNeedCalculate(question.getExamId(), true);
+        return question;
+    }
+
+    @Override
+    public ExamQuestion findById(Integer questionId) {
+        return questionDao.findOne(questionId);
+    }
+
 }

+ 19 - 7
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/utils/ScoreCalculateUtil.java

@@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamQuestion;
 import cn.com.qmth.stmms.biz.exam.model.ExamStudent;
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
 
 public class ScoreCalculateUtil {
 
@@ -58,15 +59,26 @@ public class ScoreCalculateUtil {
             } catch (Exception e) {
                 continue;
             }
+            
             boolean correct = true;
-            for (int i = 0; i < answer.length(); i++) {
-                if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
-                    correct = false;
-                    break;
+            
+            //客观题判分策略
+            //任选给分
+            if(ObjectivePolicy.ALL.equals(question.getObjectivePolicy())){
+                score = answer.length() == 0 ? 0 : question.getTotalScore();
+            }else{
+                for (int i = 0; i < answer.length(); i++) {
+                    if (!question.getAnswer().contains(String.valueOf(answer.charAt(i)))) {
+                        correct = false;
+                        break;
+                    }
+                }
+                if (correct & ObjectivePolicy.LEAK.equals(question.getObjectivePolicy())) {
+                    score = answer.length() < question.getAnswer().length() ? question.getTotalScore()/2 : question.getTotalScore();
+                }
+                if(correct & (question.getObjectivePolicy()==null || ObjectivePolicy.NONE.equals(question.getObjectivePolicy()))){
+                    score = answer.length() < question.getAnswer().length() ? 0 : question.getTotalScore();
                 }
-            }
-            if (correct) {
-                score = answer.length() < question.getAnswer().length() ? 0 : question.getTotalScore();
             }
 
             // log.debug("question result: " + question.getNumber() + ", " +

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

@@ -0,0 +1,35 @@
+package cn.com.qmth.stmms.common.enums;
+
+/**
+ * 客观题判断策略
+ * 
+ */
+public enum ObjectivePolicy {
+    NONE("无", 1), ALL("任选给分", 2), LEAK("漏选给分", 3);
+
+    private String name;
+
+    private int value;
+
+    private ObjectivePolicy(String name, int value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getValue() {
+        return value;
+    }
+
+    public static ObjectivePolicy findByValue(int value) {
+        for (ObjectivePolicy c : ObjectivePolicy.values()) {
+            if (c.getValue() == value) {
+                return c;
+            }
+        }
+        return null;
+    }
+}

+ 18 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/BaseExamController.java

@@ -6,11 +6,15 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import cn.com.qmth.stmms.admin.utils.SessionExamUtils;
 import cn.com.qmth.stmms.biz.common.BaseQuery;
 import cn.com.qmth.stmms.biz.exam.model.Exam;
@@ -18,6 +22,7 @@ import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.service.ExamService;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
 import cn.com.qmth.stmms.common.controller.BaseController;
 import cn.com.qmth.stmms.common.domain.WebUser;
@@ -126,5 +131,18 @@ public class BaseExamController extends BaseController {
             return true;
         }
     }
+    
+    protected String buildPictureConfig(String sheetConfig) {
+        String json = "";
+        if (StringUtils.isNotBlank(sheetConfig)) {
+            try {
+                ObjectMapper mapper = new ObjectMapper();
+                json = mapper.writeValueAsString(PictureConfigItem.parse(sheetConfig));
+            } catch (JsonProcessingException e) {
+                e.printStackTrace();
+            }
+        }
+        return json;
+    }
 
 }

+ 57 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/ExamController.java

@@ -5,31 +5,45 @@ import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
 
+import net.sf.json.JSONArray;
+import net.sf.json.JsonConfig;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
 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.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
 import cn.com.qmth.stmms.admin.utils.SessionExamUtils;
 import cn.com.qmth.stmms.admin.vo.ExamInfoVO;
+import cn.com.qmth.stmms.biz.campus.model.Campus;
+import cn.com.qmth.stmms.biz.campus.service.CampusService;
 import cn.com.qmth.stmms.biz.exam.model.Exam;
+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.query.ExamSearchQuery;
+import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
 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.MarkerService;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.biz.user.model.User;
 import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.domain.WebUser;
 import cn.com.qmth.stmms.common.enums.ExamStatus;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.utils.Paginator;
+import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
 
 @Controller
@@ -49,6 +63,12 @@ public class ExamController extends BaseExamController {
 
     @Autowired
     private ExamSubjectService examSubjectService;
+    
+    @Autowired
+    private CampusService campusService;
+    
+    @Value("${sheet.image.server}")
+    private String imageServer;
 
     @RequestMapping(value = { "/exam-list" })
     public String examList(Model model, HttpServletRequest request, ExamSearchQuery query) {
@@ -80,6 +100,7 @@ public class ExamController extends BaseExamController {
         Exam exam = examService.findById(examId);
         model.addAttribute("exam", exam);
         model.addAttribute("statusList", ExamStatus.values());
+        model.addAttribute("pictureConfig", buildPictureConfig(exam.getSheetConfig()));
         return "modules/exam/examEdit";
     }
 
@@ -95,9 +116,11 @@ public class ExamController extends BaseExamController {
         return "redirect:/admin/exam-list";
     }
 
+    @SuppressWarnings("unchecked")
     @RequestMapping(value = "/exam-edit", method = RequestMethod.POST)
     @RoleRequire(Role.SCHOOL_ADMIN)
-    public String examEdit(HttpServletRequest request, Exam exam, int StatusValue, RedirectAttributes redirectAttributes) {
+    public String examEdit(HttpServletRequest request, Exam exam, int StatusValue, @RequestParam String picList,
+            RedirectAttributes redirectAttributes) {
         User user = RequestUtils.getWebUser(request).getUser();
         Exam oldExam = examService.findById(exam.getId());
         if (oldExam != null && oldExam.getCreatorId().intValue() == user.getId().intValue()) {
@@ -108,6 +131,10 @@ public class ExamController extends BaseExamController {
             oldExam.setForceSpecialTag(exam.isForceSpecialTag());
             oldExam.setPassScore(exam.getPassScore());
             oldExam.setExcellentScore(exam.getExcellentScore());
+            String sheetConfig = StringEscapeUtils.unescapeHtml(picList);
+            JSONArray array = JSONArray.fromObject(sheetConfig);
+            List<PictureConfigItem> list = JSONArray.toList(array, new PictureConfigItem(), new JsonConfig());
+            oldExam.setSheetConfig(list==null?null:StringUtils.join(list, PictureConfigItem.DB_ITEM_JOINER));
             examService.save(oldExam);
         }
         return "redirect:/admin/exam-list";
@@ -193,5 +220,34 @@ public class ExamController extends BaseExamController {
         exam.setStatus(ExamStatus.FINISH);
         examService.save(exam);
     }
+    
+    @RequestMapping("/exam/getSheetConfig")
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String get(HttpServletRequest request, Model model, RedirectAttributes redirectAttributes,
+           @RequestParam Integer examId,@RequestParam(required=false) String subjectCode) {
+        Exam exam = examService.findById(examId);
+        ExamSubject subject = examSubjectService.find(examId, subjectCode);
+        ExamStudentSearchQuery query = new ExamStudentSearchQuery();
+        query.setExamId(examId);
+        query.setSubjectCode(subjectCode);
+        query.setUpload(true);
+        List<ExamStudent> examStudents = examStudentService.findByQuery(query).getResult();
+        if (examStudents.size() > 0) {
+            model.addAttribute("picUrls", buildPicUrl(examStudents.get(0)));
+            String sheetConfig = subject!=null? subject.getSheetConfig():exam.getSheetConfig();
+            model.addAttribute("pictureConfig", buildPictureConfig(sheetConfig));
+            model.addAttribute("imageServer", imageServer);
+            return "modules/mark/picConfig";
+        } else {
+            addMessage(redirectAttributes, "参数有误");
+            return "redirect:/admin/exam-list";
+        }
+    }
 
+    private List<String> buildPicUrl(ExamStudent examStudent) {
+        Campus campus = campusService.findBySchoolAndName(examStudent.getSchoolId(), examStudent.getCampusName());
+        List<String> picUrls = PictureUrlBuilder.getSheetUrls(examStudent.getExamId(), campus.getId(),
+                examStudent.getSubjectCode(), examStudent.getExamNumber(), examStudent.getSheetCount());
+        return picUrls;
+    }
 }

+ 26 - 2
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/PaperController.java

@@ -9,6 +9,9 @@ import java.util.Map.Entry;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -16,6 +19,7 @@ import org.springframework.data.domain.Sort;
 import org.springframework.data.domain.Sort.Direction;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -36,14 +40,17 @@ 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.query.ExamQuestionSearchQuery;
 import cn.com.qmth.stmms.biz.exam.service.query.ExamSubjectSearchQuery;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.utils.ExportExcel;
 import cn.com.qmth.stmms.common.utils.ImportExcel;
 import cn.com.qmth.stmms.common.utils.RequestUtils;
-import net.sf.json.JSONArray;
-import net.sf.json.JSONObject;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 
 @Controller("examPaperController")
 @RequestMapping("/admin/exam/paper")
@@ -274,4 +281,21 @@ public class PaperController extends BaseExamController {
         }
         return array;
     }
+    
+    @RequestMapping(value = "/question-edit/{questionId}", method = RequestMethod.GET)
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String edit(Model model,@PathVariable Integer questionId) {
+        ExamQuestion examQuestion = questionService.findById(questionId);
+        model.addAttribute("examQuestion", examQuestion);
+        model.addAttribute("objectivePolicyList", ObjectivePolicy.values());
+        return "modules/exam/questionEdit";
+    }
+    
+    @RequestMapping(value = "/question-edit", method = RequestMethod.POST)
+    @RoleRequire(Role.SCHOOL_ADMIN)
+    public String update(@RequestParam Integer id, @RequestParam ObjectivePolicy objectivePolicy) {
+        ExamQuestion question = questionService.updateObjectivePolicy(id, objectivePolicy);
+        return "redirect:/admin/exam/paper/detail?subjectCode="+question.getSubjectCode();
+    }
+    
 }

+ 17 - 11
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/SubjectController.java

@@ -1,7 +1,13 @@
 package cn.com.qmth.stmms.admin.exam;
 
+import java.util.List;
+
 import javax.servlet.http.HttpServletRequest;
 
+import net.sf.json.JSONArray;
+import net.sf.json.JsonConfig;
+
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -11,8 +17,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
-import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.common.auth.annotation.RoleRequire;
 import cn.com.qmth.stmms.common.enums.Role;
 
@@ -23,31 +29,31 @@ public class SubjectController extends BaseExamController {
     @Autowired
     private ExamSubjectService subjectService;
 
-    @Autowired
-    private ExamStudentService studentService;
-
     @RequestMapping("/edit")
     @RoleRequire(Role.SCHOOL_ADMIN)
     public String edit(HttpServletRequest request, @RequestParam String code, Model model) {
         ExamSubject subject = subjectService.find(getSessionExamId(request), code);
         model.addAttribute("subject", subject);
+        model.addAttribute("pictureConfig", buildPictureConfig(subject.getSheetConfig()));
         return "modules/exam/subjectEdit";
     }
 
+    @SuppressWarnings("unchecked")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @RoleRequire(Role.SCHOOL_ADMIN)
-    public String save(HttpServletRequest request, ExamSubject subject, Model model) {
+    public String save(HttpServletRequest request, ExamSubject subject, Model model,@RequestParam String picList) {
         ExamSubject previous = subjectService.find(getSessionExamId(request), subject.getCode());
-        if (previous != null && StringUtils.isNotBlank(subject.getName())) {
-            previous.setName(subject.getName());
-            previous.setLevel(subject.getLevel());
-            previous.setCategory(subject.getCategory());
-            previous.setRemark(subject.getRemark());
+        if (previous != null && StringUtils.isNotBlank(picList)) {
+            String sheetConfig = StringEscapeUtils.unescapeHtml(picList);
+            JSONArray array = JSONArray.fromObject(sheetConfig);
+            List<PictureConfigItem> list = JSONArray.toList(array, new PictureConfigItem(), new JsonConfig());
+            previous.setSheetConfig(list==null?null:StringUtils.join(list, PictureConfigItem.DB_ITEM_JOINER));
             subjectService.save(previous);
-            studentService.updateSubjectInfo(previous);
         }
         model.addAttribute("subject", previous);
+        model.addAttribute("pictureConfig", buildPictureConfig(subject.getSheetConfig()));
         model.addAttribute("message", "修改成功");
         return "modules/exam/subjectEdit";
     }
+    
 }

+ 13 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/common/controller/BaseController.java

@@ -26,6 +26,7 @@ import cn.com.qmth.stmms.common.enums.HistoryStatus;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
 import cn.com.qmth.stmms.common.enums.MarkMode;
 import cn.com.qmth.stmms.common.enums.MarkStatus;
+import cn.com.qmth.stmms.common.enums.ObjectivePolicy;
 import cn.com.qmth.stmms.common.enums.Role;
 import cn.com.qmth.stmms.common.utils.DateUtils;
 
@@ -168,6 +169,18 @@ public class BaseController {
                 }
             }
         });
+        // ObjectivePolicy 类型转换
+        binder.registerCustomEditor(ObjectivePolicy.class, new PropertyEditorSupport() {
+
+            @Override
+            public void setAsText(String text) {
+                try {
+                    setValue(ObjectivePolicy.findByValue(Integer.valueOf(text)));
+                } catch (Exception e) {
+                    setValue(null);
+                }
+            }
+        });
         
         binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(true));
     }

+ 26 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -22,6 +22,9 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.servlet.ModelAndView;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import cn.com.qmth.stmms.biz.exam.model.Exam;
 import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
 import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
@@ -35,6 +38,7 @@ import cn.com.qmth.stmms.biz.exam.service.TagService;
 import cn.com.qmth.stmms.biz.lock.LockService;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
 import cn.com.qmth.stmms.biz.mark.model.MarkResult;
+import cn.com.qmth.stmms.biz.mark.model.PictureConfigItem;
 import cn.com.qmth.stmms.biz.mark.model.Task;
 import cn.com.qmth.stmms.biz.mark.model.TrialHistory;
 import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
@@ -179,10 +183,18 @@ public class MarkController extends BaseController {
         modelAndView.addObject("sheetServer", sheetServer);
         modelAndView.addObject("cardServer", cardServer);
         modelAndView.addObject("marker", marker);
-        modelAndView.addObject("subject", subjectService.find(marker.getExamId(), marker.getSubjectCode()));
+        ExamSubject subject = subjectService.find(marker.getExamId(), marker.getSubjectCode());
+        modelAndView.addObject("subject", subject);
         Exam exam = examService.findById(marker.getExamId());
         modelAndView.addObject("forceSpecialTag", exam.isForceSpecialTag());
         modelAndView.addObject("defaultSetting", StringUtils.trimToNull(marker.getMarkSetting()));
+        String sheetConfig = "";
+        if(StringUtils.isNotBlank(subject.getSheetConfig())){
+            sheetConfig = buildPictureConfig(subject.getSheetConfig());
+        }else if(StringUtils.isNotBlank(exam.getSheetConfig())){
+            sheetConfig = buildPictureConfig(exam.getSheetConfig());
+        }
+        modelAndView.addObject("sheetConfig", sheetConfig);
         releaseMarker(marker);
     }
 
@@ -476,5 +488,18 @@ public class MarkController extends BaseController {
             lockService.unlock(LockType.MARKER, marker.getId());
         }
     }
+    
+    protected String buildPictureConfig(String sheetConfig) {
+        String json = "";
+        if (StringUtils.isNotBlank(sheetConfig)) {
+            try {
+                ObjectMapper mapper = new ObjectMapper();
+                json = mapper.writeValueAsString(PictureConfigItem.parse(sheetConfig));
+            } catch (JsonProcessingException e) {
+                e.printStackTrace();
+            }
+        }
+        return json;
+    }
 
 }

+ 9 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/examEdit.jsp

@@ -8,6 +8,8 @@
 	<script type="text/javascript">
 		$(document).ready(function() {
 			$("#name").focus();
+			var pictureConfig = '${pictureConfig}';
+			window.localStorage.setItem("pictureConfig",pictureConfig);
 			$("#inputForm").validate({
 				submitHandler: function(form){
 					loading('正在提交,请稍等...');
@@ -77,6 +79,13 @@
             </select>
 			</div>
 		</div>
+		<div class="control-group">
+            <label class="control-label">原图遮盖</label>
+            <div class="controls">
+                <input name="picList" id="picList"  type="hidden"/>
+                <a href="${ctx}/admin/exam/getSheetConfig?examId=${exam.id}" target="_blank" class="required" id= "configuration">设置</a>
+            </div>
+        </div>
 		</c:if>
 		<div class="control-group">
 			<label class="control-label">描述</label>

+ 11 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/paperDetail.jsp

@@ -36,6 +36,8 @@
 				<th>满分</th>
 				<th>间隔分</th>
 				<th>答案</th>
+				<th>判分策略</th>
+				<th>操作</th>
 			</tr>
 		</thead>
 		<tbody>
@@ -48,6 +50,15 @@
 				<td><fmt:formatNumber pattern="###.#" value="${question.totalScore}"/></td>
 				<td><fmt:formatNumber pattern="###.#" value="${question.intervalScore}"/></td>
 				<td>${question.answer}</td>
+				<td>
+					<c:if test="${question.objective}">
+					<c:if test="${question.objectivePolicy==null}">无</c:if>
+					${question.objectivePolicy.name}
+					</c:if>
+				</td>
+				<td>
+					<c:if test="${question.objective}"><a href="${ctx}/admin/exam/paper/question-edit/${question.id}">编辑</a></c:if>
+				</td>
 			</tr>
 		</c:forEach>
 		</tbody>

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

@@ -101,6 +101,7 @@
 				<th>客观总分</th>
 				<th>主观总分</th>
 				<th>试卷总分</th>
+				<th>操作</th>
 			</tr>
 		</thead>
 		<tbody>
@@ -124,6 +125,7 @@
 				<td>${subject.objectiveScore}</td>
 				<td>${subject.subjectiveScore}</td>
 				<td>${subject.totalScore}</td>
+				<td><a href="${ctx}/admin/exam/subject/edit?code=${subject.code}">原图遮盖</a></td>
 			</tr>
 		</c:forEach>
 		</tbody>

+ 33 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/questionEdit.jsp

@@ -0,0 +1,33 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+	<title>考试管理</title>
+	<meta name="decorator" content="default"/>
+	<%@include file="/WEB-INF/views/include/head.jsp" %>
+</head>
+<body>
+	<ul class="nav nav-tabs">
+		<li class="active"><a href="${ctx}/admin/exam/paper/detail?subjectCode=${examQuestion.subjectCode }">试题列表</a></li>
+	</ul><br/>
+	<form id="inputForm" action="${ctx}/admin/exam/paper/question-edit" method="post" class="form-horizontal">
+		<tags:message content="${message}"/>
+		<input type="hidden"  name="id" value="${examQuestion.id }"/>
+		<div class="control-group">
+			<label class="control-label">判分策略</label>
+			<div class="controls">
+				<select class="input-small" name="objectivePolicy">
+                <c:forEach items="${objectivePolicyList}" var="item">
+                	 <option value="${item.value}" <c:if test="${item.value==examQuestion.objectivePolicy.value}">selected</c:if>>${item.name}</option>
+                </c:forEach>
+            </select>
+			</div>
+		</div>
+		<div class="form-actions">
+			<input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/>
+			&nbsp;
+			<a href="${ctx}/admin/exam/paper/detail?subjectCode=${examQuestion.subjectCode }" class="btn"/>返回</a>
+		</div>
+	</form>
+</body>
+</html>

+ 16 - 14
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/subjectEdit.jsp

@@ -7,40 +7,42 @@
 	<%@include file="/WEB-INF/views/include/head.jsp" %>
 </head>
 <body>
+	<ul class="nav nav-tabs">
+		<li class="active"><a href="${ctx}/admin/exam/paper">科目管理</a></li>
+	</ul><br/>
 	<form:form id="inputForm" modelAttribute="subject" action="${ctx}/admin/exam/subject/save" method="post" class="form-horizontal">
 		<form:hidden path="code"/>
 		<tags:message content="${message}"/>
 		<div class="control-group">
 			<label class="control-label">名称</label>
 			<div class="controls">
-				<form:input path="name" htmlEscape="false" maxlength="20" class="required"/>
+				${subject.name }
 			</div>
 		</div>
 		<div class="control-group">
-			<label class="control-label">层次</label>
+			<label class="control-label">代码</label>
 			<div class="controls">
-				<form:input path="level" htmlEscape="false" maxlength="20" class=""/>
+				${subject.code }
 			</div>
 		</div>
 		<div class="control-group">
-			<label class="control-label">专业</label>
-			<div class="controls">
-				<form:input path="category" htmlEscape="false" maxlength="20" class=""/>
-			</div>
-		</div>
-		<div class="control-group">
-			<label class="control-label">备注</label>
-			<div class="controls">
-				<form:input path="remark" htmlEscape="false" maxlength="20" class=""/>
-			</div>
-		</div>
+            <label class="control-label">原图遮盖</label>
+            <div class="controls">
+                <input name="picList" id="picList"  type="hidden"/>
+                <a href="${ctx}/admin/exam/getSheetConfig?examId=${subject.examId}&subjectCode=${subject.code}" target="_blank" class="required" id= "configuration">设置</a>
+            </div>
+        </div>
 		<div class="form-actions">
 			<input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/>
+			<a href="${ctx}/admin/exam/paper" class="btn"/>返回</a>
 		</div>
 	</form:form>
 <script type="text/javascript">
 	$(document).ready(function() {
 		//$("#name").focus();
+		var pictureConfig = '${pictureConfig}';
+		window.localStorage.setItem("pictureConfig",pictureConfig);
+			
 		$("#inputForm").validate({
 			
 			submitHandler: function(form){

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markNew.jsp

@@ -75,7 +75,8 @@
 					},
 					<c:if test="${sheetView==true}">
 					'sheet-view' : {
-						server : '${sheetServer}'
+						server : '${sheetServer}',
+						sheetConfig:'${sheetConfig}'
 					},
 					</c:if>
 					'warning-info': {

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markTrack.jsp

@@ -77,7 +77,8 @@
                     },
                     <c:if test="${sheetView==true}">
 					'sheet-view':{
-                        server : '${sheetServer}'
+                        server : '${sheetServer}',
+                        sheetConfig:'${sheetConfig}'
                     },
                     </c:if>
 					'object-view':{

+ 18 - 6
stmms-web/src/main/webapp/static/mark-new/js/modules/sheet-view.js

@@ -8,6 +8,7 @@ var sheet_view = function(option, success) {
 function SheetView(option) {
     this.markControl = option.markControl;
     this.server = option.server;
+    this.sheetConfig = option.sheetConfig;
     this.init();
     this.markControl.on('task.get.success', this, function(event, context, eventObject) {
         this.render(context.task.sheetUrls);
@@ -87,24 +88,35 @@ SheetView.prototype.renderContent = function(content, sheetId) {
 	var url =  document.getElementById(sheetId).getAttribute("data-url");
 	var show  = false;
 	var i = sheetId.split("sheet")[1];
-	if(i%2==0){
-		show = true;
-	}
+//	if(i%2==0){
+//		show = true;
+//	}
 	content.append($('<canvas id="sheet-canvas"></canvas>'));
 	var image = new Image();
 	image.crossOrigin = '';
 	image.src = this.server + url ;
     image.canvas = document.getElementById('sheet-canvas');
     image.content = content;
+    var self = this;
+    if(self.sheetConfig){
+    	self.sheetConfig = JSON.parse(self.sheetConfig);
+	};
     image.onload = function() {
     	var ctx = this.canvas.getContext("2d");
     	this.canvas.width = Math.min(this.width, this.content.width());
     	this.canvas.height = this.canvas.width * this.height / this.width;
     	ctx.drawImage(image, 0,0,this.width,this.height,0, 0, this.canvas.width, this.canvas.height);
-    	if(show){
-    		ctx.fillStyle = "#FFFFFF";
-    		ctx.fillRect(0, 0, this.canvas.width/2, this.canvas.height*3.7/10);
+    	ctx.fillStyle = "#FFFFFF";
+//    	if(show){
+//    		ctx.fillRect(0, 0, this.canvas.width/2, this.canvas.height*3.7/10);
+//    	}
+    	for(var j = 0; j < self.sheetConfig.length; j++){
+    		var config = self.sheetConfig[j];
+    		if(config.i == i+1){
+    			ctx.fillRect(config.x, config.y, config.w, config.h);
+    		}
     	}
+    	
     	this.canvas.toDataURL("image/jpeg");
     }
 }