Commit 56bc7c05 by tangyi

优化

parent f0c822a6
Version v3.5.0 (2020-01-19)
--------------------------
改进:
* 支持不定项选项
* 多处优化
Version v3.5.0 (2019-12-08)
--------------------------
......
# 1 简介
<h1 align="center">Welcome to spring-microservice-exam 👋</h1>
<p>
<img alt="Version" src="https://img.shields.io/badge/version-3.5.0-blue.svg?cacheSeconds=2592000" />
<a href="https://www.kancloud.cn/tangyi/spring-microservice-exam/1322864" target="_blank">
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
</a>
<a href="#" target="_blank">
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" />
</a>
</p>
硕果云,基于Spring Cloud搭建的新一代微服务教学管理平台,提供多租户、权限管理、考试、练习等功能。
> 硕果云,基于Spring Cloud搭建的新一代微服务教学管理平台,提供多租户、权限管理、考试、练习等功能。
# 2 在线体验
### 🏠 [主页](https://gitee.com/wells2333/spring-microservice-exam)
- 前台:[http://118.25.138.130](http://118.25.138.130)
### ✨ [在线体验-前台](http://118.25.138.130)
- 后台:[http://118.25.138.130:81](http://118.25.138.130:81)
### ✨ [在线体验-后台](http://118.25.138.130:81)
账号:
测试账号:
| 单位ID | 账号 | 密码 | 角色 |
| --------- | -------- | -------- | -------- |
......@@ -16,7 +25,7 @@
| gitee | student | 123456 | 学生 |
| gitee | teacher | 123456 | 老师 |
# 3 技术选型
## 技术选型
- 服务注册与发现:`Consul`
- 熔断器:`Hystrix` + `Turbine`
......@@ -32,22 +41,22 @@
- 构建工具:`Maven`
- 后台 API 文档:`Swagger`
- 消息队列:`RabbitMQ`
- 文件系统:`FastDFS`
- 文件系统:`七牛云`
- 缓存:`Redis`
- 前端:`vue`
# 4 核心依赖
## 核心依赖
| 名称 | 版本 |
| --------- | -------- |
| `Spring Boot` | `2.1.11.RELEASE` |
| `Spring Cloud` | `Greenwich.SR4` |
# 5 系统架构
## 系统架构
![image](docs/images/系统架构图v3.0.jpg)
# 6 功能概述
## 功能概述
项目分前台网站和后台管理两部分,前台主要提供考试功能,后台提供基础管理、考试管理功能。
......@@ -84,9 +93,9 @@
- 个人资料:姓名、头像等基本信息的修改
- 修改密码:修改密码
# 7 功能演示
## 系统截图
## 7.1 前台功能
### 前台功能
1. 首页
![image](docs/images/image_web.png)
......@@ -94,10 +103,7 @@
2. 考试
![image](docs/images/image_web_exam.png)
3. 查看错题
![image](docs/images/image_web_incorrect_answer.png)
## 7.2 后台功能
### 后台功能
1. 总体功能
![image](docs/images/image_ui_menu.png)
......@@ -108,16 +114,7 @@
3. 题目管理
![image](docs/images/image_ui_subjects_rich_edit.png)
4. 个人资料
![image](docs/images/image_ui_msg.png)
# 8 问题反馈
欢迎提交 issue,请写清楚遇到问题的原因、浏览器、操作系统环境、重现的流程和报错日志等。
如果有开发能力,建议在本地调试出出错的代码。
# 9 参考资料
## 部署文档
- [在线考试系统-部署文档](https://www.kancloud.cn/tangyi/spring-microservice-exam/1322870)
......@@ -129,14 +126,28 @@
- [在线考试系统V3.0镜像构建、推送、部署](http://ehedgehog.net/2019/04/22/%E5%9C%A8%E7%BA%BF%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9FV2.0%E9%95%9C%E5%83%8F%E6%9E%84%E5%BB%BA%E3%80%81%E6%8E%A8%E9%80%81%E3%80%81%E9%83%A8%E7%BD%B2/)
***
## 作者
👤 **tangyi**
# 10 关于
* Gitee: [@wells2333](https://gitee.com/wells2333)
交流QQ群:<a target="_blank" href="https://jq.qq.com/?_wv=1027&k=5RKZNF2"><img border="0" src="http://pub.idqqimg.com/wpa/images/group.png" alt="Spring Cloud考试系统学习" title="Spring Cloud考试系统学习"></a>
* Github: [@wells2333](https://github.com/wells2333)
QQ群号:996208878,二维码:
## 🤝 参与贡献
<img src="http://118.25.138.130/static/img/WechatIMG4.c775d3e.png" alt="Spring Cloud考试系统学习" title="Spring Cloud考试系统学习">
欢迎提交PR、[issues](https://gitee.com/wells2333/spring-microservice-exam/issues)一起完善项目
如果您觉得有帮助,请点右上角 "Star" 或者项目底部的“捐助”支持一下,谢谢!
\ No newline at end of file
## 反馈交流
交流QQ群:
![image](docs/images/qq.png) ![image](docs/images/qq_new.png)
## 请作者喝咖啡
如果您觉得有帮助,请点右上角 ⭐️ "Star" 或者**微信扫一扫**支持一下,谢谢!
![image](docs/images/wechat.png)
***
......@@ -60,10 +60,10 @@ export function delAllSubject (obj) {
// 导出
export function exportSubject (ids, examinationId, categoryId) {
let url = baseSubjectUrl + 'export?'
if (examinationId !== null && examinationId !== '') {
if (examinationId !== undefined && examinationId !== null && examinationId !== '') {
url = url + 'examinationId=' + examinationId
}
if (categoryId !== null && categoryId !== '') {
if (categoryId !== undefined && categoryId !== null && categoryId !== '') {
url = url + '&categoryId=' + categoryId
}
return request({
......
......@@ -175,15 +175,13 @@ export default {
analysis: '',
level: 2
}
// 默认序号
if (isNotEmpty(serialNumber)) {
this.subjectInfo.serialNumber = serialNumber
}
// 默认分数
if (isNotEmpty(score)) {
this.subjectInfo.score = score
}
},
initDefaultOptions() {
}
}
}
......
......@@ -43,6 +43,7 @@ export default {
data () {
return {
hasChange: false,
hasClick: false,
hasInit: false,
tinymceId: this.id,
fullscreen: false,
......@@ -112,6 +113,11 @@ export default {
this.hasChange = true
this.$emit('input', editor.getContent())
})
editor.on('Click', () => {
this.hasClick = true
this.$emit('hasClick', this.hasClick)
})
},
setup (editor) {
editor.on('FullscreenStateChanged', (e) => {
......@@ -130,6 +136,12 @@ export default {
},
getContent () {
return window.tinymce.get(this.tinymceId).getContent()
},
getHasClick () {
return this.hasClick
},
setHashClick (click) {
this.hasClick = click
}
}
}
......
import { formatDate, commonFilter, isNotEmpty } from '../utils/util'
import { statusType, examType, subjectType } from '../utils/constant'
/**
* 日期格式化
* @param date
* @param format
* @returns {*}
*/
export function fmtDate (date, format) {
if (!isNotEmpty(date)) {
return ''
}
return formatDate(new Date(date), format)
}
/**
* 通用状态
* @param status
* @returns {*}
*/
export function statusTypeFilter (status) {
return statusType[status]
}
/**
* 截取指定长度
* @param str
* @param length
* @returns {string}
*/
export function simpleStrFilter (str, length) {
return commonFilter(str, length)
}
/**
* 考试类型
* @param type
* @returns {*}
*/
export function examTypeFilter (type) {
return examType[type]
}
/**
* 发布类型
* @param status
* @returns {string}
*/
export function examStatusFilter (status) {
return status === 0 ? '已发布' : '未发布'
}
/**
* 题目类型
* @param type
* @returns {*}
*/
export function subjectTypeFilter (type) {
return subjectType[type]
}
......@@ -138,6 +138,7 @@ export default {
isDefault: '是否默认',
actions: '操作',
edit: '修改',
view: '查看',
publish: '发布',
draft: '草稿',
delete: '删除',
......@@ -196,7 +197,9 @@ export default {
optionE: '选项E',
optionF: '选项F',
answer: '参考答案',
analysis: '解析'
analysis: '解析',
modifyDate: '修改时间',
modifier: '修改人'
},
public: '发布',
retrieve: '回收',
......
......@@ -108,8 +108,37 @@ export const constantRouterMap = [
}
]
export const constantExamRouterMap = [
{
path: '',
component: Layout,
children: [
{
path: '/exam/exam/subjects/:id',
component: () => import('@/views/exam/examSubjects'),
name: '题目管理',
title: '题目管理',
noCache: true
}
]
},
{
path: '',
component: Layout,
children: [
{
path: '/exam/:examinationId/subjects/:id/:type',
component: () => import('@/views/exam/subjectDetails'),
name: '题目详情',
title: '题目详情',
noCache: true
}
]
}
]
export default new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: [].concat(...formatRoutes(store.state.user.menu), constantRouterMap)
routes: [].concat(...formatRoutes(store.state.user.menu), constantRouterMap, constantExamRouterMap)
})
......@@ -20,3 +20,6 @@
.subject-tinymce {
padding-left: 12px;
}
.collapse-top {
margin-top: 20px;
}
export const dialogStatusConstant = {
create: 'create',
update: 'update'
}
export const statusType = {
0: 'success',
1: 'warning'
}
// 考试类型
export const examType = {
0: '正式考试',
1: '模拟考试',
2: '在线练习'
}
// 题目类型
export const subjectType = {
0: '单选题',
1: '简答题',
3: '多选题'
}
......@@ -369,3 +369,23 @@ export const isSuccess = (response) => {
}
return success
}
/**
* 截取指定长度
* @param str
* @param length
* @returns {string}
*/
export const commonFilter = (str, length) => {
if (str.length > length) {
return str.substring(0, length) + '...'
}
return str
}
/**
* 新建状态
*/
export const isCreate = (status) => {
return status === 'create'
}
<template>
<div class="app-container">
<el-tabs v-model="activeName" @tab-click="handleTabChange">
<!-- 单选题 -->
<el-tab-pane label="单选题" name="0" :disabled="tempSubject.type !== 0 && dialogStatus !== dialogStatusType.create">
<choices ref="choices" subjectInfo="tempSubject"></choices>
</el-tab-pane>
<!-- 多选题 -->
<el-tab-pane label="多选题" name="3" :disabled="tempSubject.type !== 3 && dialogStatus !== dialogStatusType.create">
<multiple-choices ref="multipleChoices" subjectInfo="tempSubject"></multiple-choices>
</el-tab-pane>
<!-- 简答题 -->
<el-tab-pane label="简答题" name="1" :disabled="tempSubject.type !== 1 && dialogStatus !== dialogStatusType.create">
<short-answer ref="shortAnswer" subjectInfo="tempSubject"></short-answer>
</el-tab-pane>
</el-tabs>
<div slot="footer" class="dialog-footer collapse-top">
<el-button @click="dialogSubjectFormVisible = false">{{ $t('table.cancel') }}</el-button>
<el-button v-if="dialogStatus === dialogStatusType.create" type="primary" @click="createSubjectData">{{ $t('table.save') }}</el-button>
<el-button v-else type="primary" @click="updateSubjectData">{{ $t('table.save') }}</el-button>
<el-button type="primary" @click="updateAndAddSubjectData">{{ $t('table.saveAndAdd') }}</el-button>
</div>
</div>
</template>
<script>
import waves from '@/directive/waves'
import { mapGetters } from 'vuex'
import { getSubject, addSubject, putSubject, delSubject, exportSubject } from '@/api/exam/subject'
import { notifySuccess, isNotEmpty, isCreate } from '@/utils/util'
import { dialogStatusConstant } from '@/utils/constant'
import SpinnerLoading from '@/components/SpinnerLoading'
import Tinymce from '@/components/Tinymce'
import Choices from '@/components/Subjects/Choices'
import MultipleChoices from '@/components/Subjects/MultipleChoices'
import ShortAnswer from '@/components/Subjects/ShortAnswer'
export default {
name: 'CourseManagement',
components: { Tinymce, SpinnerLoading, Choices, MultipleChoices, ShortAnswer },
directives: {
waves
},
data () {
return {
dialogSubjectFormVisible: false,
activeName: '0',
dialogStatus: '',
dialogStatusType: { ...dialogStatusConstant },
examinationId: '',
// 题目临时信息
tempSubject: {
id: '',
examinationId: '',
categoryId: 0,
subjectName: '',
type: 0,
choicesType: 0,
options: [
{ subjectChoicesId: '', optionName: 'A', optionContent: '' },
{ subjectChoicesId: '', optionName: 'B', optionContent: '' },
{ subjectChoicesId: '', optionName: 'C', optionContent: '' },
{ subjectChoicesId: '', optionName: 'D', optionContent: '' }
],
answer: {
subjectId: '',
answer: '',
answerType: '',
score: ''
},
score: 5,
analysis: '',
level: 2
},
}
},
created () {
this.getSubject()
},
computed: {
...mapGetters([
'elements',
'permissions'
])
},
methods: {
getSubject() {
let subjectId = this.$route.params.id
this.examinationId = this.$route.params.examinationId
if (isNotEmpty(subjectId)) {
// 加载选项信息
getSubject(subjectId, { type: this.$route.params.type }).then(response => {
const subjectInfo = response.data.data
this.tempSubject = subjectInfo
this.dialogStatus = dialogStatusConstant.update
// 切换到对应的题型选项卡
this.updateCurrentTag(subjectInfo.type)
setTimeout(() => {
const ref = this.getSubjectRef()
if (isNotEmpty(ref)) {
// 初始化单选题
this.$nextTick(() => {
ref.clearValidate()
ref.setSubjectInfo(subjectInfo)
})
}
}, 200)
})
} else {
// 新增题目
// 切换tab
this.dialogStatus = dialogStatusConstant.create
setTimeout(() => {
const ref = this.getSubjectRef()
if (isNotEmpty(ref)) {
this.$nextTick(() => {
// 初始化单选题选项
ref.initDefaultOptions()
})
}
}, 200)
}
},
// 切换题型
handleTabChange (tab, event) {
this.tempSubject.type = parseInt(tab.name)
// 更新组件里的题目信息
this.updateComponentSubjectInfo()
},
// 更新题目
updateSubjectData () {
const ref = this.getSubjectRef()
if (ref.validate()) {
const subjectInfo = ref.getSubjectInfo()
subjectInfo.examinationId = this.examinationId
putSubject(subjectInfo).then(() => {
this.dialogSubjectFormVisible = false
notifySuccess(this, '更新成功')
})
}
},
// 更新并添加题目
updateAndAddSubjectData () {
const ref = this.getSubjectRef()
if (ref.validate()) {
const subjectInfo = ref.getSubjectInfo()
// 绑定考试ID
subjectInfo.examinationId = this.examinationId
// 创建
if (isCreate(this.dialogStatus)) {
addSubject(subjectInfo).then(() => {
this.resetTempSubject(subjectInfo.score)
this.dialogStatus = dialogStatusConstant.create
ref.clearValidate()
this.getSubject()
notifySuccess(this, '创建成功')
})
} else {
// 修改
putSubject(subjectInfo).then(() => {
this.resetTempSubject(subjectInfo.score)
this.dialogStatus = dialogStatusConstant.create
ref.clearValidate()
notifySuccess(this, '更新成功')
})
}
}
},
updateCurrentTag (type) {
this.activeName = type + ''
},
// 更新组件里的题目信息
updateComponentSubjectInfo () {
// 单选题
const ref = this.getSubjectRef()
if (isNotEmpty(ref)) {
ref.setSubjectInfo(this.tempSubject)
}
},
getSubjectRef () {
let ref
switch (this.activeName) {
case '0':
ref = this.$refs['choices']
break
case '1':
ref = this.$refs['shortAnswer']
break
case '3':
ref = this.$refs['multipleChoices']
break
}
return ref
},
// 保存题目
createSubjectData () {
const ref = this.getSubjectRef()
if (ref.validate()) {
let subjectInfo = ref.getSubjectInfo()
// 绑定考试ID
subjectInfo.examinationId = this.examinationId
addSubject(subjectInfo).then(() => {
this.dialogSubjectFormVisible = false
this.getSubject()
notifySuccess(this, '创建成功')
})
}
},
// 切换题目类型
changeSubjectType (value) {
console.log(value)
},
resetActiveName () {
// 重置选项卡至单选题
this.activeName = '0'
},
resetTempSubject (score) {
const ref = this.getSubjectRef()
if (isNotEmpty(ref)) {
ref.resetTempSubject(score)
}
}
}
}
</script>
<style lang="scss" scoped>
.collapse-top {
margin-top: 20px;
}
</style>
......@@ -57,10 +57,11 @@ public class PreviewFilter implements GlobalFilter, Ordered {
private boolean shouldFilter(ServerHttpRequest request) {
// enabled不为true
Map<String, String> previewConfigMap = LoadingCacheHelper.getInstance().get(PreviewConfigLoader.class, PreviewConfigLoader.PREVIEW_ENABLE);
if (previewConfigMap == null || previewConfigMap.isEmpty() || !"true".equals(previewConfigMap.get(PreviewConfigLoader.PREVIEW_ENABLE)))
return false;
if (previewConfigMap == null || previewConfigMap.isEmpty() || !previewConfigMap.containsKey(PreviewConfigLoader.PREVIEW_ENABLE)) {
return true;
}
// 演示环境下,只拦截对默认租户的修改操作
if (GatewayConstant.DEFAULT_TENANT_CODE
if ("true".equals(previewConfigMap.get(PreviewConfigLoader.PREVIEW_ENABLE)) && GatewayConstant.DEFAULT_TENANT_CODE
.equals(request.getHeaders().getFirst(GatewayConstant.TENANT_CODE_HEADER))) {
String method = request.getMethodValue(), uri = request.getURI().getPath();
// GET请求、POST请求
......
package com.github.tangyi.exam.enums;
import com.github.tangyi.exam.service.BaseSubjectService;
import com.github.tangyi.exam.service.ISubjectService;
import com.github.tangyi.exam.service.SubjectChoicesService;
import com.github.tangyi.exam.service.SubjectJudgementService;
import com.github.tangyi.exam.service.SubjectShortAnswerService;
......@@ -29,7 +29,7 @@ public enum SubjectTypeEnum {
private Integer value;
private Class<? extends BaseSubjectService> service;
private Class<? extends ISubjectService> service;
/**
* 根据类型返回具体的SubjectType
......
package com.github.tangyi.exam.excel.listener;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.common.core.utils.excel.AbstractExcelImportListener;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.api.module.SubjectOption;
import com.github.tangyi.exam.excel.model.SubjectExcelModel;
import com.github.tangyi.exam.service.SubjectService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
......@@ -30,11 +34,47 @@ public class SubjectImportListener extends AbstractExcelImportListener<SubjectEx
@Override
public void saveData(List<SubjectExcelModel> subjectExcelModelList) {
logger.info("saveData size: {}", subjectExcelModelList.size());
logger.info("SaveData size: {}", subjectExcelModelList.size());
List<SubjectDto> subjects = new ArrayList<>();
String creator = SysUtil.getUser();
String sysCode = SysUtil.getSysCode();
String tenantCode = SysUtil.getTenantCode();
subjectExcelModelList.forEach(subject -> {
SubjectDto subjectDto = new SubjectDto();
subjectDto.setCommonValue(creator, sysCode, tenantCode);
BeanUtils.copyProperties(subject, subjectDto);
List<SubjectOption> subjectOptions = new ArrayList<>();
if (StringUtils.isNotBlank(subject.getOptions())) {
String[] options = subject.getOptions().split("\\$\\$");
// $$A# 测试测试
for (String option : options) {
if (StringUtils.isNotBlank(option)) {
String[] optionInfos = option.split("#");
if (optionInfos.length >= 2) {
// 去掉$$
String optionName = optionInfos[0].trim();
StringBuilder optionContent = new StringBuilder();
if (optionInfos.length > 2) {
for (int i = 1; i < optionInfos.length; i++) {
optionContent.append(optionInfos[i].trim());
}
} else {
optionContent = new StringBuilder(optionInfos[1].trim());
}
SubjectOption subjectOption = new SubjectOption();
subjectOption.setOptionName(optionName);
subjectOption.setOptionContent(optionContent.toString());
subjectOptions.add(subjectOption);
}
}
}
}
subjectDto.setOptions(subjectOptions);
// 答案
Answer answer = new Answer();
answer.setAnswer(subject.getAnswer());
subjectDto.setAnswer(answer);
subjects.add(subjectDto);
});
subjectService.importSubject(subjects, examinationId, categoryId);
......
......@@ -20,7 +20,7 @@ import java.util.Date;
*/
@Data
@ExcelModel("考试记录")
@ContentRowHeight(10)
@ContentRowHeight(18)
@HeadRowHeight(20)
@ColumnWidth(25)
public class ExamRecordExcelModel {
......
......@@ -18,7 +18,7 @@ import lombok.Data;
*/
@Data
@ExcelModel("题目信息")
@ContentRowHeight(10)
@ContentRowHeight(18)
@HeadRowHeight(20)
@ColumnWidth(25)
public class SubjectExcelModel {
......@@ -45,9 +45,15 @@ public class SubjectExcelModel {
@NumberFormat("#.##")
private Double score;
@ExcelProperty("答案")
private String answer;
@ExcelProperty("解析")
private String analysis;
@ExcelProperty(value = "难度等级", converter = SubjectLevelConverter.class)
private Integer level;
@ExcelProperty("选项")
private String options;
}
package com.github.tangyi.exam.handler;
import com.github.tangyi.common.core.utils.SpringContextHolder;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.service.SubjectService;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* 统计成绩
* @author tangyi
* @date 2020/1/19 10:07 上午
*/
public abstract class AbstractAnswerHandler implements IAnswerHandler {
@Override
public AnswerHandleResult handle(List<Answer> answers) {
if (CollectionUtils.isNotEmpty(answers)) {
// 保存答题正确的题目分数
List<Double> rightScore = new ArrayList<>();
// 获取题目信息
List<SubjectDto> subjects = getSubjects(answers);
answers.forEach(tempAnswer -> {
subjects.stream()
// 题目ID匹配
.filter(tempSubject -> tempSubject.getId().equals(tempAnswer.getSubjectId())).findFirst()
.ifPresent(subject -> judge(tempAnswer, subject, rightScore));
});
AnswerHandleResult result = new AnswerHandleResult();
// 记录总分、正确题目数、错误题目数
result.setScore(rightScore.stream().mapToDouble(Double::valueOf).sum());
result.setCorrectNum(rightScore.size());
result.setInCorrectNum(answers.size() - rightScore.size());
return result;
}
return null;
}
@Override
public List<SubjectDto> getSubjects(List<Answer> answers) {
return SpringContextHolder.getApplicationContext().getBean(SubjectService.class)
.findListById(getSubjectType().getValue(),
answers.stream().map(Answer::getSubjectId).distinct().toArray(Long[]::new));
}
}
......@@ -8,7 +8,7 @@ import lombok.Data;
* @date 2019/12/8 9:56 下午
*/
@Data
public class HandleResult {
public class AnswerHandleResult {
/**
* 总分
......
package com.github.tangyi.exam.handler;
import com.github.tangyi.exam.api.module.Answer;
import java.util.List;
/**
* 统计成绩
* @author tangyi
* @date 2019/12/8 9:56 下午
*/
@FunctionalInterface
public interface BaseHandler {
HandleResult handle(List<Answer> answers);
}
package com.github.tangyi.exam.handler;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import java.util.List;
/**
* 统计成绩
* @author tangyi
* @date 2019/12/8 9:56 下午
*/
public interface IAnswerHandler {
/**
* 统计成绩
* @param answers answers
* @return HandleResult
*/
AnswerHandleResult handle(List<Answer> answers);
/**
* 获取题目类型
* @return SubjectTypeEnum
*/
SubjectTypeEnum getSubjectType();
/**
* 获取题目列表
* @param answers answers
* @return List
*/
List<SubjectDto> getSubjects(List<Answer> answers);
/**
* 判断是否正确
* @param answer answer
* @param subject subject
* @param rightScore rightScore
*/
void judge(Answer answer, SubjectDto subject, List<Double> rightScore);
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.AbstractAnswerHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 选择题
* @author tangyi
* @date 2019/12/8 21:57
*/
@Slf4j
@AllArgsConstructor
@Component
public class ChoicesAnswerHandler extends AbstractAnswerHandler {
@Override
public SubjectTypeEnum getSubjectType() {
return SubjectTypeEnum.CHOICES;
}
@Override
public void judge(Answer answer, SubjectDto subject, List<Double> rightScore) {
if (subject.getAnswer().getAnswer().equalsIgnoreCase(answer.getAnswer())) {
rightScore.add(subject.getScore());
answer.setAnswerType(AnswerConstant.RIGHT);
answer.setScore(subject.getScore());
answer.setMarkStatus(AnswerConstant.MARKED);
} else {
answer.setAnswerType(AnswerConstant.WRONG);
answer.setScore(0.0);
answer.setMarkStatus(AnswerConstant.MARKED);
}
}
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.BaseHandler;
import com.github.tangyi.exam.handler.HandleResult;
import com.github.tangyi.exam.service.SubjectService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 选择题
* @author tangyi
* @date 2019/12/8 21:57
*/
@Slf4j
@AllArgsConstructor
@Component
public class ChoicesHandler implements BaseHandler {
private final SubjectService subjectService;
@Override
public HandleResult handle(List<Answer> answers) {
if (CollectionUtils.isEmpty(answers))
return null;
// 查找题目信息
java.util.List<SubjectDto> subjects = subjectService.findListById(SubjectTypeEnum.CHOICES.getValue(),
answers.stream().map(Answer::getSubjectId).distinct().toArray(Long[]::new));
// 保存答题正确的题目分数
List<Double> rightScore = new ArrayList<>();
answers.forEach(tempAnswer -> {
// 题目集合
subjects.stream()
// 题目ID、题目答案匹配
.filter(tempSubject -> tempSubject.getId().equals(tempAnswer.getSubjectId()) && tempSubject
.getAnswer().getAnswer().equalsIgnoreCase(tempAnswer.getAnswer()))
// 记录答题正确的成绩
.findFirst().ifPresent(right -> {
rightScore.add(right.getScore());
tempAnswer.setAnswerType(AnswerConstant.RIGHT);
tempAnswer.setScore(right.getScore());
tempAnswer.setMarkStatus(AnswerConstant.MARKED);
});
});
// 统计错题
answers.forEach(tempAnswer -> {
// 题目集合
subjects.stream()
// 题目ID、题目答案匹配
.filter(tempSubject -> tempSubject.getId().equals(tempAnswer.getSubjectId()) && !tempSubject
.getAnswer().getAnswer().equalsIgnoreCase(tempAnswer.getAnswer()))
// 错题
.findFirst().ifPresent(tempSubject -> {
tempAnswer.setAnswerType(AnswerConstant.WRONG);
tempAnswer.setScore(0.0);
tempAnswer.setMarkStatus(AnswerConstant.MARKED);
});
});
HandleResult result = new HandleResult();
// 记录总分、正确题目数、错误题目数
result.setScore(rightScore.stream().mapToDouble(Double::valueOf).sum());
result.setCorrectNum(rightScore.size());
result.setInCorrectNum(answers.size() - rightScore.size());
return result;
}
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.AbstractAnswerHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 判断题
* @author tangyi
* @date 2019/12/8 22:01
*/
@Slf4j
@AllArgsConstructor
@Component
public class JudgementAnswerHandler extends AbstractAnswerHandler {
@Override
public SubjectTypeEnum getSubjectType() {
return SubjectTypeEnum.JUDGEMENT;
}
@Override
public void judge(Answer answer, SubjectDto subject, List<Double> rightScore) {
if (subject.getAnswer().getAnswer().equalsIgnoreCase(answer.getAnswer())) {
rightScore.add(subject.getScore());
answer.setAnswerType(AnswerConstant.RIGHT);
answer.setScore(subject.getScore());
answer.setMarkStatus(AnswerConstant.MARKED);
} else {
answer.setAnswerType(AnswerConstant.WRONG);
answer.setScore(0.0);
answer.setMarkStatus(AnswerConstant.MARKED);
}
}
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.BaseHandler;
import com.github.tangyi.exam.handler.HandleResult;
import com.github.tangyi.exam.service.SubjectService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 判断题
* @author tangyi
* @date 2019/12/8 22:01
*/
@Slf4j
@AllArgsConstructor
@Component
public class JudgementHandler implements BaseHandler {
private final SubjectService subjectService;
@Override
public HandleResult handle(List<Answer> answers) {
if (CollectionUtils.isEmpty(answers))
return null;
// 查找题目信息
List<SubjectDto> subjects = subjectService.findListById(SubjectTypeEnum.JUDGEMENT.getValue(),
answers.stream().map(Answer::getSubjectId).distinct().toArray(Long[]::new));
// 保存答题正确的题目分数
List<Double> rightScore = new ArrayList<>();
answers.forEach(tempAnswer -> {
// 题目集合
subjects.stream()
// 题目ID、题目答案匹配
.filter(tempSubject -> tempSubject.getId().equals(tempAnswer.getSubjectId()) && tempSubject
.getAnswer().getAnswer().equalsIgnoreCase(tempAnswer.getAnswer()))
// 记录答题正确的成绩
.findFirst().ifPresent(right -> {
rightScore.add(right.getScore());
tempAnswer.setAnswerType(AnswerConstant.RIGHT);
tempAnswer.setScore(right.getScore());
tempAnswer.setMarkStatus(AnswerConstant.MARKED);
});
});
// 统计错题
answers.forEach(tempAnswer -> {
// 题目集合
subjects.stream()
// 题目ID、题目答案匹配
.filter(tempSubject -> tempSubject.getId().equals(tempAnswer.getSubjectId()) && !tempSubject
.getAnswer().getAnswer().equalsIgnoreCase(tempAnswer.getAnswer()))
// 错题
.findFirst().ifPresent(tempSubject -> {
tempAnswer.setAnswerType(AnswerConstant.WRONG);
tempAnswer.setScore(0.0);
tempAnswer.setMarkStatus(AnswerConstant.MARKED);
});
});
HandleResult result = new HandleResult();
// 记录总分、正确题目数、错误题目数
result.setScore(rightScore.stream().mapToDouble(Double::valueOf).sum());
result.setCorrectNum(rightScore.size());
result.setInCorrectNum(answers.size() - rightScore.size());
return result;
}
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.AbstractAnswerHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 统计多选题
* @author tangyi
* @date 2020/1/19 10:02 上午
*/
@Slf4j
@AllArgsConstructor
@Component
public class MultipleChoicesAnswerHandler extends AbstractAnswerHandler {
@Override
public SubjectTypeEnum getSubjectType() {
return SubjectTypeEnum.MULTIPLE_CHOICES;
}
@Override
public void judge(Answer answer, SubjectDto subject, List<Double> rightScore) {
if (StringUtils.isNotBlank(subject.getAnswer().getAnswer())) {
boolean isRight = true;
String[] standerAnswers = subject.getAnswer().getAnswer().split(",");
for (String as : answer.getAnswer().split(",")) {
if (!ArrayUtils.contains(standerAnswers, as)) {
isRight = false;
}
}
if (isRight) {
rightScore.add(subject.getScore());
answer.setAnswerType(AnswerConstant.RIGHT);
answer.setScore(subject.getScore());
answer.setMarkStatus(AnswerConstant.MARKED);
} else {
answer.setAnswerType(AnswerConstant.WRONG);
answer.setScore(0.0);
answer.setMarkStatus(AnswerConstant.MARKED);
}
}
}
}
package com.github.tangyi.exam.handler.impl;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.Answer;
import com.github.tangyi.exam.handler.BaseHandler;
import com.github.tangyi.exam.handler.HandleResult;
import com.github.tangyi.exam.service.SubjectService;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.AbstractAnswerHandler;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
......@@ -18,12 +18,20 @@ import java.util.List;
@Slf4j
@AllArgsConstructor
@Component
public class ShortAnswerHandler implements BaseHandler {
public class ShortAnswerHandler extends AbstractAnswerHandler {
private final SubjectService subjectService;
@Override
public SubjectTypeEnum getSubjectType() {
return SubjectTypeEnum.SHORT_ANSWER;
}
@Override
public HandleResult handle(List<Answer> answers) {
public List<SubjectDto> getSubjects(List<Answer> answers) {
return null;
}
@Override
public void judge(Answer answer, SubjectDto subject, List<Double> rightScore) {
// TODO
}
}
......@@ -22,12 +22,13 @@ import com.github.tangyi.exam.api.module.Examination;
import com.github.tangyi.exam.api.module.ExaminationRecord;
import com.github.tangyi.exam.api.module.ExaminationSubject;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.handler.HandleResult;
import com.github.tangyi.exam.handler.impl.ChoicesHandler;
import com.github.tangyi.exam.handler.impl.JudgementHandler;
import com.github.tangyi.exam.handler.AnswerHandleResult;
import com.github.tangyi.exam.handler.impl.ChoicesAnswerHandler;
import com.github.tangyi.exam.handler.impl.JudgementAnswerHandler;
import com.github.tangyi.exam.handler.impl.MultipleChoicesAnswerHandler;
import com.github.tangyi.exam.mapper.AnswerMapper;
import com.github.tangyi.exam.utils.ExamRecordUtil;
import com.github.tangyi.exam.utils.HandlerUtil;
import com.github.tangyi.exam.utils.AnswerHandlerUtil;
import com.github.tangyi.user.api.feign.UserServiceClient;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
......@@ -67,9 +68,11 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
private final ExaminationSubjectService examinationSubjectService;
private final ChoicesHandler choicesHandler;
private final ChoicesAnswerHandler choicesHandler;
private final JudgementHandler judgementHandler;
private final MultipleChoicesAnswerHandler multipleChoicesHandler;
private final JudgementAnswerHandler judgementHandler;
private final RedisTemplate<String, String> redisTemplate;
......@@ -200,7 +203,6 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
* 提交答卷,自动统计选择题得分
*
* @param answer answer
* @return boolean
* @author tangyi
* @date 2018/12/26 14:09
*/
......@@ -217,10 +219,10 @@ public class AnswerService extends CrudService<AnswerMapper, Answer> {
// 分类题目
Map<String, List<Answer>> distinctAnswer = this.distinctAnswer(answerList);
// 暂时只自动统计单选题、多选题、判断题,简答题由老师阅卷批改
HandleResult choiceResult = choicesHandler.handle(distinctAnswer.get(SubjectTypeEnum.CHOICES.name()));
HandleResult multipleResult = choicesHandler.handle(distinctAnswer.get(SubjectTypeEnum.MULTIPLE_CHOICES.name()));
HandleResult judgementResult = judgementHandler.handle(distinctAnswer.get(SubjectTypeEnum.JUDGEMENT.name()));
HandleResult result = HandlerUtil.addAll(Arrays.asList(choiceResult, multipleResult, judgementResult));
AnswerHandleResult choiceResult = choicesHandler.handle(distinctAnswer.get(SubjectTypeEnum.CHOICES.name()));
AnswerHandleResult multipleResult = multipleChoicesHandler.handle(distinctAnswer.get(SubjectTypeEnum.MULTIPLE_CHOICES.name()));
AnswerHandleResult judgementResult = judgementHandler.handle(distinctAnswer.get(SubjectTypeEnum.JUDGEMENT.name()));
AnswerHandleResult result = AnswerHandlerUtil.addAll(Arrays.asList(choiceResult, multipleResult, judgementResult));
// 记录总分、正确题目数、错误题目数
record.setScore(result.getScore());
record.setCorrectNumber(result.getCorrectNum());
......
......@@ -11,7 +11,7 @@ import java.util.List;
* @author tangyi
* @date 2019/6/16 17:30
*/
public interface BaseSubjectService {
public interface ISubjectService {
/**
* 根据ID查询
......
......@@ -3,6 +3,7 @@ package com.github.tangyi.exam.service;
import com.github.pagehelper.PageInfo;
import com.github.tangyi.common.core.constant.CommonConstant;
import com.github.tangyi.common.core.service.CrudService;
import com.github.tangyi.common.core.utils.SysUtil;
import com.github.tangyi.exam.api.constants.AnswerConstant;
import com.github.tangyi.exam.api.dto.SubjectDto;
import com.github.tangyi.exam.api.module.ExaminationSubject;
......@@ -29,7 +30,7 @@ import java.util.List;
@AllArgsConstructor
@Service
public class SubjectChoicesService extends CrudService<SubjectChoicesMapper, SubjectChoices>
implements BaseSubjectService {
implements ISubjectService {
private final SubjectOptionService subjectOptionService;
......@@ -96,20 +97,7 @@ public class SubjectChoicesService extends CrudService<SubjectChoicesMapper, Sub
@CacheEvict(value = "subjectChoices", key = "#subjectChoices.id")
public int update(SubjectChoices subjectChoices) {
// 更新选项
List<SubjectOption> options = subjectChoices.getOptions();
if (CollectionUtils.isNotEmpty(options)) {
SubjectOption subjectOption = new SubjectOption();
subjectOption.setSubjectChoicesId(subjectChoices.getId());
subjectOptionService.deleteBySubjectChoicesId(subjectOption);
// 初始化
options.forEach(option -> {
option.setCommonValue(subjectChoices.getCreator(), subjectChoices.getApplicationCode(),
subjectChoices.getTenantCode());
option.setSubjectChoicesId(subjectChoices.getId());
});
// 批量插入
subjectOptionService.insertBatch(options);
}
this.insertOptions(subjectChoices);
return super.update(subjectChoices);
}
......@@ -305,10 +293,34 @@ public class SubjectChoicesService extends CrudService<SubjectChoicesMapper, Sub
BeanUtils.copyProperties(subjectDto, subjectChoices);
subjectChoices.setAnswer(subjectDto.getAnswer().getAnswer());
subjectChoices.setChoicesType(subjectDto.getType());
insertOptions(subjectChoices);
return this.insert(subjectChoices);
}
/**
* 保存选项
* @param subjectChoices subjectChoices
* @author tangyi
* @date 2020/01/17 22:30:48
*/
@Transactional
public void insertOptions(SubjectChoices subjectChoices) {
if (CollectionUtils.isNotEmpty(subjectChoices.getOptions())) {
SubjectOption subjectOption = new SubjectOption();
subjectOption.setSubjectChoicesId(subjectChoices.getId());
subjectOptionService.deleteBySubjectChoicesId(subjectOption);
// 初始化
subjectChoices.getOptions().forEach(option -> {
option.setCommonValue(subjectChoices.getCreator(), subjectChoices.getApplicationCode(),
subjectChoices.getTenantCode());
option.setSubjectChoicesId(subjectChoices.getId());
});
// 批量插入
subjectOptionService.insertBatch(subjectChoices.getOptions());
}
}
/**
* 更新,包括更新选项
*
* @param subjectDto subjectDto
......@@ -321,6 +333,7 @@ public class SubjectChoicesService extends CrudService<SubjectChoicesMapper, Sub
public int updateSubject(SubjectDto subjectDto) {
SubjectChoices subjectChoices = new SubjectChoices();
BeanUtils.copyProperties(subjectDto, subjectChoices);
subjectChoices.setCommonValue(SysUtil.getUser(), SysUtil.getSysCode(), SysUtil.getTenantCode());
// 参考答案
subjectChoices.setAnswer(subjectDto.getAnswer().getAnswer());
return this.update(subjectChoices);
......
......@@ -21,7 +21,7 @@ import java.util.List;
@Slf4j
@Service
public class SubjectJudgementService extends CrudService<SubjectJudgementMapper, SubjectJudgement>
implements BaseSubjectService {
implements ISubjectService {
/**
* 根据ID查询
......
......@@ -190,17 +190,6 @@ public class SubjectService {
examinationSubject.setSubjectId(subjectDto.getId());
examinationSubject.setType(subjectDto.getType());
examinationSubjectService.insert(examinationSubject);
// 保存选项
if (CollectionUtils.isNotEmpty(subjectDto.getOptions())) {
// 初始化基本属性
subjectDto.getOptions().forEach(subjectOption -> {
subjectOption.setCommonValue(subjectDto.getCreator(), subjectDto.getApplicationCode(),
subjectDto.getTenantCode());
subjectOption.setSubjectChoicesId(subjectDto.getId());
});
// 批量保存
subjectOptionService.insertBatch(subjectDto.getOptions());
}
return subjectService(subjectDto.getType()).insertSubject(subjectDto);
}
......@@ -214,7 +203,10 @@ public class SubjectService {
*/
@Transactional
public int update(SubjectDto subjectDto) {
return subjectService(subjectDto.getType()).updateSubject(subjectDto);
int update;
if ((update = subjectService(subjectDto.getType()).updateSubject(subjectDto)) == 0)
update = this.insert(subjectDto);
return update;
}
/**
......@@ -293,7 +285,7 @@ public class SubjectService {
* @author tangyi
* @date 2019/06/16 17:34
*/
private BaseSubjectService subjectService(Integer type) {
private ISubjectService subjectService(Integer type) {
return SpringContextHolder.getApplicationContext().getBean(SubjectTypeEnum.matchByValue(type).getService());
}
......@@ -337,7 +329,7 @@ public class SubjectService {
* @author tangyi
* @date 2019/06/17 10:43
*/
public Map<String, Long[]> getSubjectIdByType(List<ExaminationSubject> examinationSubjects) {
private Map<String, Long[]> getSubjectIdByType(List<ExaminationSubject> examinationSubjects) {
Map<String, Long[]> idMap = new HashMap<>();
examinationSubjects.stream().collect(Collectors.groupingBy(ExaminationSubject::getType, Collectors.toList()))
.forEach((type, temp) -> {
......@@ -350,6 +342,11 @@ public class SubjectService {
temp.stream().map(ExaminationSubject::getSubjectId).distinct()
.toArray(Long[]::new));
break;
case MULTIPLE_CHOICES:
idMap.put(SubjectTypeEnum.MULTIPLE_CHOICES.name(),
temp.stream().map(ExaminationSubject::getSubjectId).distinct()
.toArray(Long[]::new));
break;
case SHORT_ANSWER:
idMap.put(SubjectTypeEnum.SHORT_ANSWER.name(),
temp.stream().map(ExaminationSubject::getSubjectId).distinct()
......@@ -396,6 +393,18 @@ public class SubjectService {
subjectDtoList.addAll(SubjectUtil.subjectChoicesToDto(subjectChoicesList));
}
}
if (idMap.containsKey(SubjectTypeEnum.MULTIPLE_CHOICES.name())) {
List<SubjectChoices> subjectChoicesList = subjectChoicesService.findListById(idMap.get(SubjectTypeEnum.MULTIPLE_CHOICES.name()));
if (CollectionUtils.isNotEmpty(subjectChoicesList)) {
// 查找选项信息
if (findOptions) {
subjectChoicesList = subjectChoicesList.stream().map(subjectChoicesService::get)
.collect(Collectors.toList());
}
subjectDtoList.addAll(SubjectUtil.subjectChoicesToDto(subjectChoicesList));
}
}
if (idMap.containsKey(SubjectTypeEnum.SHORT_ANSWER.name())) {
List<SubjectShortAnswer> subjectShortAnswers = subjectShortAnswerService.findListById(idMap.get(SubjectTypeEnum.SHORT_ANSWER.name()));
if (CollectionUtils.isNotEmpty(subjectShortAnswers)) {
......
......@@ -24,7 +24,7 @@ import java.util.List;
*/
@Service
public class SubjectShortAnswerService extends CrudService<SubjectShortAnswerMapper, SubjectShortAnswer>
implements BaseSubjectService {
implements ISubjectService {
/**
* 查找题目
......
package com.github.tangyi.exam.utils;
import com.github.tangyi.exam.handler.HandleResult;
import com.github.tangyi.exam.handler.AnswerHandleResult;
import java.util.List;
......@@ -9,14 +9,14 @@ import java.util.List;
* @author tangyi
* @date 2019/12/8 22:42
*/
public class HandlerUtil {
public class AnswerHandlerUtil {
public static HandleResult addAll(List<HandleResult> results) {
HandleResult result = new HandleResult();
public static AnswerHandleResult addAll(List<AnswerHandleResult> results) {
AnswerHandleResult result = new AnswerHandleResult();
int score = 0;
int correctNum = 0;
int inCorrectNum = 0;
for (HandleResult tempResult : results) {
for (AnswerHandleResult tempResult : results) {
if (tempResult != null) {
score += tempResult.getScore();
correctNum += tempResult.getCorrectNum();
......
......@@ -7,6 +7,7 @@ import com.github.tangyi.exam.api.module.SubjectShortAnswer;
import com.github.tangyi.exam.enums.SubjectTypeEnum;
import com.github.tangyi.exam.excel.model.SubjectExcelModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
......@@ -23,114 +24,124 @@ import java.util.stream.Collectors;
*/
public class SubjectUtil {
private SubjectUtil() {
}
private SubjectUtil() {
}
/**
* 转换对象
* @param subjectDtoList subjectDtoList
* @return List
*/
public static List<SubjectExcelModel> convertToExcelModel(List<SubjectDto> subjectDtoList) {
List<SubjectExcelModel> subjectExcelModels = new ArrayList<>(subjectDtoList.size());
subjectDtoList.forEach(subject -> {
SubjectExcelModel subjectExcelModel = new SubjectExcelModel();
BeanUtils.copyProperties(subject, subjectExcelModel);
subjectExcelModels.add(subjectExcelModel);
});
return subjectExcelModels;
}
/**
* 转换对象
*
* @param subjectDtoList subjectDtoList
* @return List
*/
public static List<SubjectExcelModel> convertToExcelModel(List<SubjectDto> subjectDtoList) {
List<SubjectExcelModel> subjectExcelModels = new ArrayList<>(subjectDtoList.size());
subjectDtoList.forEach(subject -> {
SubjectExcelModel subjectExcelModel = new SubjectExcelModel();
BeanUtils.copyProperties(subject, subjectExcelModel);
if (CollectionUtils.isNotEmpty(subject.getOptions())) {
List<String> optionString = subject.getOptions().stream()
.map(option -> "$$" + option.getOptionName() + "# " + option.getOptionContent()).collect(Collectors.toList());
subjectExcelModel.setOptions(StringUtils.join(optionString, "\n"));
}
subjectExcelModel.setAnswer(subject.getAnswer().getAnswer());
subjectExcelModels.add(subjectExcelModel);
});
return subjectExcelModels;
}
/**
* SubjectChoices转SubjectDto
*
* @param subjectChoice subjectChoice
* @return List
* @author tangyi
* @date 2019/06/16 16:50
*/
public static SubjectDto subjectChoicesToDto(SubjectChoices subjectChoice) {
if (subjectChoice == null)
return null;
SubjectDto subjectDto = new SubjectDto();
subjectDto.setId(subjectChoice.getId());
subjectDto.setSubjectName(subjectChoice.getSubjectName());
subjectDto.setScore(subjectChoice.getScore());
subjectDto.setAnalysis(subjectChoice.getAnalysis());
subjectDto.setLevel(subjectChoice.getLevel());
// 选择题类型匹配
SubjectTypeEnum subjectTypeEnum = SubjectTypeEnum.matchByValue(subjectChoice.getChoicesType());
if (subjectTypeEnum != null)
subjectDto.setType(subjectTypeEnum.getValue());
subjectDto.setChoicesType(subjectChoice.getChoicesType());
subjectDto.setOptions(subjectChoice.getOptions());
subjectDto.setCreator(subjectChoice.getCreator());
// 参考答案
Answer answer = new Answer();
answer.setAnswer(subjectChoice.getAnswer());
subjectDto.setAnswer(answer);
return subjectDto;
}
/**
* SubjectChoices转SubjectDto
*
* @param subjectChoice subjectChoice
* @return List
* @author tangyi
* @date 2019/06/16 16:50
*/
public static SubjectDto subjectChoicesToDto(SubjectChoices subjectChoice) {
if (subjectChoice == null)
return null;
SubjectDto subjectDto = new SubjectDto();
subjectDto.setId(subjectChoice.getId());
subjectDto.setSubjectName(subjectChoice.getSubjectName());
subjectDto.setScore(subjectChoice.getScore());
subjectDto.setAnalysis(subjectChoice.getAnalysis());
subjectDto.setLevel(subjectChoice.getLevel());
// 选择题类型匹配
SubjectTypeEnum subjectTypeEnum = SubjectTypeEnum.matchByValue(subjectChoice.getChoicesType());
if (subjectTypeEnum != null)
subjectDto.setType(subjectTypeEnum.getValue());
subjectDto.setChoicesType(subjectChoice.getChoicesType());
subjectDto.setOptions(subjectChoice.getOptions());
subjectDto.setCreator(subjectChoice.getCreator());
subjectDto.setModifier(subjectChoice.getModifier());
subjectDto.setModifyDate(subjectChoice.getModifyDate());
// 参考答案
Answer answer = new Answer();
answer.setAnswer(subjectChoice.getAnswer());
subjectDto.setAnswer(answer);
return subjectDto;
}
/**
* SubjectChoices转SubjectDto
*
* @param subjectChoices subjectChoices
* @return List
* @author tangyi
* @date 2019/06/16 16:50
*/
public static List<SubjectDto> subjectChoicesToDto(List<SubjectChoices> subjectChoices) {
List<SubjectDto> subjectDtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(subjectChoices)) {
subjectDtoList = subjectChoices.stream().map(SubjectUtil::subjectChoicesToDto).collect(Collectors.toList());
}
return subjectDtoList;
}
/**
* SubjectChoices转SubjectDto
*
* @param subjectChoices subjectChoices
* @return List
* @author tangyi
* @date 2019/06/16 16:50
*/
public static List<SubjectDto> subjectChoicesToDto(List<SubjectChoices> subjectChoices) {
List<SubjectDto> subjectDtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(subjectChoices)) {
subjectDtoList = subjectChoices.stream().map(SubjectUtil::subjectChoicesToDto).collect(Collectors.toList());
}
return subjectDtoList;
}
/**
* SubjectShortAnswer转SubjectDto
*
* @param subjectShortAnswer subjectShortAnswer
* @return List
* @author tangyi
* @date 2019/06/16 16:59
*/
public static SubjectDto subjectShortAnswerToDto(SubjectShortAnswer subjectShortAnswer) {
if (subjectShortAnswer == null)
return null;
SubjectDto subjectDto = new SubjectDto();
subjectDto.setId(subjectShortAnswer.getId());
subjectDto.setSubjectName(subjectShortAnswer.getSubjectName());
subjectDto.setScore(subjectShortAnswer.getScore());
subjectDto.setAnalysis(subjectShortAnswer.getAnalysis());
subjectDto.setLevel(subjectShortAnswer.getLevel());
subjectDto.setType(SubjectTypeEnum.SHORT_ANSWER.getValue());
subjectDto.setCreator(subjectShortAnswer.getCreator());
// 题目类型
subjectDto.setType(SubjectTypeEnum.SHORT_ANSWER.getValue());
/**
* SubjectShortAnswer转SubjectDto
*
* @param subjectShortAnswer subjectShortAnswer
* @return List
* @author tangyi
* @date 2019/06/16 16:59
*/
public static SubjectDto subjectShortAnswerToDto(SubjectShortAnswer subjectShortAnswer) {
if (subjectShortAnswer == null)
return null;
SubjectDto subjectDto = new SubjectDto();
subjectDto.setId(subjectShortAnswer.getId());
subjectDto.setSubjectName(subjectShortAnswer.getSubjectName());
subjectDto.setScore(subjectShortAnswer.getScore());
subjectDto.setAnalysis(subjectShortAnswer.getAnalysis());
subjectDto.setLevel(subjectShortAnswer.getLevel());
subjectDto.setType(SubjectTypeEnum.SHORT_ANSWER.getValue());
subjectDto.setCreator(subjectShortAnswer.getCreator());
subjectDto.setModifyDate(subjectShortAnswer.getModifyDate());
// 题目类型
subjectDto.setType(SubjectTypeEnum.SHORT_ANSWER.getValue());
// 参考答案
Answer answer = new Answer();
answer.setAnswer(subjectShortAnswer.getAnswer());
subjectDto.setAnswer(answer);
return subjectDto;
}
// 参考答案
Answer answer = new Answer();
answer.setAnswer(subjectShortAnswer.getAnswer());
subjectDto.setAnswer(answer);
return subjectDto;
}
/**
* SubjectShortAnswer转SubjectDto
*
* @param subjectShortAnswers subjectShortAnswers
* @return List
* @author tangyi
* @date 2019/06/16 16:59
*/
public static List<SubjectDto> subjectShortAnswerToDto(List<SubjectShortAnswer> subjectShortAnswers) {
List<SubjectDto> subjectDtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(subjectShortAnswers)) {
subjectDtoList = subjectShortAnswers.stream().map(SubjectUtil::subjectShortAnswerToDto)
.collect(Collectors.toList());
}
return subjectDtoList;
}
/**
* SubjectShortAnswer转SubjectDto
*
* @param subjectShortAnswers subjectShortAnswers
* @return List
* @author tangyi
* @date 2019/06/16 16:59
*/
public static List<SubjectDto> subjectShortAnswerToDto(List<SubjectShortAnswer> subjectShortAnswers) {
List<SubjectDto> subjectDtoList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(subjectShortAnswers)) {
subjectDtoList = subjectShortAnswers.stream().map(SubjectUtil::subjectShortAnswerToDto)
.collect(Collectors.toList());
}
return subjectDtoList;
}
}
......@@ -15,7 +15,7 @@ import lombok.Data;
*/
@Data
@ExcelModel("菜单信息")
@ContentRowHeight(10)
@ContentRowHeight(18)
@HeadRowHeight(20)
@ColumnWidth(25)
public class MenuExcelModel {
......
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