package com.mindskip.xzs.service.impl;
|
|
import com.mindskip.xzs.domain.*;
|
import com.mindskip.xzs.domain.TextContent;
|
import com.mindskip.xzs.domain.enums.ExamPaperTypeEnum;
|
import com.mindskip.xzs.domain.enums.QuestionTypeEnum;
|
import com.mindskip.xzs.domain.exam.ExamPaperQuestionItemObject;
|
import com.mindskip.xzs.domain.exam.ExamPaperTitleItemObject;
|
import com.mindskip.xzs.domain.other.KeyValue;
|
import com.mindskip.xzs.repository.ExamPaperMapper;
|
import com.mindskip.xzs.repository.QuestionMapper;
|
import com.mindskip.xzs.service.*;
|
import com.mindskip.xzs.service.enums.ActionEnum;
|
import com.mindskip.xzs.utility.DateTimeUtil;
|
import com.mindskip.xzs.utility.JsonUtil;
|
import com.mindskip.xzs.utility.ModelMapperSingle;
|
import com.mindskip.xzs.utility.ExamUtil;
|
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperEditRequestVM;
|
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperPageRequestVM;
|
import com.mindskip.xzs.viewmodel.admin.exam.ExamPaperTitleItemVM;
|
import com.mindskip.xzs.viewmodel.admin.question.QuestionEditRequestVM;
|
import com.mindskip.xzs.viewmodel.student.dashboard.PaperFilter;
|
import com.mindskip.xzs.viewmodel.student.dashboard.PaperInfo;
|
import com.mindskip.xzs.viewmodel.student.exam.ExamPaperPageVM;
|
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageInfo;
|
import com.mindskip.xzs.domain.ExamPaper;
|
import com.mindskip.xzs.domain.Question;
|
import com.mindskip.xzs.domain.User;
|
import org.modelmapper.ModelMapper;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.*;
|
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.stream.Collectors;
|
|
@Service
|
public class ExamPaperServiceImpl extends BaseServiceImpl<ExamPaper> implements ExamPaperService {
|
|
protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();
|
private final ExamPaperMapper examPaperMapper;
|
private final QuestionMapper questionMapper;
|
private final TextContentService textContentService;
|
private final QuestionService questionService;
|
private final SubjectService subjectService;
|
private final ExamPaperDepartmentService examPaperDepartmentService;
|
private final ExamPaperSubjectService examPaperSubjectService;
|
private final QuestionSubjectService questionSubjectService;
|
|
@Autowired
|
public ExamPaperServiceImpl(ExamPaperMapper examPaperMapper, QuestionMapper questionMapper, TextContentService textContentService, QuestionService questionService, SubjectService subjectService, ExamPaperDepartmentService examPaperDepartmentService, ExamPaperSubjectService examPaperSubjectService, QuestionSubjectService questionSubjectService) {
|
super(examPaperMapper);
|
this.examPaperMapper = examPaperMapper;
|
this.questionMapper = questionMapper;
|
this.textContentService = textContentService;
|
this.questionService = questionService;
|
this.subjectService = subjectService;
|
this.examPaperDepartmentService = examPaperDepartmentService;
|
this.examPaperSubjectService = examPaperSubjectService;
|
this.questionSubjectService = questionSubjectService;
|
}
|
|
|
@Override
|
public PageInfo<ExamPaper> page(ExamPaperPageRequestVM requestVM) {
|
return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() ->
|
examPaperMapper.page(requestVM));
|
}
|
|
@Override
|
public PageInfo<ExamPaper> taskExamPage(ExamPaperPageRequestVM requestVM) {
|
return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() ->
|
examPaperMapper.taskExamPage(requestVM));
|
}
|
|
@Override
|
public PageInfo<ExamPaper> studentPage(ExamPaperPageVM requestVM) {
|
return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() ->
|
examPaperMapper.studentPage(requestVM));
|
}
|
|
|
@Override
|
@Transactional
|
public ExamPaper savePaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, User user) {
|
ActionEnum actionEnum = (examPaperEditRequestVM.getId() == null) ? ActionEnum.ADD : ActionEnum.UPDATE;
|
Date now = new Date();
|
|
List<ExamPaperTitleItemObject> frameTextContentList = new ArrayList<>();
|
List<ExamPaperTitleItemVM> titleItemsVM = new ArrayList<>();
|
//随机试卷
|
if (examPaperEditRequestVM.getSubjectSource() != null) {
|
// Map<Integer, Integer> questionList = questionService.getAll().stream().collect(Collectors.toMap(Question::getId, Question::getScore));
|
randomQuestion(examPaperEditRequestVM, frameTextContentList, titleItemsVM);
|
}
|
if (titleItemsVM.size() < 0) {
|
titleItemsVM = examPaperEditRequestVM.getTitleItems();
|
}
|
if (frameTextContentList.size() < 0) {
|
frameTextContentList = frameTextContentFromVM(titleItemsVM);
|
}
|
|
String frameTextContentStr = JsonUtil.toJsonStr(frameTextContentList);
|
|
ExamPaper examPaper;
|
if (actionEnum == ActionEnum.ADD) {
|
examPaper = modelMapper.map(examPaperEditRequestVM, ExamPaper.class);
|
TextContent frameTextContent = new TextContent(frameTextContentStr, now);
|
textContentService.insertByFilter(frameTextContent);
|
examPaper.setFrameTextContentId(frameTextContent.getId());
|
examPaper.setCreateTime(now);
|
examPaper.setCreateUser(user.getId());
|
examPaper.setDeleted(false);
|
examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM);
|
examPaperMapper.insertSelective(examPaper);
|
|
} else {
|
examPaper = examPaperMapper.selectByPrimaryKey(examPaperEditRequestVM.getId());
|
TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId());
|
frameTextContent.setContent(frameTextContentStr);
|
textContentService.updateByIdFilter(frameTextContent);
|
modelMapper.map(examPaperEditRequestVM, examPaper);
|
examPaperFromVM(examPaperEditRequestVM, examPaper, titleItemsVM);
|
examPaperMapper.updateByPrimaryKeySelective(examPaper);
|
//批量修改
|
examPaperDepartmentService.removeByExamPaperId(examPaper.getId());
|
examPaperSubjectService.removeByExamPaperId(examPaper.getId());
|
}
|
addExamPaperDepartment(examPaperEditRequestVM, examPaper);
|
addExamPaperSubject(examPaperEditRequestVM, examPaper);
|
return examPaper;
|
}
|
|
@Override
|
public ExamPaperEditRequestVM examPaperToVM(Integer id) {
|
ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(id);
|
ExamPaperEditRequestVM vm = modelMapper.map(examPaper, ExamPaperEditRequestVM.class);
|
vm.setLevel(examPaper.getGradeLevel());
|
TextContent frameTextContent = textContentService.selectById(examPaper.getFrameTextContentId());
|
List<ExamPaperTitleItemObject> examPaperTitleItemObjects = JsonUtil.toJsonListObject(frameTextContent.getContent(), ExamPaperTitleItemObject.class);
|
List<Integer> questionIds = examPaperTitleItemObjects.stream()
|
.flatMap(t -> t.getQuestionItems().stream()
|
.map(q -> q.getId()))
|
.collect(Collectors.toList());
|
List<Question> questions = questionMapper.selectByIds(questionIds);
|
List<ExamPaperTitleItemVM> examPaperTitleItemVMS = examPaperTitleItemObjects.stream().map(t -> {
|
ExamPaperTitleItemVM tTitleVM = modelMapper.map(t, ExamPaperTitleItemVM.class);
|
List<QuestionEditRequestVM> questionItemsVM = t.getQuestionItems().stream().map(i -> {
|
Question question = questions.stream().filter(q -> q.getId().equals(i.getId())).findFirst().get();
|
QuestionEditRequestVM questionEditRequestVM = questionService.getQuestionEditRequestVM(question);
|
questionEditRequestVM.setItemOrder(i.getItemOrder());
|
return questionEditRequestVM;
|
}).collect(Collectors.toList());
|
tTitleVM.setQuestionItems(questionItemsVM);
|
return tTitleVM;
|
}).collect(Collectors.toList());
|
vm.setTitleItems(examPaperTitleItemVMS);
|
vm.setScore(ExamUtil.scoreToVM(examPaper.getScore()));
|
if (ExamPaperTypeEnum.TimeLimit == ExamPaperTypeEnum.fromCode(examPaper.getPaperType())) {
|
List<String> limitDateTime = Arrays.asList(DateTimeUtil.dateFormat(examPaper.getLimitStartTime()), DateTimeUtil.dateFormat(examPaper.getLimitEndTime()));
|
vm.setLimitDateTime(limitDateTime);
|
}
|
|
//查询部门和课目
|
vm.setSubjectId(examPaperSubjectService.getByExamPaperId(examPaper.getId())
|
.stream().map(ExamPaperSubject::getSubjectId).toArray(Integer[]::new));
|
vm.setDepartmentIds(examPaperDepartmentService.getByExamPaperId(examPaper.getId())
|
.stream().map(ExamPaperDepartment::getDepartmentId).toArray(Integer[]::new));
|
return vm;
|
}
|
|
@Override
|
public List<PaperInfo> indexPaper(PaperFilter paperFilter) {
|
return examPaperMapper.indexPaper(paperFilter);
|
}
|
|
|
@Override
|
public Integer selectAllCount() {
|
return examPaperMapper.selectAllCount();
|
}
|
|
@Override
|
public List<Integer> selectMothCount() {
|
Date startTime = DateTimeUtil.getMonthStartDay();
|
Date endTime = DateTimeUtil.getMonthEndDay();
|
List<KeyValue> mouthCount = examPaperMapper.selectCountByDate(startTime, endTime);
|
List<String> mothStartToNowFormat = DateTimeUtil.MothStartToNowFormat();
|
return mothStartToNowFormat.stream().map(md -> {
|
KeyValue keyValue = mouthCount.stream().filter(kv -> kv.getName().equals(md)).findAny().orElse(null);
|
return null == keyValue ? 0 : keyValue.getValue();
|
}).collect(Collectors.toList());
|
}
|
|
@Override
|
public Integer removeByIds(Integer[] ids) {
|
return examPaperMapper.removeByIds(ids);
|
}
|
|
private void examPaperFromVM(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper, List<ExamPaperTitleItemVM> titleItemsVM) {
|
// Integer gradeLevel = subjectService.levelBySubjectId(examPaperEditRequestVM.getSubjectId());
|
Integer questionCount = titleItemsVM.stream()
|
.mapToInt(t -> t.getQuestionItems().size()).sum();
|
Integer score = titleItemsVM.stream().
|
flatMapToInt(t -> t.getQuestionItems().stream()
|
.mapToInt(q -> ExamUtil.scoreFromVM(q.getScore()))
|
).sum();
|
examPaper.setQuestionCount(questionCount);
|
examPaper.setScore(score);
|
examPaper.setGradeLevel(null);
|
List<String> dateTimes = examPaperEditRequestVM.getLimitDateTime();
|
if (ExamPaperTypeEnum.TimeLimit == ExamPaperTypeEnum.fromCode(examPaper.getPaperType())) {
|
examPaper.setLimitStartTime(DateTimeUtil.parse(dateTimes.get(0), DateTimeUtil.STANDER_FORMAT));
|
examPaper.setLimitEndTime(DateTimeUtil.parse(dateTimes.get(1), DateTimeUtil.STANDER_FORMAT));
|
}
|
}
|
|
private List<ExamPaperTitleItemObject> frameTextContentFromVM(List<ExamPaperTitleItemVM> titleItems) {
|
AtomicInteger index = new AtomicInteger(1);
|
return titleItems.stream().map(t -> {
|
ExamPaperTitleItemObject titleItem = modelMapper.map(t, ExamPaperTitleItemObject.class);
|
List<ExamPaperQuestionItemObject> questionItems = t.getQuestionItems().stream()
|
.map(q -> {
|
ExamPaperQuestionItemObject examPaperQuestionItemObject = modelMapper.map(q, ExamPaperQuestionItemObject.class);
|
examPaperQuestionItemObject.setItemOrder(index.getAndIncrement());
|
return examPaperQuestionItemObject;
|
})
|
.collect(Collectors.toList());
|
titleItem.setQuestionItems(questionItems);
|
return titleItem;
|
}).collect(Collectors.toList());
|
}
|
|
private void addExamPaperDepartment(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) {
|
List<ExamPaperDepartment> list = Arrays.asList(examPaperEditRequestVM.getDepartmentIds()).stream().map(e -> {
|
ExamPaperDepartment examPaperDepartment = new ExamPaperDepartment();
|
examPaperDepartment.setExamPaperId(examPaper.getId());
|
examPaperDepartment.setDepartmentId(e);
|
examPaperDepartment.setDeleted("0");
|
return examPaperDepartment;
|
}).collect(Collectors.toList());
|
examPaperDepartmentService.saves(list);
|
}
|
|
private void addExamPaperSubject(ExamPaperEditRequestVM examPaperEditRequestVM, ExamPaper examPaper) {
|
List<ExamPaperSubject> subjectList = Arrays.asList(examPaperEditRequestVM.getSubjectId()).stream().map(e -> {
|
ExamPaperSubject examPaperSubject = new ExamPaperSubject();
|
examPaperSubject.setSubjectId(e);
|
examPaperSubject.setExamPaperId(examPaper.getId());
|
examPaperSubject.setDeleted("0");
|
return examPaperSubject;
|
}).collect(Collectors.toList());
|
examPaperSubjectService.saves(subjectList);
|
}
|
|
/**
|
*
|
* @param result
|
* @param scoresMap
|
* @param quantity
|
* @param totalScore
|
*/
|
public static void selectRandomScores(Map<Integer, Integer> result, Map<Integer, Integer> scoresMap, int quantity, int totalScore) {
|
// Map<String, Integer> selectedScoresMap = new HashMap<>();
|
|
if (quantity <= 0 || totalScore <= 0 || scoresMap.isEmpty()) {
|
return; // 返回空Map
|
}
|
|
List<Integer> keys = new ArrayList<>(scoresMap.keySet());
|
List<Integer> values = scoresMap.values().stream().map(e->e=e/10).collect(Collectors.toList());
|
|
Random random = new Random();
|
int remainingQuantity = quantity;
|
int remainingScore = totalScore;
|
|
for (int i = 0; i < quantity - 1; i++) {
|
int index = random.nextInt(values.size());
|
int score = values.get(index);
|
|
if (score <= remainingScore) {
|
result.put(keys.get(index), score);
|
remainingQuantity--;
|
remainingScore -= score;
|
values.remove(index);
|
keys.remove(index);
|
}
|
}
|
|
if (!values.isEmpty()) {
|
int index = random.nextInt(values.size());
|
int score = values.get(index);
|
result.put(keys.get(index), remainingScore); // 最后一个分数为剩余的分数
|
}
|
|
}
|
|
/**
|
* 随机试卷
|
*
|
* @param examPaperEditRequestVM 传参
|
* @param frameTextContentList
|
* @param titleItemsVM title
|
*/
|
private void randomQuestion(ExamPaperEditRequestVM examPaperEditRequestVM, List<ExamPaperTitleItemObject> frameTextContentList, List<ExamPaperTitleItemVM> titleItemsVM) {
|
Map<Integer, Integer> subjectSource = examPaperEditRequestVM.getSubjectSource();
|
//总数量
|
Integer sum = subjectSource.values().stream().mapToInt(Integer::intValue).sum();
|
Integer avg = 0;
|
|
ExamPaperTitleItemObject examPaperTitleItemObject = new ExamPaperTitleItemObject();
|
examPaperTitleItemObject.setName("测试001");
|
|
ExamPaperTitleItemVM examPaperTitleItemVM = new ExamPaperTitleItemVM();
|
//titleItemsVM
|
examPaperTitleItemVM.setName("测试001");
|
|
List<ExamPaperQuestionItemObject> examPaperQuestionItemObjectList = new ArrayList<>();
|
|
List<QuestionEditRequestVM> questionItems = new ArrayList<>();
|
for (Integer key : subjectSource.keySet()) { // key:数量
|
//该标签对应的分数 多选:3 判断:3 单选:4
|
Integer source = 20 * subjectSource.get(key) / sum;
|
// 多选和判断数量
|
Integer multipleNumber = subjectSource.get(key) * 3 / 10;
|
//多选和判断分数
|
Integer multipleSource = source * 3 / 10;
|
List<Integer> questions = questionSubjectService.getSubject(key)
|
.stream().map(QuestionSubject::getQuestionId).collect(Collectors.toList());
|
List<Question> list = questionService.selectByIds(questions);
|
|
Map<Integer, Integer> multiple = new HashMap<>();
|
//多选
|
Map<Integer, Integer> multipleMap = list.stream()
|
.filter(e -> e.getQuestionType().equals(QuestionTypeEnum.MultipleChoice.getCode()))
|
.collect(Collectors.toMap(Question::getId, Question::getScore));
|
selectRandomScores(multiple, multipleMap, multipleNumber, multipleSource);
|
|
|
//判断
|
Map<Integer, Integer> judgmentMap = list.stream()
|
.filter(e -> e.getQuestionType().equals(QuestionTypeEnum.TrueFalse.getCode()))
|
.collect(Collectors.toMap(Question::getId, Question::getScore));
|
selectRandomScores(multiple, judgmentMap, multipleNumber, multipleSource);
|
|
//单选数量
|
Integer radioNumber = subjectSource.get(key) - multiple.size();
|
//单选分数
|
Integer radioSource = source - multiple.values().stream().mapToInt(Integer::intValue).sum();;
|
//单选
|
Map<Integer, Integer> radioMap = list.stream()
|
.filter(e -> e.getQuestionType().equals(QuestionTypeEnum.SingleChoice.getCode()))
|
.collect(Collectors.toMap(Question::getId, Question::getScore));
|
selectRandomScores(multiple, radioMap, radioNumber, radioSource);
|
Integer order = 0;
|
titleItemsVM.add(examPaperTitleItemVM);
|
for (Integer k : multiple.keySet()) {
|
ExamPaperQuestionItemObject examPaperQuestionItemObject = new ExamPaperQuestionItemObject();
|
examPaperQuestionItemObject.setId(k);
|
examPaperQuestionItemObject.setItemOrder(order++);
|
examPaperQuestionItemObjectList.add(examPaperQuestionItemObject);
|
//titleItemsVM
|
QuestionEditRequestVM questionEditRequestVM = new QuestionEditRequestVM();
|
questionEditRequestVM.setScore(multiple.get(k).toString());
|
questionItems.add(questionEditRequestVM);
|
}
|
|
examPaperTitleItemObject.setQuestionItems(examPaperQuestionItemObjectList);
|
|
//titleItemsVM
|
examPaperTitleItemVM.setQuestionItems(questionItems);
|
|
}
|
frameTextContentList.add(examPaperTitleItemObject);
|
titleItemsVM.add(examPaperTitleItemVM);
|
|
}
|
|
}
|