package com.qxueyou.scc.exam.service.impl; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import com.qxueyou.scc.base.model.Pager; import com.qxueyou.scc.base.model.Result; import com.qxueyou.scc.base.service.impl.CommonAppService; import com.qxueyou.scc.base.util.CollectionUtils; import com.qxueyou.scc.base.util.TraceUtils; import com.qxueyou.scc.base.util.UUIDUtils; import com.qxueyou.scc.exam.model.ExamPaperSectionInfo; import com.qxueyou.scc.exam.service.IExamPaperSectionService; import com.qxueyou.scc.exercise.model.ExerciseGroup; import com.qxueyou.scc.exercise.model.ExerciseGroupItemRe; import com.qxueyou.scc.exercise.model.ExerciseItem; import com.qxueyou.scc.exercise.service.IExerciseGroupService; import com.qxueyou.scc.exercise.service.IExerciseService; /** * 试卷部分管理服务层 * * @author kevin * @createTime 2017-11-1 */ @Service public class ExamPaperSectionService extends CommonAppService implements IExamPaperSectionService { @Autowired IExerciseGroupService exerciseGroupService; @Autowired IExerciseService exerciseService; @SuppressWarnings("rawtypes") @Autowired private RedisTemplate redisTemplate; @Override public int queryExamPaperSectionCount(Map param) { // TODO Auto-generated method stub return 0; } @Override public List queryExamPaperSectionList(Map param, Pager page) { // TODO Auto-generated method stub return null; } @Override public String addExamPaperSection(ExamPaperSectionInfo examPaperSectionInfo) { TraceUtils.setCreateTrace(examPaperSectionInfo); // 查询当前最大的sectionOrder String hql = "select max(sectionOrder) from ExamPaperSectionInfo where examPaperId=? and deleteFlag is false"; Integer maxOrder = this.findUnique(hql, CollectionUtils.newList(examPaperSectionInfo.getExamPaperId()), Integer.class); int beginOrder = maxOrder == null ? 0 : maxOrder.intValue(); examPaperSectionInfo.setSectionOrder(++beginOrder); // 获取当前section对应的开始index int count = this.findCount("from ExerciseGroupItemRe r where r.deleteFlag is false and r.exerciseGroupId=?", CollectionUtils.newList(examPaperSectionInfo.getGroupId())); String sectionId = UUIDUtils.generateUUID().replace("-", ""); examPaperSectionInfo.setSectionId(sectionId); examPaperSectionInfo.setItemStartOrder((short) (count)); examPaperSectionInfo.setItemEndOrder((short) -1); this.insert(examPaperSectionInfo); return examPaperSectionInfo.getSectionId(); } @Override public Result deleteExamPaperSection(String[] paperSectionIds) { Result result = new Result(true); if (paperSectionIds != null && paperSectionIds.length > 0) { String hql = "update ExamPaperSectionInfo set deleteFlag = true where sectionId=?"; result = bulkUpdateInLoop(hql, paperSectionIds); for (String sectionId : paperSectionIds) { ExamPaperSectionInfo currentSectionInfo = this.read(ExamPaperSectionInfo.class, sectionId); this.deleteAllSectionItem(currentSectionInfo.getSectionId()); } } return result; } @Override public Result updateExamPaperSection(ExamPaperSectionInfo param) { ExamPaperSectionInfo examPaperSectionInfo = read(ExamPaperSectionInfo.class, param.getSectionId()); if (examPaperSectionInfo != null) { TraceUtils.setUpdateTrace(examPaperSectionInfo); examPaperSectionInfo.setSectionName(param.getSectionName()); examPaperSectionInfo.setSectionDesc(param.getSectionDesc()); } return save(examPaperSectionInfo); } @Deprecated @Override public Result saveExamPaperSectionGroup(String sectionId, String[] selectedGroupIds, Short[] itemTypes) throws Exception { ExamPaperSectionInfo examPaperSectionInfo = read(ExamPaperSectionInfo.class, sectionId); ExerciseGroup exerciseGroup = read(ExerciseGroup.class, examPaperSectionInfo.getGroupId()); // 获取试卷部分原开始位置和结束位置 int origStartIndex = examPaperSectionInfo.getItemStartOrder(); int origEndIndex = examPaperSectionInfo.getItemEndOrder(); if (origEndIndex > 0) { this.deleteAllSectionItem(examPaperSectionInfo.getSectionId()); } // 将题库的题目复制到试卷题库 int itemIndex = origStartIndex; ExerciseGroup targetExerciseGroup = new ExerciseGroup(); targetExerciseGroup.setGroupId(examPaperSectionInfo.getGroupId()); if (selectedGroupIds != null && selectedGroupIds.length > 0) { for (int i = 0; i < selectedGroupIds.length; i++) { ExerciseGroup sourceExerciseGroup = this.read(ExerciseGroup.class, selectedGroupIds[i]); itemIndex += exerciseGroupService.doCopyExerciseGroupItem(sourceExerciseGroup, targetExerciseGroup, itemTypes, itemIndex); } long allCount = exerciseGroup.getAllCount() == null ? 0 : exerciseGroup.getAllCount().longValue() + (itemIndex - origStartIndex); exerciseGroup.setAllCount(BigInteger.valueOf(allCount)); if (itemIndex - origStartIndex > 0) { examPaperSectionInfo.setItemEndOrder((short) (itemIndex)); } this.updateSectionRangeIndex(sectionId, itemIndex - origStartIndex); this.updatePaperScore(exerciseGroup.getGroupId()); } return new Result(true); } @Override public Result saveExamPaperSectionItems(String sectionId, String sourceGroupId, String[] selectedItemIds) throws Exception { ExamPaperSectionInfo examPaperSectionInfo = read(ExamPaperSectionInfo.class, sectionId); ExerciseGroup exerciseGroup = read(ExerciseGroup.class, examPaperSectionInfo.getGroupId()); // 获取试卷部分原开始位置和结束位置 int origStartIndex = examPaperSectionInfo.getItemStartOrder(); int origEndIndex = examPaperSectionInfo.getItemEndOrder(); //如果试卷其他部分中已经存在该题目,则返回错误,重复的题目 int count = this.findCountByComplexHql("from ExerciseGroupItemRe r where r.deleteFlag is false and r.exerciseGroupId=:paperGroupId and (r.itemOrder<:startIdx or r.itemOrder>:endIdx) and r.exerciseItemId in (:exerciseItemIds)", CollectionUtils.newObjectMap("startIdx", origStartIndex, "endIdx", origEndIndex, "paperGroupId", examPaperSectionInfo.getGroupId(), "exerciseItemIds", selectedItemIds)); if (count > 0) { return new Result(false, "请检查选择的题目,同一份试卷中不允许存在相同的题目!"); } // 将题库的题目复制到试卷题库 int copyStartIndex = origEndIndex > 0 ? origEndIndex : origStartIndex; ExerciseGroup targetExerciseGroup = new ExerciseGroup(); targetExerciseGroup.setGroupId(examPaperSectionInfo.getGroupId()); ExerciseGroup sourceExerciseGroup = this.read(ExerciseGroup.class, sourceGroupId); int copyEndIndex = copyStartIndex + exerciseGroupService.doCopyExerciseGroupItem(sourceExerciseGroup, targetExerciseGroup, selectedItemIds, copyStartIndex); long allCount = exerciseGroup.getAllCount() == null ? 0 : exerciseGroup.getAllCount().longValue() + (copyEndIndex - copyStartIndex); exerciseGroup.setAllCount(BigInteger.valueOf(allCount)); //如果有保存题目则处理索引,否则不处理 if (copyEndIndex - copyStartIndex > 0) { examPaperSectionInfo.setItemEndOrder((short) (copyEndIndex)); } this.updateSectionRangeIndex(sectionId, copyEndIndex - copyStartIndex); this.updatePaperScore(exerciseGroup.getGroupId()); return new Result(true); } @Override public ExamPaperSectionInfo queryExamPaperSectionDetail(String examPaperSectionId) { ExamPaperSectionInfo examPaperSectionInfo = this.read(ExamPaperSectionInfo.class, examPaperSectionId); ExerciseGroup exerciseGroup = exerciseGroupService.queryExerciseGroupDetail(examPaperSectionInfo.getGroupId()); List items = null; // 查询出section 对应的题目信息 if (examPaperSectionInfo.getItemEndOrder() > 0) { int itemCount = examPaperSectionInfo.getItemEndOrder() - examPaperSectionInfo.getItemStartOrder(); items = new ArrayList(itemCount); items.addAll(exerciseGroup.getItems().subList(examPaperSectionInfo.getItemStartOrder(), examPaperSectionInfo.getItemEndOrder())); } examPaperSectionInfo.setLstExerciseItem(items); return examPaperSectionInfo; } @SuppressWarnings("unchecked") private Result updateSectionRangeIndex(String currentSectionid, int adjustNum) { ExamPaperSectionInfo currentSectionInfo = this.read(ExamPaperSectionInfo.class, currentSectionid); // 如果部分对应的end为-1,则不需要更新endorder String hql = "from ExamPaperSectionInfo where examPaperId=? and sectionOrder>? and deleteFlag is false"; List lstExamPaperSectionInfo = this.find(hql, CollectionUtils.newList(currentSectionInfo.getExamPaperId(), currentSectionInfo.getSectionOrder()), ExamPaperSectionInfo.class); if (lstExamPaperSectionInfo != null && lstExamPaperSectionInfo.size() > 0) { for (ExamPaperSectionInfo sectionInfo : lstExamPaperSectionInfo) { if (sectionInfo.getItemEndOrder() > 0) { sectionInfo.setItemStartOrder((short) (sectionInfo.getItemStartOrder() + adjustNum)); sectionInfo.setItemEndOrder((short) (sectionInfo.getItemEndOrder() + adjustNum)); } else { sectionInfo.setItemStartOrder((short) (sectionInfo.getItemStartOrder() + adjustNum)); } this.saveOrUpdateAll(lstExamPaperSectionInfo); } } //清理试卷缓存 this.redisTemplate.delete(currentSectionInfo.getGroupId()); return new Result(true); } private void deleteAllSectionItem(String sectionId) { ExamPaperSectionInfo examPaperSectionInfo = this.read(ExamPaperSectionInfo.class, sectionId); int origStartIndex = examPaperSectionInfo.getItemStartOrder(); int origEndIndex = examPaperSectionInfo.getItemEndOrder(); if (origEndIndex > 0) { int itemCount = origEndIndex - origStartIndex; List lstItemRe = new ArrayList(itemCount); String hql = "from ExerciseGroupItemRe r where r.exerciseGroupId=? and r.deleteFlag is false order by r.itemOrder asc"; List lstExerciseGroupItemRe = this.find(hql, CollectionUtils.newList(examPaperSectionInfo.getGroupId()), ExerciseGroupItemRe.class); lstItemRe.addAll(lstExerciseGroupItemRe.subList(examPaperSectionInfo.getItemStartOrder(), examPaperSectionInfo.getItemEndOrder())); String[] exerciseItemIds = new String[itemCount]; for (int i = 0; i < lstItemRe.size(); i++) { exerciseItemIds[i] = lstItemRe.get(i).getExerciseItemId(); } this.deleteSectionItem(examPaperSectionInfo.getSectionId(), examPaperSectionInfo.getGroupId(), exerciseItemIds); // section坐标置空 examPaperSectionInfo.setItemEndOrder((short) -1); this.save(examPaperSectionInfo); } } @Override public Result deleteSectionItem(String sectionId, String groupId, String[] exerciseItemIds) { if (exerciseItemIds != null && exerciseItemIds.length > 0) { // 查询题库与题目的关系 List lstRelationIds = new ArrayList(exerciseItemIds.length); ExamPaperSectionInfo currentSectionInfo = this.read(ExamPaperSectionInfo.class, sectionId); String hql = "from ExerciseGroupItemRe r where r.exerciseGroupId=? and r.deleteFlag is false order by r.itemOrder asc"; List lstExerciseGroupItemRe = this.find(hql, CollectionUtils.newList(currentSectionInfo.getGroupId()), ExerciseGroupItemRe.class); lstExerciseGroupItemRe = lstExerciseGroupItemRe.subList(currentSectionInfo.getItemStartOrder(), currentSectionInfo.getItemEndOrder()); Map itemReMap = new HashMap( exerciseItemIds.length); for (ExerciseGroupItemRe itemRe : lstExerciseGroupItemRe) { itemReMap.put(itemRe.getExerciseItemId(), itemRe); } for (String strExerciseItemId : exerciseItemIds) { lstRelationIds.add(itemReMap.get(strExerciseItemId).getRelationId()); } // 如果题目删除完了,则设置end为-1 if (currentSectionInfo.getItemEndOrder() - exerciseItemIds.length == currentSectionInfo .getItemStartOrder()) { currentSectionInfo.setItemEndOrder((short) -1); } else { currentSectionInfo .setItemEndOrder((short) (currentSectionInfo.getItemEndOrder() - exerciseItemIds.length)); } this.save(currentSectionInfo); this.deleteExerciseItems(lstRelationIds.toArray(new String[]{}), groupId); this.updateSectionRangeIndex(sectionId, -exerciseItemIds.length); this.updatePaperScore(groupId); } return new Result(true); } /** * 删除试卷习题 * * * @param reIds * @param groupId * @return */ private Result deleteExerciseItems(String[] reIds, String groupId) { ExerciseGroup group = this.read(ExerciseGroup.class, groupId); // 更新组试卷习题数量 group.setAllCount(group.getAllCount().subtract(new BigInteger(String.valueOf(reIds.length)))); TraceUtils.setUpdateTrace(group); this.save(group); // 2.删除试卷题目组关联表数据 this.bulkUpdateInLoop("delete from ExerciseGroupItemRe where relationId=?", reIds); // 更新item的顺序号 String hql = "from ExerciseGroupItemRe re where re.exerciseGroupId=? and re.deleteFlag is false order by re.itemOrder asc "; List lstRe = this.find(hql, CollectionUtils.newList(groupId), ExerciseGroupItemRe.class); if (lstRe != null && lstRe.size() > 0) { for (int i = 0; i < lstRe.size(); i++) { lstRe.get(i).setItemOrder(i + 1); } this.saveOrUpdateAll(lstRe); } return new Result(true); } @Override public Result saveSectionItem(ExerciseGroup exerciseGroup) { //保存题目信息 return exerciseService.saveExerciseItemBatch(exerciseGroup.getGroupId(), exerciseGroup.getItems()); } @Override public BigDecimal updatePaperScore(String groupId) { String totalScore = this.findUnique("select sum(s.score) as totalScore from ExerciseGroupItemRe r, ExerciseItemScore s where r.exerciseGroupId = s.groupId and r.exerciseItemId = s.exerciseItemId " + " and s.groupId=? and r.deleteFlag is false and s.deleteFlag is false ", CollectionUtils.newList(groupId), String.class); totalScore = StringUtils.isEmpty(totalScore) ? "0.00" : totalScore; this.bulkUpdate("update ExamPaperInfo set totalScore=" + totalScore + " where deleteFlag is false and groupId=?", new Object[]{groupId}); return new BigDecimal(totalScore); } }