Commit fb1bdf99 by tangyi

功能优化

parent c138889a
......@@ -2,6 +2,8 @@
交流QQ群:996208878
如果您觉得有帮助,请点右上角 "Star" 或者项目底部的“捐助”支持一下,谢谢!
## 简介
- 重写[spring-cloud-online-exam](https://gitee.com/wells2333/spring-cloud-online-exam)
......@@ -16,6 +18,12 @@
- 在线体验-后台:[http://www.it99.club:81](http://www.it99.club:81)
默认账号:
1. 管理员:admin/123456
2. 学生:student/123456
3. 教师:teacher/123456
## 技术选型
- 服务注册与发现:`Consul`
......
......@@ -20,4 +20,9 @@ public class MqConstant {
* 刷新路由
*/
public static final String REFRESH_GATEWAY_ROUTE_QUEUE = "refresh_gateway_route_queue";
/**
* 提交考试
*/
public static final String SUBMIT_EXAMINATION_QUEUE = "submit_examination_queue";
}
package com.github.tangyi.common.core.persistence;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.utils.DateUtils;
import com.github.tangyi.common.core.utils.IdGen;
import org.apache.commons.lang.StringUtils;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.LocalDateTime;
/**
* Entity基类
......@@ -63,14 +63,15 @@ public class BaseEntity<T> implements Serializable {
* @param applicationCode 系统编号
*/
public void setCommonValue(String userCode, String applicationCode) {
String currentDate = DateUtils.localDateToString(LocalDateTime.now());
if (this.isNewRecord()) {
this.setId(IdGen.snowflakeId());
this.setNewRecord(true);
this.creator = userCode;
this.createDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
this.createDate = currentDate;
}
this.modifier = userCode;
this.modifyDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
this.modifyDate = currentDate;
this.delFlag = 0;
this.applicationCode = applicationCode;
}
......
package com.github.tangyi.common.core.utils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 日期工具类
*
* @author tangyi
* @date 2019/4/28 16:03
*/
public class DateUtils {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter FORMATTER_MILLIS = DateTimeFormatter.ofPattern("yyyyMMddhhmmssSSS");
/**
* 日期转string
*
* @param date date
* @return String
*/
public static String localDateToString(LocalDateTime date) {
return date != null ? date.format(FORMATTER) : "";
}
/**
* 日期转string
*
* @param date date
* @return String
*/
public static String localDateMillisToString(LocalDateTime date) {
return date != null ? date.format(FORMATTER_MILLIS) : "";
}
}
......@@ -8,7 +8,9 @@ import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
......@@ -17,6 +19,10 @@ import java.util.*;
*/
public class ExcelToolUtil {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter FORMATTER_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
/**
* 根据数据和标题封装excel数据输出流
*
......@@ -36,10 +42,7 @@ public class ExcelToolUtil {
// 创建首行标题,设置高度
Row rowHeader = sh.createRow(0);
rowHeader.setHeightInPoints(16);
Iterator<String> keys = keys2titlesMap.keySet().iterator();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int i = 0;
List<String> keyList = new ArrayList<String>();
while (keys.hasNext()) {
......@@ -71,11 +74,13 @@ public class ExcelToolUtil {
if (dataMap.get(key) instanceof String) {
cell.setCellValue(MapUtil.getString(dataMap, key));
} else if (dataMap.get(key) instanceof Date) {
cell.setCellValue(simpleDateFormat.format(MapUtil.getDate(dataMap, key)));
Date date = MapUtil.getDate(dataMap, key);
cell.setCellValue(date == null ? "" : FORMATTER.format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())));
} else if (dataMap.get(key) instanceof Number) {
cell.setCellValue(MapUtil.getDouble(dataMap, key));
} else if (dataMap.get(key) instanceof Boolean) {
cell.setCellValue(MapUtil.getBooleanValue(dataMap, key));
Boolean value = MapUtil.getBooleanValue(dataMap, key);
cell.setCellValue(value == null ? Boolean.FALSE : value);
}
} else if (key.contains(".")) {
// 标题的名称对应的可以是对象
......@@ -214,7 +219,7 @@ public class ExcelToolUtil {
if (DateUtil.isCellDateFormatted(cell)) {
// 用于转化为日期格式
Date d = cell.getDateCellValue();
map.put(keys[cellnum], new SimpleDateFormat("yyyy-MM-dd").format(d));
map.put(keys[cellnum], FORMATTER_DATE.format(LocalDateTime.ofInstant(d.toInstant(), ZoneId.systemDefault())));
} else {
map.put(keys[cellnum], numToStringFormat(String.valueOf(cell.getNumericCellValue())));
}
......
......@@ -2,13 +2,13 @@ server:
port: 8090
spring:
datasource:
url: jdbc:mysql://${MYSQL_HOST:192.168.0.144}:${MYSQL_PORT:3306}/microservice-auth?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:platform}
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/microservice-auth?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:root}
password: ${MYSQL_PASSWORD:11}
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
redis:
host: ${REDIS_HOST:192.168.0.213}
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
rabbitmq:
host: ${RABBIT_HOST:localhost}
......
......@@ -2,13 +2,13 @@ server:
port: 8098
spring:
datasource:
url: jdbc:mysql://${MYSQL_HOST:192.168.0.144}:${MYSQL_PORT:3306}/microservice-exam?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:platform}
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/microservice-exam?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:root}
password: ${MYSQL_PASSWORD:11}
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
redis:
host: ${REDIS_HOST:192.168.0.213}
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
rabbitmq:
host: ${RABBIT_HOST:localhost}
......
......@@ -2,7 +2,7 @@ server:
port: 8000
spring:
redis:
host: ${REDIS_HOST:192.168.0.213}
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
rabbitmq:
host: ${RABBIT_HOST:localhost}
......@@ -68,8 +68,8 @@ preview:
enabled: ${PREVIEW_ENABLED:false}
ignores:
- token
- examRecord
- saveOrUpdate
- start
- saveAndNext
- register
- submit
- checkExist
......
......@@ -8,13 +8,13 @@ spring:
# 单次请求的文件的总大小
max-request-size: 100MB
datasource:
url: jdbc:mysql://${MYSQL_HOST:192.168.0.144}:${MYSQL_PORT:3306}/microservice-user?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:platform}
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/microservice-user?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&characterEncoding=UTF-8
username: ${MYSQL_USERNAME:root}
password: ${MYSQL_PASSWORD:11}
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
redis:
host: ${REDIS_HOST:192.168.0.213}
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
rabbitmq:
host: ${RABBIT_HOST:localhost}
......@@ -79,11 +79,11 @@ fdfs:
width: 150
height: 150
tracker-list: #TrackerList参数,支持多个
- ${FDFS_HOST:192.168.0.95}:${FDFS_PORT:22122}
- ${FDFS_HOST:182.254.233.125}:${FDFS_PORT:22122}
# 系统配置
sys:
fdfsHttpHost: ${ATTACHMENT_HOST:http://192.168.0.95}:${ATTACHMENT_PORT:80} # fastDfs的HTTP配置
fdfsHttpHost: ${ATTACHMENT_HOST:http://182.254.233.125}:${ATTACHMENT_PORT:80} # fastDfs的HTTP配置
uploadUrl: api/user/v1/attachment/upload
defaultAvatar: https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80
......
/*
Navicat Premium Data Transfer
Source Server : 144
Source Server : mysql_localhost
Source Server Type : MySQL
Source Server Version : 50710
Source Host : 192.168.0.144:3306
Source Server Version : 50617
Source Host : localhost:3306
Source Schema : microservice-auth
Target Server Type : MySQL
Target Server Version : 50710
Target Server Version : 50617
File Encoding : 65001
Date: 26/04/2019 23:22:30
Date: 03/05/2019 14:21:18
*/
SET NAMES utf8mb4;
......@@ -42,7 +42,7 @@ CREATE TABLE `oauth_client_details` (
`del_flag` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '删除标记',
`application_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '系统编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of oauth_client_details
......
/*
Navicat Premium Data Transfer
Source Server : 144
Source Server : mysql_localhost
Source Server Type : MySQL
Source Server Version : 50710
Source Host : 192.168.0.144:3306
Source Server Version : 50617
Source Host : localhost:3306
Source Schema : microservice-user
Target Server Type : MySQL
Target Server Version : 50710
Target Server Version : 50617
File Encoding : 65001
Date: 26/04/2019 23:21:27
Date: 08/05/2019 22:29:02
*/
SET NAMES utf8mb4;
......@@ -37,7 +37,7 @@ CREATE TABLE `sys_attachment` (
`del_flag` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '删除标记',
`application_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '系统编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_attachment
......@@ -65,7 +65,7 @@ CREATE TABLE `sys_dept` (
`dept_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门描述',
`dept_leader` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门负责人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_dept
......@@ -95,7 +95,7 @@ CREATE TABLE `sys_log` (
`del_flag` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '删除标记',
`application_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '系统编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for sys_menu
......@@ -121,7 +121,7 @@ CREATE TABLE `sys_menu` (
`redirect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '重定向url',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_menu
......@@ -216,7 +216,7 @@ CREATE TABLE `sys_role` (
`application_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '系统编号',
`status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态 0-启用,1-禁用',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_role
......@@ -234,7 +234,7 @@ CREATE TABLE `sys_role_dept` (
`role_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`dept_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_role_dept
......@@ -252,7 +252,7 @@ CREATE TABLE `sys_role_menu` (
`role_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`menu_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_role_menu
......@@ -381,7 +381,7 @@ CREATE TABLE `sys_route` (
`del_flag` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '删除标记',
`application_code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '系统编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_route
......@@ -416,7 +416,7 @@ CREATE TABLE `sys_user` (
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
`dept_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '部门ID',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_user
......@@ -434,7 +434,7 @@ CREATE TABLE `sys_user_role` (
`user_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`role_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_user_role
......
......@@ -16,17 +16,17 @@ REDIS_HOST=redis
REDIS_PORT=6379
// 数据库配置
MYSQL_HOST=192.168.0.144
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USERNAME=platform
MYSQL_PASSWORD=11
// FDFS配置
FDFS_HOST=192.168.0.95
FDFS_HOST=localhost
FDFS_PORT=22122
// 附件服务器配置
ATTACHMENT_HOST=http://192.168.0.95
ATTACHMENT_HOST=http://localhost
ATTACHMENT_PORT=80
// 各服务host配置
......
package com.github.tangyi.exam.config;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.service.ExaminationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.PostConstruct;
import java.util.Optional;
import java.util.stream.Stream;
/**
* 考试初始化
* 启动时加载已发布的考试到缓存
*
* @author tangyi
* @date 2019/4/30 16:02
*/
@Configuration
public class ExaminationInitConfig {
private static final Logger logger = LoggerFactory.getLogger(ExaminationInitConfig.class);
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ExaminationService examinationService;
@PostConstruct
public void initExamination() {
logger.info("开始加载考试信息.");
// 查询已发布的考试
Examination examination = new Examination();
examination.setStatus(CommonConstant.STATUS_NORMAL);
Stream<Examination> examinationStream = examinationService.findList(examination).stream();
if (Optional.ofNullable(examinationStream).isPresent())
examinationStream.forEach(tempExamination -> redisTemplate.opsForValue().set("examination::" + tempExamination.getId(), tempExamination));
logger.info("考试信息加载完成.");
}
}
package com.github.tangyi.exam.config;
import com.github.tangyi.common.core.constant.MqConstant;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MQ配置
*
* @author tangyi
* @date 2019/5/3 14:53
*/
@Configuration
public class RabbitSubmitExaminationConfig {
/**
* 提交考试队列
*
* @return Queue
*/
@Bean
public Queue submitExaminationQueue() {
return new Queue(MqConstant.SUBMIT_EXAMINATION_QUEUE);
}
}
......@@ -8,8 +8,10 @@ import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.core.web.BaseController;
import com.github.tangyi.common.log.annotation.Log;
import com.github.tangyi.common.security.utils.SecurityUtil;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.service.AnswerService;
import com.github.tangyi.exam.service.SubjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
......@@ -17,7 +19,6 @@ import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
......@@ -38,6 +39,9 @@ public class AnswerController extends BaseController {
@Autowired
private AnswerService answerService;
@Autowired
private SubjectService subjectService;
/**
* 根据ID获取
*
......@@ -155,24 +159,27 @@ public class AnswerController extends BaseController {
* @author tangyi
* @date 2018/12/24 20:06
*/
@PostMapping("saveOrUpdate")
@PostMapping("save")
@ApiOperation(value = "保存答题", notes = "保存答题")
@ApiImplicitParam(name = "answer", value = "答题信息", dataType = "Answer")
@Log("保存答题")
public ResponseBean<Boolean> saveOrUpdate(@RequestBody Answer answer) {
boolean success;
Answer search = new Answer();
BeanUtils.copyProperties(answer, search);
search = answerService.getAnswer(search);
if (search == null) {
answer.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
success = answerService.insert(answer) > 0;
} else {
search.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
search.setAnswer(answer.getAnswer());
success = answerService.update(search) > 0;
}
return new ResponseBean<>(success);
public ResponseBean<Boolean> save(@RequestBody Answer answer) {
return new ResponseBean<>(answerService.save(answer) > 0);
}
/**
* 保存答题,返回下一题信息
*
* @param answer answer
* @return ResponseBean
* @author tangyi
* @date 2019/04/30 18:06
*/
@PostMapping("saveAndNext")
@ApiOperation(value = "保存答题", notes = "保存答题")
@ApiImplicitParam(name = "answer", value = "答题信息", dataType = "Answer")
public ResponseBean<SubjectDto> saveAndNext(@RequestBody Answer answer) {
return new ResponseBean<>(answerService.saveAndNext(answer));
}
/**
......@@ -188,6 +195,6 @@ public class AnswerController extends BaseController {
@ApiImplicitParam(name = "answer", value = "答卷信息", dataType = "Answer")
@Log("提交答题")
public ResponseBean<Boolean> submit(@RequestBody Answer answer) {
return new ResponseBean<>(answerService.submit(answer));
return new ResponseBean<>(answerService.submitAsync(answer));
}
}
......@@ -12,6 +12,7 @@ import com.github.tangyi.common.log.annotation.Log;
import com.github.tangyi.common.security.constant.SecurityConstant;
import com.github.tangyi.common.security.utils.SecurityUtil;
import com.github.tangyi.exam.api.dto.ExamRecordDto;
import com.github.tangyi.exam.api.dto.StartExamDto;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.service.ExamRecordService;
......@@ -34,8 +35,11 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
/**
......@@ -136,6 +140,11 @@ public class ExamRecordController extends BaseController {
examRecordDto.setEndTime(tempExamRecord.getEndTime());
examRecordDto.setScore(tempExamRecord.getScore());
examRecordDto.setUserId(tempExamRecord.getUserId());
// 正确题目数
examRecordDto.setCorrectNumber(tempExamRecord.getCorrectNumber());
examRecordDto.setInCorrectNumber(tempExamRecord.getInCorrectNumber());
// 提交状态
examRecordDto.setSubmitStatus(tempExamRecord.getSubmitStatus());
examRecordDtoList.add(examRecordDto);
}
});
......@@ -265,7 +274,7 @@ public class ExamRecordController extends BaseController {
// 配置response
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "考试成绩" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()) + ".xlsx"));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "考试成绩" + DateUtils.localDateMillisToString(LocalDateTime.now()) + ".xlsx"));
List<ExamRecord> examRecordList;
if (StringUtils.isNotEmpty(examRecordDto.getIdString())) {
ExamRecord examRecord = new ExamRecord();
......@@ -339,4 +348,30 @@ public class ExamRecordController extends BaseController {
logger.error("导出成绩数据失败!", e);
}
}
/**
* 开始考试
*
* @param examRecord examRecord
* @return ResponseBean
* @author tangyi
* @date 2019/04/30 16:45
*/
@PostMapping("start")
@Log("开始考试")
public ResponseBean<StartExamDto> start(@RequestBody ExamRecord examRecord) {
return new ResponseBean<>(examRecordService.start(examRecord));
}
/**
* 获取服务器当前时间
*
* @return ResponseBean
* @author tangyi
* @date 2019/05/07 22:03
*/
@GetMapping("currentTime")
public ResponseBean<String> currentTime() {
return new ResponseBean<>(DateUtils.localDateToString(LocalDateTime.now()));
}
}
......@@ -3,6 +3,7 @@ package com.github.tangyi.exam.controller;
import com.github.pagehelper.PageInfo;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.model.ResponseBean;
import com.github.tangyi.common.core.utils.DateUtils;
import com.github.tangyi.common.core.utils.PageUtil;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.core.web.BaseController;
......@@ -27,8 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
......@@ -67,9 +67,6 @@ public class ExaminationController extends BaseController {
if (StringUtils.isNotBlank(id)) {
examination.setId(id);
examination = examinationService.get(examination);
// 获取当前时间
if (examination != null)
examination.setCurrentTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
return new ResponseBean<>(examination);
}
......@@ -108,17 +105,12 @@ public class ExaminationController extends BaseController {
// 流处理获取课程ID集合,转成字符串数组
course.setIds(page.getList().stream().map(Examination::getCourseId).distinct().toArray(String[]::new));
List<Course> courses = courseService.findListById(course);
// 当前时间
String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
// 流处理转成Dto集合
List<ExaminationDto> examinationDtos = page.getList().stream().map(exam -> {
ExaminationDto examinationDto = new ExaminationDto();
BeanUtils.copyProperties(exam, examinationDto);
examinationDto.setCurrentTime(currentTime);
// 设置考试所属课程
Course examinationCourse = courses.stream().filter(tempCourse -> tempCourse.getId().equals(exam.getCourseId())).findFirst().orElse(null);
if (examinationCourse != null)
examinationDto.setCourse(examinationCourse);
courses.stream().filter(tempCourse -> tempCourse.getId().equals(exam.getCourseId())).findFirst().ifPresent(examinationDto::setCourse);
return examinationDto;
}).collect(Collectors.toList());
examinationDtoPageInfo.setList(examinationDtos);
......
......@@ -116,6 +116,9 @@ public class IncorrectAnswerController extends BaseController {
});
}
}
pageInfo.setPageSize(incorrectAnswerPageInfo.getPageSize());
pageInfo.setPageNum(incorrectAnswerPageInfo.getPageNum());
pageInfo.setTotal(incorrectAnswerPageInfo.getTotal());
pageInfo.setList(incorrectAnswerDtoList);
return pageInfo;
}
......
......@@ -27,9 +27,8 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
......@@ -201,7 +200,7 @@ public class SubjectBankController extends BaseController {
// 配置response
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "题目信息" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()) + ".xlsx"));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "题目信息" + DateUtils.localDateMillisToString(LocalDateTime.now()) + ".xlsx"));
List<SubjectBank> subjectBanks = new ArrayList<>();
// 根据题目id导出
if (StringUtils.isNotEmpty(subjectBankDto.getIdString())) {
......
......@@ -9,8 +9,6 @@ import com.github.tangyi.common.log.annotation.Log;
import com.github.tangyi.common.security.constant.SecurityConstant;
import com.github.tangyi.common.security.utils.SecurityUtil;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.api.module.Subject;
import com.github.tangyi.exam.service.AnswerService;
......@@ -20,11 +18,9 @@ import com.github.tangyi.exam.service.SubjectService;
import com.github.tangyi.exam.utils.SubjectUtil;
import com.google.common.net.HttpHeaders;
import io.swagger.annotations.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
......@@ -32,8 +28,11 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
......@@ -210,7 +209,7 @@ public class SubjectController extends BaseController {
// 配置response
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "题目信息" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()) + ".xlsx"));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "题目信息" + DateUtils.localDateMillisToString(LocalDateTime.now()) + ".xlsx"));
List<Subject> subjects = new ArrayList<>();
// 根据题目id导出
if (StringUtils.isNotEmpty(subjectDto.getIdString())) {
......@@ -336,35 +335,6 @@ public class SubjectController extends BaseController {
public ResponseBean<SubjectDto> subjectAnswer(@RequestParam("serialNumber") String serialNumber,
@RequestParam("examRecordId") String examRecordId,
@RequestParam(value = "userId", required = false) String userId) {
SubjectDto subjectDto = null;
ExamRecord examRecord = new ExamRecord();
examRecord.setId(examRecordId);
// 查找考试记录
examRecord = examRecordService.get(examRecord);
if (examRecord != null) {
// 查找题目
Subject subject = new Subject();
subject.setExaminationId(examRecord.getExaminationId());
subject.setSerialNumber(serialNumber);
subject = subjectService.getByExaminationIdAndSerialNumber(subject);
if (subject != null) {
subjectDto = new SubjectDto();
// 查找答题
Answer answer = new Answer();
answer.setSubjectId(subject.getId());
answer.setExaminationId(examRecord.getExaminationId());
answer.setExamRecordId(examRecordId);
answer.setUserId(userId);
List<Answer> answerList = answerService.findList(answer);
if (answerList != null && answerList.size() == 1) {
answer = answerList.get(0);
}
BeanUtils.copyProperties(subject, subjectDto);
// 设置答题
subjectDto.setAnswer(answer);
subjectDto.setExaminationRecordId(examRecordId);
}
}
return new ResponseBean<>(subjectDto);
return new ResponseBean<>(subjectService.subjectAnswer(serialNumber, examRecordId, userId));
}
}
......@@ -15,6 +15,7 @@ public interface AnswerMapper extends CrudMapper<Answer> {
/**
* 根据用户ID、考试ID、考试记录ID、题目ID查找答题
*
* @param answer answer
* @return Answer
* @author tangyi
......
package com.github.tangyi.exam.mq;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.exceptions.CommonException;
import com.github.tangyi.exam.api.constants.ExamRecordConstant;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.service.AnswerService;
import com.github.tangyi.exam.service.ExamRecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 提交考试消息消费者
*
* @author tangyi
* @date 2019/5/3 14:55
*/
@Service
public class RabbitSubmitExaminationReceiver {
private static final Logger logger = LoggerFactory.getLogger(RabbitSubmitExaminationReceiver.class);
@Autowired
private AnswerService answerService;
@Autowired
private ExamRecordService examRecordService;
/**
* 处理提交考试逻辑:统计错题,计算成绩等
* 1. 先更新考试记录的状态为正在计算
* 2. 更新成功则执行提交逻辑
*
* @param answer answer
* @author tangyi
* @date 2019/05/03 14:56
*/
@RabbitListener(queues = {MqConstant.SUBMIT_EXAMINATION_QUEUE})
public void submitExamination(Answer answer) {
logger.debug("处理考试提交ID:{}, 提交人:{}", answer.getExamRecordId(), answer.getModifier());
try {
ExamRecord examRecord = new ExamRecord();
examRecord.setId(answer.getExamRecordId());
examRecord = examRecordService.get(examRecord);
if (examRecord == null)
return;
if (ExamRecordConstant.STATUS_NOT_SUBMITTED.equals(examRecord.getSubmitStatus()))
logger.warn("考试:{}未提交", examRecord.getId());
if (ExamRecordConstant.STATUS_CALCULATE.equals(examRecord.getSubmitStatus()))
logger.warn("考试:{}正在统计成绩,请勿重复提交", examRecord.getId());
// 更新状态为正在统计
examRecord.setSubmitStatus(ExamRecordConstant.STATUS_CALCULATE);
// 更新成功
if (examRecordService.update(examRecord) > 0) {
logger.debug("考试:{}更新状态为正在统计成功", examRecord.getId());
answerService.submit(answer);
} else {
logger.warn("考试:{}更新状态为正在统计失败", examRecord.getId());
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
package com.github.tangyi.exam.service;
import com.github.tangyi.common.core.constant.MqConstant;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.security.utils.SecurityUtil;
import com.github.tangyi.exam.api.constants.ExamRecordConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.IncorrectAnswer;
import com.github.tangyi.exam.api.module.Subject;
import com.github.tangyi.exam.mapper.AnswerMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
......@@ -28,6 +32,9 @@ import java.util.List;
public class AnswerService extends CrudService<AnswerMapper, Answer> {
@Autowired
private AmqpTemplate amqpTemplate;
@Autowired
private SubjectService subjectService;
@Autowired
......@@ -108,8 +115,43 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
}
/**
* 保存
*
* @param answer answer
* @return int
* @author tangyi
* @date 2019/04/30 18:03
*/
@Transactional
public int save(Answer answer) {
answer.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
return super.save(answer);
}
/**
* 保存答题,返回下一题信息
*
* @param answer answer
* @return SubjectDto
* @author tangyi
* @date 2019/05/01 11:42
*/
@Transactional
public SubjectDto saveAndNext(Answer answer) {
Answer tempAnswer = this.getAnswer(answer);
if (tempAnswer != null) {
tempAnswer.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
tempAnswer.setAnswer(answer.getAnswer());
this.update(tempAnswer);
} else {
answer.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
this.insert(answer);
}
return subjectService.subjectAnswer(answer.getSerialNumber(), answer.getExamRecordId(), answer.getUserId());
}
/**
* 提交答卷
* TODO 通过mq异步处理
*
* @param answer answer
* @return boolean
......@@ -120,7 +162,7 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
public boolean submit(Answer answer) {
long start = System.currentTimeMillis();
boolean success = false;
String currentUsername = SecurityUtil.getCurrentUsername();
String currentUsername = answer.getModifier();
// 查找已提交的题目
List<Answer> answerList = findList(answer);
if (CollectionUtils.isNotEmpty(answerList)) {
......@@ -166,12 +208,14 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
});
// 保存成绩
ExamRecord examRecord = new ExamRecord();
examRecord.setCommonValue(SecurityUtil.getCurrentUsername(), SysUtil.getSysCode());
examRecord.setCommonValue(currentUsername, SysUtil.getSysCode());
examRecord.setId(answer.getExamRecordId());
examRecord.setEndTime(examRecord.getCreateDate());
examRecord.setScore(Integer.toString(totalScore));
examRecord.setCorrectNumber(String.valueOf(rightScore.size()));
examRecord.setInCorrectNumber(String.valueOf(incorrectAnswers.size()));
// 更新状态为统计完成
examRecord.setSubmitStatus(ExamRecordConstant.STATUS_CALCULATED);
success = examRecordService.update(examRecord) > 0;
// 保存错题
ExamRecord searchExamRecord = new ExamRecord();
......@@ -189,4 +233,34 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
logger.debug("提交答卷,用户名:{},考试ID:{},耗时:{}ms", currentUsername, answer.getExaminationId(), System.currentTimeMillis() - start);
return success;
}
/**
* 通过mq异步处理
* 1. 先发送消息
* 2. 发送消息成功,更新提交状态,发送失败,返回提交失败
* 3. 消费消息,计算成绩
*
* @param answer answer
* @return boolean
* @author tangyi
* @date 2019/05/03 14:35
*/
@Transactional
public boolean submitAsync(Answer answer) {
long start = System.currentTimeMillis();
String currentUsername = SecurityUtil.getCurrentUsername();
answer.setModifier(currentUsername);
ExamRecord examRecord = new ExamRecord();
examRecord.setCommonValue(currentUsername, SysUtil.getSysCode());
examRecord.setId(answer.getExamRecordId());
// 提交时间
examRecord.setEndTime(examRecord.getCreateDate());
examRecord.setSubmitStatus(ExamRecordConstant.STATUS_SUBMITTED);
// 1. 发送消息
amqpTemplate.convertAndSend(MqConstant.SUBMIT_EXAMINATION_QUEUE, answer);
// 2. 更新考试状态
boolean success = examRecordService.update(examRecord) > 0;
logger.debug("异步提交答卷成功,提交人:{},考试ID:{},耗时:{}ms", currentUsername, answer.getExaminationId(), System.currentTimeMillis() - start);
return success;
}
}
package com.github.tangyi.exam.service;
import com.github.tangyi.common.core.exceptions.CommonException;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.exam.mapper.ExamRecordMapper;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.security.utils.SecurityUtil;
import com.github.tangyi.exam.api.constants.ExamRecordConstant;
import com.github.tangyi.exam.api.constants.SubjectConstant;
import com.github.tangyi.exam.api.dto.StartExamDto;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.api.module.Subject;
import com.github.tangyi.exam.mapper.ExamRecordMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
......@@ -17,6 +30,18 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class ExamRecordService extends CrudService<ExamRecordMapper, ExamRecord> {
@Autowired
private SubjectService subjectService;
@Autowired
private AnswerService answerService;
@Autowired
private ExamRecordService examRecordService;
@Autowired
private ExaminationService examinationService;
/**
* 查询考试记录
*
......@@ -87,4 +112,67 @@ public class ExamRecordService extends CrudService<ExamRecordMapper, ExamRecord>
public int deleteAll(String[] ids) {
return super.deleteAll(ids);
}
/**
* 开始考试
*
* @param examRecord examRecord
* @return StartExamDto
* @author tangyi
* @date 2019/04/30 23:06
*/
@Transactional
public StartExamDto start(ExamRecord examRecord) {
StartExamDto startExamDto = new StartExamDto();
String currentUsername = SecurityUtil.getCurrentUsername(), applicationCode = SysUtil.getSysCode();
// 创建考试记录
if (StringUtils.isEmpty(examRecord.getExaminationId()))
throw new CommonException("参数校验失败,考试id为空!");
if (StringUtils.isEmpty(examRecord.getUserId()))
throw new CommonException("参数校验失败,用户id为空!");
Examination examination = new Examination();
examination.setId(examRecord.getExaminationId());
// 查找考试信息
examination = examinationService.get(examination);
if (examination != null) {
examRecord.setExaminationName(examination.getExaminationName());
examRecord.setCourseId(examination.getCourseId());
}
examRecord.setCommonValue(currentUsername, applicationCode);
examRecord.setStartTime(examRecord.getCreateDate());
// 默认未提交状态
examRecord.setSubmitStatus(ExamRecordConstant.STATUS_NOT_SUBMITTED);
// 保存考试记录
if (examRecordService.insert(examRecord) > 0) {
startExamDto.setExamination(examination);
startExamDto.setExamRecord(examRecord);
// 封装dto
SubjectDto subjectDto = new SubjectDto();
startExamDto.setSubjectDto(subjectDto);
// 查找第一题
Subject subject = new Subject();
subject.setExaminationId(examRecord.getExaminationId());
subject.setSerialNumber(SubjectConstant.DEFAULT_SERIAL_NUMBER);
subject = subjectService.getByExaminationIdAndSerialNumber(subject);
if (subject == null)
throw new CommonException("没有第一题");
// 获取题目信息
BeanUtils.copyProperties(subject, subjectDto);
// 创建第一题的答题
Answer answer = new Answer();
answer.setCommonValue(currentUsername, applicationCode);
answer.setUserId(examRecord.getUserId());
answer.setExaminationId(examRecord.getExaminationId());
answer.setExamRecordId(examRecord.getId());
answer.setSubjectId(subject.getId());
// 默认题号为1
answer.setSerialNumber(subject.getSerialNumber());
// 保存答题
answerService.save(answer);
subjectDto.setAnswer(answer);
}
return startExamDto;
}
}
package com.github.tangyi.exam.service;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.exam.mapper.ExaminationMapper;
import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.api.module.Subject;
import com.github.tangyi.exam.mapper.ExaminationMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
......@@ -89,6 +89,7 @@ public class ExaminationService extends CrudService<ExaminationMapper, Examinati
/**
* 查询考试数量
*
* @param examination examination
* @return int
* @author tangyi
......
package com.github.tangyi.exam.service;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.exam.mapper.SubjectMapper;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.Subject;
import com.github.tangyi.exam.mapper.SubjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
......@@ -17,6 +22,12 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public class SubjectService extends CrudService<SubjectMapper, Subject> {
@Autowired
private ExamRecordService examRecordService;
@Autowired
private AnswerService answerService;
/**
* 查找题目
*
......@@ -113,4 +124,46 @@ public class SubjectService extends CrudService<SubjectMapper, Subject> {
public int deleteAll(String[] ids) {
return super.deleteAll(ids);
}
/**
* 查询题目和答题
*
* @param serialNumber serialNumber
* @param examRecordId examRecordId
* @param userId userId
* @return SubjectDto
* @author tangyi
* @date 2019/04/30 17:10
*/
@Transactional
public SubjectDto subjectAnswer(String serialNumber, String examRecordId, String userId) {
SubjectDto subjectDto = null;
ExamRecord examRecord = new ExamRecord();
examRecord.setId(examRecordId);
// 查找考试记录
examRecord = examRecordService.get(examRecord);
if (examRecord != null) {
// 查找题目
Subject subject = new Subject();
subject.setExaminationId(examRecord.getExaminationId());
subject.setSerialNumber(serialNumber);
subject = this.getByExaminationIdAndSerialNumber(subject);
if (subject != null) {
subjectDto = new SubjectDto();
// 查找答题
Answer answer = new Answer();
answer.setSubjectId(subject.getId());
answer.setExaminationId(examRecord.getExaminationId());
answer.setExamRecordId(examRecordId);
answer.setUserId(userId);
Answer userAnswer = answerService.getAnswer(answer);
// 设置答题
if (userAnswer != null)
subjectDto.setAnswer(userAnswer);
BeanUtils.copyProperties(subject, subjectDto);
subjectDto.setExaminationRecordId(examRecordId);
}
}
return subjectDto;
}
}
......@@ -67,7 +67,7 @@
and a.examination_id = #{examinationId}
and a.exam_record_id = #{examRecordId}
and a.subject_id = #{subjectId}
</select>
</select>
<select id="findList" resultMap="answerResultMap">
SELECT
......
......@@ -12,6 +12,7 @@
<result column="score" property="score"/>
<result column="correct_number" property="correctNumber"/>
<result column="incorrect_number" property="inCorrectNumber"/>
<result column="submit_status" property="submitStatus"/>
<result column="creator" property="creator"/>
<result column="create_date" property="createDate"/>
<result column="modifier" property="modifier"/>
......@@ -31,6 +32,7 @@
a.score,
a.correct_number,
a.incorrect_number,
a.submit_status,
a.creator,
a.create_date,
a.modifier,
......@@ -53,6 +55,9 @@
<if test="courseId != null and courseId != ''">
and a.course_id = #{courseId}
</if>
<if test="submitStatus != null and submitStatus != ''">
and a.submit_status = #{submitStatus}
</if>
</sql>
<select id="get" resultMap="examRecordResultMap">
......@@ -99,6 +104,7 @@
score,
correct_number,
incorrect_number,
submit_status,
creator,
create_date,
modifier,
......@@ -116,6 +122,7 @@
#{score},
#{correctNumber},
#{inCorrectNumber},
#{submitStatus},
#{creator},
#{createDate},
#{modifier},
......@@ -154,6 +161,9 @@
<if test="inCorrectNumber != null">
incorrect_number = #{inCorrectNumber},
</if>
<if test="submitStatus != null">
submit_status = #{submitStatus},
</if>
<if test="delFlag != null">
del_flag = #{delFlag},
</if>
......
......@@ -25,8 +25,11 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
......@@ -264,7 +267,7 @@ public class MenuController extends BaseController {
// 配置response
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "菜单信息" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()) + ".xlsx"));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "菜单信息" + DateUtils.localDateMillisToString(LocalDateTime.now()) + ".xlsx"));
List<Menu> menus;
// 导出所有
if (StringUtils.isEmpty(menuVo.getIdString())) {
......
......@@ -36,9 +36,8 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
......@@ -304,7 +303,7 @@ public class UserController extends BaseController {
// 配置response
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "用户信息" + new SimpleDateFormat("yyyyMMddhhmmssSSS").format(new Date()) + ".xlsx"));
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, Servlets.getDownName(request, "用户信息" + DateUtils.localDateMillisToString(LocalDateTime.now()) + ".xlsx"));
List<User> users;
if (StringUtils.isNotEmpty(userVo.getIdString())) {
User user = new User();
......
package com.github.tangyi.exam.api.constants;
/**
* @author tangyi
* @date 2019/5/3 14:41
*/
public class ExamRecordConstant {
/**
* 未提交
*/
public static final String STATUS_NOT_SUBMITTED = "0";
/**
* 已提交
*/
public static final String STATUS_SUBMITTED = "1";
/**
* 正在统计
*/
public static final String STATUS_CALCULATE = "2";
/**
* 统计完成
*/
public static final String STATUS_CALCULATED = "3";
}
package com.github.tangyi.exam.api.constants;
/**
* @author tangyi
* @date 2019/4/30 17:17
*/
public class SubjectConstant {
/**
* 默认的题目序号
*/
public static final String DEFAULT_SERIAL_NUMBER = "1";
}
......@@ -105,6 +105,21 @@ public class ExamRecordDto extends BaseEntity<ExamRecordDto> {
*/
private String examTime;
/**
* 错误题目数量
*/
private String inCorrectNumber;
/**
* 正确题目数量
*/
private String correctNumber;
/**
* 提交状态 1-已提交 0-未提交
*/
private String submitStatus;
public String getExaminationName() {
return examinationName;
}
......@@ -256,4 +271,28 @@ public class ExamRecordDto extends BaseEntity<ExamRecordDto> {
public void setExamTime(String examTime) {
this.examTime = examTime;
}
public String getSubmitStatus() {
return submitStatus;
}
public void setSubmitStatus(String submitStatus) {
this.submitStatus = submitStatus;
}
public String getInCorrectNumber() {
return inCorrectNumber;
}
public void setInCorrectNumber(String inCorrectNumber) {
this.inCorrectNumber = inCorrectNumber;
}
public String getCorrectNumber() {
return correctNumber;
}
public void setCorrectNumber(String correctNumber) {
this.correctNumber = correctNumber;
}
}
package com.github.tangyi.exam.api.dto;
import com.github.tangyi.exam.api.module.ExamRecord;
import com.github.tangyi.exam.api.module.Examination;
import java.io.Serializable;
/**
* @author tangyi
* @date 2019/4/30 16:54
*/
public class StartExamDto implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 考试记录信息
*/
private ExamRecord examRecord;
/**
* 考试信息
*/
private Examination examination;
/**
* 题目信息
*/
private SubjectDto subjectDto;
public ExamRecord getExamRecord() {
return examRecord;
}
public void setExamRecord(ExamRecord examRecord) {
this.examRecord = examRecord;
}
public Examination getExamination() {
return examination;
}
public void setExamination(Examination examination) {
this.examination = examination;
}
public SubjectDto getSubjectDto() {
return subjectDto;
}
public void setSubjectDto(SubjectDto subjectDto) {
this.subjectDto = subjectDto;
}
}
......@@ -40,6 +40,11 @@ public class Answer extends BaseEntity<Answer> {
*/
private String answer;
/**
* 下一题题目序号
*/
private String serialNumber;
public String getUserId() {
return userId;
}
......@@ -87,4 +92,12 @@ public class Answer extends BaseEntity<Answer> {
public void setExamRecordId(String examRecordId) {
this.examRecordId = examRecordId;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
}
......@@ -55,6 +55,11 @@ public class ExamRecord extends BaseEntity<ExamRecord> {
*/
private String correctNumber;
/**
* 提交状态 1-已提交 0-未提交
*/
private String submitStatus;
public String getUserId() {
return userId;
}
......@@ -126,4 +131,12 @@ public class ExamRecord extends BaseEntity<ExamRecord> {
public void setCorrectNumber(String correctNumber) {
this.correctNumber = correctNumber;
}
public String getSubmitStatus() {
return submitStatus;
}
public void setSubmitStatus(String submitStatus) {
this.submitStatus = submitStatus;
}
}
......@@ -26,11 +26,6 @@ public class Examination extends BaseEntity<Examination> {
private String attention;
/**
* 当前时间
*/
private String currentTime;
/**
* 考试开始时间
*/
private String startTime;
......@@ -194,14 +189,6 @@ public class Examination extends BaseEntity<Examination> {
this.remark = remark;
}
public String getCurrentTime() {
return currentTime;
}
public void setCurrentTime(String currentTime) {
this.currentTime = currentTime;
}
public String getTotalSubject() {
return totalSubject;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment