1
0
Quellcode durchsuchen

枚举空字符串转换

xiatian vor 14 Stunden
Ursprung
Commit
c13eee7006

+ 0 - 1
install/mysql/init/stmms_ft.sql

@@ -225,7 +225,6 @@ CREATE TABLE `eb_exam`
     `name`                  varchar(64) NOT NULL COMMENT '考试名称',
     `school_id`             int(11)     NOT NULL COMMENT '学校ID',
     `code`                  varchar(64)  DEFAULT NULL COMMENT '考试代码',
-    `exam_time`             datetime    NOT NULL COMMENT '考试时间',
     `type`                  varchar(16) NOT NULL COMMENT '类型',
     `status`                varchar(16) NOT NULL COMMENT '状态',
     `card_type`             varchar(16)  DEFAULT NULL COMMENT '题卡类型',

+ 1 - 0
install/mysql/upgrade/2.0.0.sql

@@ -8,6 +8,7 @@ ALTER TABLE eb_exam ADD COLUMN `re_mark_limit_count` int(11)  DEFAULT NULL  COMM
 ALTER TABLE eb_exam ADD COLUMN `barcode_ai_check` tinyint(1)  NOT NULL DEFAULT 0 COMMENT '启用条码粘贴AI检测';
 ALTER TABLE eb_exam ADD COLUMN `answer_ai_check` tinyint(1)  NOT NULL DEFAULT 0 COMMENT '启用题卡作答AI检测';
 ALTER TABLE eb_exam ADD COLUMN `ai_check_finish_time`           datetime     DEFAULT NULL COMMENT 'AI检测完成时间';
+ALTER TABLE eb_exam DROP COLUMN `exam_time`;
 
 ALTER TABLE b_user ADD COLUMN   `student_export_cols`        varchar(500) DEFAULT NULL COMMENT '学生列表导出表头',
 ALTER TABLE b_user ADD COLUMN   `score_export_cols`        varchar(500) DEFAULT NULL COMMENT '成绩列表导出表头',

+ 23 - 14
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/bean/ExamVo.java

@@ -2,6 +2,10 @@ package cn.com.qmth.stmms.biz.exam.bean;
 
 import java.util.Date;
 
+import javax.validation.constraints.NotNull;
+
+import org.hibernate.validator.constraints.NotBlank;
+
 import cn.com.qmth.stmms.biz.exam.model.Exam;
 import cn.com.qmth.stmms.biz.file.enums.FormatType;
 import cn.com.qmth.stmms.common.enums.ExamStatus;
@@ -17,6 +21,7 @@ public class ExamVo {
 
     private Integer id;
 
+    @NotBlank(message = "名称不能为空")
     @ApiModelProperty(value = "名称")
     private String name;
 
@@ -25,9 +30,7 @@ public class ExamVo {
     @ApiModelProperty(value = "code")
     private String code;
 
-    @ApiModelProperty(value = "考试时间")
-    private Date examTime;
-
+    @NotNull(message = "状态不能为空")
     @ApiModelProperty(value = "状态")
     private ExamStatus status;
 
@@ -37,6 +40,7 @@ public class ExamVo {
     /**
      * 开启强制特殊标记
      */
+    @NotNull(message = "强制标记不能为空")
     @ApiModelProperty(value = "开启强制特殊标记")
     private Boolean forceSpecialTag;
 
@@ -67,6 +71,7 @@ public class ExamVo {
     /**
      * 考试类型
      */
+    @NotNull(message = "考试类型不能为空")
     @ApiModelProperty(value = "考试类型")
     private ExamType type;
 
@@ -79,12 +84,14 @@ public class ExamVo {
     /**
      * 禁止管理员以外人查看考生个人信息
      */
+    @NotNull(message = "禁止他人查看考生信息不能为空")
     @ApiModelProperty(value = "禁止管理员以外人查看考生个人信息")
     private Boolean forbiddenInfo;
 
     /**
      * 禁止查看成绩
      */
+    @NotNull(message = "禁止科组长成绩查询不能为空")
     @ApiModelProperty(value = "禁止查看成绩")
     private Boolean forbiddenScore;
 
@@ -109,12 +116,14 @@ public class ExamVo {
     /**
      * 强制评卷模式
      */
-    @ApiModelProperty(value = "强制评卷模式")
+    @NotNull(message = "评卷模式不能为空")
+    @ApiModelProperty(value = "评卷模式")
     private MarkMode markMode;
 
     /**
      * 开启/关闭 原卷显示
      */
+    @NotNull(message = "原卷显示不能为空")
     @ApiModelProperty(value = "开启/关闭 原卷显示")
     private Boolean sheetView;
 
@@ -127,34 +136,40 @@ public class ExamVo {
     /**
      * 自动跳转
      */
+    @NotNull(message = "评卷提交自动定位不能为空")
     @ApiModelProperty(value = "评卷提交自动定位")
     private Boolean autoScroll;
 
     /**
      * 是否裁切
      */
+    @NotNull(message = "自劝对切题卡不能为空")
     @ApiModelProperty(value = "自动对切题卡")
     private Boolean enableSplit;
 
     /**
      * 打回后是否显示原分值
      */
+    @NotNull(message = "打回后是否显示原分值不能为空")
     @ApiModelProperty(value = "打回后是否显示原分值")
     private Boolean showReject;
 
     /**
      * 全卷多次复核时不能为同一账号
      */
+    @NotNull(message = "全卷多次复核不能同一账号不能为空")
     @ApiModelProperty(value = "全卷多次复核时不能为同一账号")
     private Boolean inspectUnrepeated;
 
     /**
      * 全卷复核时强制试卷拉到底部
      */
+    @NotNull(message = "全卷复核强制试卷拉到底部不能为空")
     @ApiModelProperty(value = "全卷复核时强制试卷拉到底部")
     private Boolean inspectScrollBottom;
 
     // 评卷时强制试卷拉到底部
+    @NotNull(message = "评卷时强制试卷拉到底部不能为空")
     @ApiModelProperty(value = "评卷时强制试卷拉到底部")
     private Boolean markScrollBottom;
 
@@ -167,12 +182,14 @@ public class ExamVo {
     /**
      * 评卷端是否显示客观分
      */
+    @NotNull(message = "评卷端显示客观分不能为空")
     @ApiModelProperty(value = "评卷端是否显示客观分")
     private Boolean showObjectiveScore;
 
     /**
      * 全卷复核进度100%时才能再次复核
      */
+    @NotNull(message = "全卷复核进度100%才能再次复核不能为空")
     @ApiModelProperty(value = "全卷复核进度100%时才能再次复核")
     private Boolean inspectRoundLimit;
 
@@ -200,10 +217,12 @@ public class ExamVo {
     private Integer reMarkLimitCount;
 
     // 启用条码粘贴AI检测
+    @NotNull(message = "启用条码粘贴AI检测不能为空")
     @ApiModelProperty(value = "启用条码粘贴AI检测")
     private Boolean barcodeAiCheck;
 
     // 启用题卡作答AI检测
+    @NotNull(message = "启用题卡作答AI检测不能为空")
     @ApiModelProperty(value = "启用题卡作答AI检测")
     private Boolean answerAiCheck;
 
@@ -239,14 +258,6 @@ public class ExamVo {
         this.code = code;
     }
 
-    public Date getExamTime() {
-        return examTime;
-    }
-
-    public void setExamTime(Date examTime) {
-        this.examTime = examTime;
-    }
-
     public ExamStatus getStatus() {
         return status;
     }
@@ -544,7 +555,6 @@ public class ExamVo {
         ret.setName(from.getName());
         ret.setSchoolId(from.getSchoolId());
         ret.setCode(from.getCode());
-        ret.setExamTime(from.getExamTime());
         ret.setStatus(from.getStatus());
         ret.setDescription(from.getDescription());
         ret.setForceSpecialTag(from.isForceSpecialTag());
@@ -592,7 +602,6 @@ public class ExamVo {
         ret.setName(from.getName());
         ret.setSchoolId(from.getSchoolId());
         ret.setCode(from.getCode());
-        ret.setExamTime(from.getExamTime());
         ret.setStatus(from.getStatus());
         ret.setDescription(from.getDescription());
         ret.setForceSpecialTag(from.getForceSpecialTag());

+ 1 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/ExamDao.java

@@ -22,7 +22,7 @@ public interface ExamDao extends PagingAndSortingRepository<Exam, Integer>, JpaS
 
     List<Exam> findByStatus(ExamStatus status);
 
-    @Query("select e from Exam e where e.creatorId=?1 and e.status=?2 order by e.examTime desc")
+    @Query("select e from Exam e where e.creatorId=?1 and e.status=?2 order by e.createTime desc")
     public List<Exam> findByCreatorAndStatus(Integer id, ExamStatus status);
 
     @Modifying

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

@@ -44,10 +44,6 @@ public class Exam implements Serializable {
 
     private String code;
 
-    @Temporal(TemporalType.DATE)
-    @Column(name = "exam_time")
-    private Date examTime;
-
     @Enumerated(EnumType.STRING)
     @Column(name = "status", length = 16, nullable = false)
     private ExamStatus status;
@@ -259,14 +255,6 @@ public class Exam implements Serializable {
         this.description = description;
     }
 
-    public Date getExamTime() {
-        return examTime;
-    }
-
-    public void setExamTime(Date examTime) {
-        this.examTime = examTime;
-    }
-
     public Date getCreateTime() {
         return createTime;
     }

+ 70 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exception/StatusException.java

@@ -0,0 +1,70 @@
+package cn.com.qmth.stmms.biz.exception;
+
+public class StatusException extends RuntimeException {
+
+    private static final long serialVersionUID = 5003047488500388819L;
+
+    private static final String DEF_CODE = "500";
+
+    /**
+     * 追踪ID
+     */
+    private String traceId;
+
+    /**
+     * 状态码
+     */
+    private String code;
+
+    /**
+     * 状态描述
+     */
+    private String desc;
+
+    /**
+     * 构造函数
+     */
+    public StatusException(String code, String desc) {
+        super("[code: " + code + "; desc: " + desc + "]");
+        this.code = code;
+        this.desc = desc;
+    }
+
+    /**
+     * 构造函数
+     */
+    public StatusException(String code, String desc, Throwable cause) {
+        super("[code: " + code + "; desc: " + desc + "]", cause);
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public StatusException(String desc) {
+        super("[code: " + DEF_CODE + "; desc: " + desc + "]");
+        this.code = DEF_CODE;
+        this.desc = desc;
+    }
+
+    public StatusException(String desc, Throwable cause) {
+        super("[code: " + DEF_CODE + "; desc: " + desc + "]", cause);
+        this.code = DEF_CODE;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public String getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(String traceId) {
+        this.traceId = traceId;
+    }
+
+}

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

@@ -155,7 +155,6 @@ public class ExamController extends BaseExamController {
         Exam oldExam = examService.findById(exam.getId());
         if (oldExam != null && oldExam.getSchoolId().equals(user.getSchoolId())) {
             oldExam.setName(exam.getName());
-            oldExam.setExamTime(exam.getExamTime());
             oldExam.setDescription(exam.getDescription());
             oldExam.setStatus(exam.getStatus());
             oldExam.setForceSpecialTag(exam.isForceSpecialTag());

+ 2 - 5
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/CoreController.java

@@ -179,9 +179,6 @@ public class CoreController extends BaseApiController {
             throw ApiException.EXAM_NOT_ACCESSIBLED;
         }
         current.setName(name);
-        if (time != null) {
-            current.setExamTime(time);
-        }
         current = examService.save(current);
         result.accumulate("id", current.getId());
         result.accumulate("updateTime", DateUtils.formatDateTime(new Date()));
@@ -308,11 +305,11 @@ public class CoreController extends BaseApiController {
         query = studentService.findByQuery(query);
         for (ExamStudent student : query.getResult()) {
             Exam exam = examService.findById(student.getExamId());
-            if (minExamTime != null && minExamTime.before(exam.getExamTime())) {
+            if (minExamTime != null && minExamTime.before(exam.getCreateTime())) {
                 JSONObject obj = new JSONObject();
                 obj.accumulate("examId", exam.getId());
                 obj.accumulate("examCode", exam.getCode());
-                obj.accumulate("examTime", DateUtils.formatDateTime(exam.getExamTime()));
+                obj.accumulate("examTime", DateUtils.formatDateTime(exam.getCreateTime()));
                 obj.accumulate("examNumber", student.getExamNumber());
                 obj.accumulate("name", student.getName());
                 obj.accumulate("subjectCode", student.getSubjectCode());

+ 1 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamController.java

@@ -72,7 +72,7 @@ public class ExamController extends BaseApiController {
             JSONObject obj = new JSONObject();
             obj.accumulate("id", exam.getId());
             obj.accumulate("name", exam.getName());
-            obj.accumulate("examTime", exam.getExamTime().getTime());
+            obj.accumulate("examTime", exam.getCreateTime().getTime());
             if (StringUtils.isNotBlank(exam.getScanConfig())) {
                 obj.accumulate("config", exam.getScanConfig());
             }

+ 5 - 7
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/ExamInfoController.java

@@ -83,15 +83,15 @@ public class ExamInfoController extends BaseApiController {
             JSONObject obj = new JSONObject();
             obj.accumulate("id", exam.getId());
             obj.accumulate("name", exam.getName());
-            obj.accumulate("examTime", DateUtils.formatDate(exam.getExamTime()));
+            obj.accumulate("examTime", DateUtils.formatDate(exam.getCreateTime()));
             if (exam.getCardType() != null) {
                 obj.accumulate("cardType", exam.getCardType().getExtName());
                 obj.accumulate("cardUrl",
                         fileService.getFileServer() + fileService.getCardUri(exam.getId(), exam.getCardType()));
             }
             obj.accumulate("sliceConfig", StringUtils.trimToEmpty(exam.getSliceConfig()));
-            obj.accumulate("updateTime", exam.getUpdateTime() == null ? exam.getCreateTime().getTime() : exam
-                    .getUpdateTime().getTime());
+            obj.accumulate("updateTime",
+                    exam.getUpdateTime() == null ? exam.getCreateTime().getTime() : exam.getUpdateTime().getTime());
             array.add(obj);
         }
         return array;
@@ -124,10 +124,8 @@ public class ExamInfoController extends BaseApiController {
             obj.accumulate("name", subject.getName());
             if (subject.getCardType() != null) {
                 obj.accumulate("cardType", subject.getCardType().getExtName());
-                obj.accumulate(
-                        "cardUrl",
-                        fileService.getFileServer()
-                                + fileService.getCardUri(subject.getExamId(), subject.getCode(), subject.getCardType()));
+                obj.accumulate("cardUrl", fileService.getFileServer()
+                        + fileService.getCardUri(subject.getExamId(), subject.getCode(), subject.getCardType()));
             }
             obj.accumulate("sliceConfig", StringUtils.trimToEmpty(subject.getSliceConfig()));
             array.add(obj);

+ 7 - 6
stmms-web/src/main/java/cn/com/qmth/stmms/api/controller/admin/ExamController.java

@@ -3,6 +3,8 @@ package cn.com.qmth.stmms.api.controller.admin;
 import java.math.BigDecimal;
 import java.util.*;
 
+import javax.validation.Valid;
+
 import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -170,7 +172,7 @@ public class ExamController extends BaseApiController {
     @ResponseBody
     @Logging(menu = "创建考试", type = LogType.ADD)
     @RequestMapping(value = "save", method = RequestMethod.POST)
-    public ResultMessage save(@RequestBody ExamVo vo) {
+    public ResultMessage save(@Valid @RequestBody ExamVo vo) {
         User user = getApiUser().getUser();
         Exam exam = ExamVo.of(vo);
         exam.setSchoolId(user.getSchoolId());
@@ -199,7 +201,6 @@ public class ExamController extends BaseApiController {
         Exam oldExam = examService.findById(exam.getId());
         if (oldExam != null && oldExam.getSchoolId().equals(user.getSchoolId())) {
             oldExam.setName(exam.getName());
-            oldExam.setExamTime(exam.getExamTime());
             oldExam.setDescription(exam.getDescription());
             oldExam.setStatus(exam.getStatus());
             oldExam.setForceSpecialTag(exam.getForceSpecialTag());
@@ -353,17 +354,17 @@ public class ExamController extends BaseApiController {
         ExamStudentSearchQuery query = new ExamStudentSearchQuery();
         query.setExamId(examId);
         query.setUpload(true);
-        query.setSheetCount(sheetCount/2);
+        query.setSheetCount(sheetCount / 2);
         List<ExamStudent> examStudents = examStudentService.findByQuery(query).getResult();
         if (examStudents.size() > 0) {
             ExamStudent student = examStudents.get(0);
-            List<String> sheetUris= fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1, sheetCount);
+            List<String> sheetUris = fileService.getSheetUris(student.getExamId(), student.getExamNumber(), 1,
+                    sheetCount);
             vo.setStudentUrl(sheetUris);
             return vo;
-        }else{
+        } else {
             throw new StatusException("没有已上传的考生");
         }
     }
 
-
 }

+ 16 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/common/support/CustomExceptionHandler.java

@@ -9,6 +9,9 @@ import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 
@@ -26,7 +29,19 @@ public class CustomExceptionHandler {
 
     @ExceptionHandler(Exception.class)
     public ResponseEntity<StatusResponse> handleException(Exception e, HttpServletRequest request) {
-        StatusResponse body = new StatusResponse(500, "系统异常");
+        StatusResponse body = null;
+        if (e instanceof MethodArgumentNotValidException) {
+            MethodArgumentNotValidException se = (MethodArgumentNotValidException) e;
+            StringBuilder sb = new StringBuilder();
+            BindingResult br = se.getBindingResult();
+            for (ObjectError be : br.getAllErrors()) {
+                sb.append(" " + be.getDefaultMessage());
+            }
+            body = new StatusResponse(500, sb.toString());
+        } else {
+            body = new StatusResponse(500, "系统异常");
+            log.error(e.getMessage(), e);
+        }
         return asResult(e, body, request);
     }
 

+ 24 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/common/support/MyObjectMapper.java

@@ -0,0 +1,24 @@
+package cn.com.qmth.stmms.common.support;
+
+import java.text.SimpleDateFormat;
+
+import org.springframework.context.annotation.Configuration;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+@Configuration
+public class MyObjectMapper extends ObjectMapper {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    public MyObjectMapper() {
+        super();
+        setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
+        configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
+    }
+
+}

+ 11 - 1
stmms-web/src/main/java/cn/com/qmth/stmms/common/support/ValuedEnumConverter.java

@@ -1,8 +1,11 @@
 package cn.com.qmth.stmms.common.support;
 
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.core.convert.converter.ConverterFactory;
 
+import cn.com.qmth.stmms.biz.exception.StatusException;
+
 @SuppressWarnings("rawtypes")
 public class ValuedEnumConverter implements ConverterFactory<String, Enum> {
 
@@ -21,7 +24,14 @@ public class ValuedEnumConverter implements ConverterFactory<String, Enum> {
 
         @Override
         public T convert(String source) {
-            return (T) Enum.valueOf(targetType, source);
+            if (StringUtils.isBlank(source)) {
+                return null;
+            }
+            try {
+                return (T) Enum.valueOf(targetType, source);
+            } catch (Exception e) {
+                throw new StatusException("枚举值:" + source + "不存在");
+            }
         }
     }
 }

+ 13 - 6
stmms-web/src/main/webapp/WEB-INF/spring-mvc.xml

@@ -110,14 +110,21 @@
             </list>
         </property>
     </bean> -->
-<mvc:annotation-driven conversion-service="conversionService"/>
- <bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionService">
-        <property name="converters">
+    
+<mvc:annotation-driven >
+    <mvc:message-converters register-defaults="true">
+            <bean 
+          class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
+        <property name="supportedMediaTypes">
             <list>
-                <bean class="cn.com.qmth.stmms.common.support.ValuedEnumConverter"/>
+                <value>application/json;charset=UTF-8</value>
             </list>
         </property>
+        <property name="objectMapper" ref="myObjectMapper"/>
     </bean>
+    </mvc:message-converters>
+</mvc:annotation-driven>
+ <bean class="cn.com.qmth.stmms.common.support.MyObjectMapper" id="myObjectMapper"/>
     <!-- 视图文件解析配置 -->
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/views/"/>
@@ -136,7 +143,7 @@
         <props> </props> </property> </bean> -->
 
     <!-- 配置SpringMVC @ResponseBody和@RequestBody注解 -->
-    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
+<!--     <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
         <property name="messageConverters">
             <list>
                 <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
@@ -152,7 +159,7 @@
                 <value>application/json;charset=UTF-8</value>
             </list>
         </property>
-    </bean>
+    </bean> -->
 
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
         <!--配置编码格式-->