package com.qxueyou.scc.exercise.service.impl; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.math.BigInteger; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.poi.POIXMLDocument; import org.apache.poi.POIXMLTextExtractor; import org.apache.poi.hwpf.extractor.WordExtractor; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.xwpf.extractor.XWPFWordExtractor; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSONArray; import com.qxueyou.scc.admin.classes.model.ClsClass; import com.qxueyou.scc.base.dao.CommonDAO; import com.qxueyou.scc.base.model.Result; import com.qxueyou.scc.base.model.ResultJson; import com.qxueyou.scc.base.service.ICacheService; import com.qxueyou.scc.base.service.IFileUploadService; import com.qxueyou.scc.base.service.impl.CommonAppService; import com.qxueyou.scc.base.util.ClientUtils; 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.exercise.dao.ExerciseDAO; import com.qxueyou.scc.exercise.model.ExerciseDeepAnalysis; import com.qxueyou.scc.exercise.model.ExerciseGroup; import com.qxueyou.scc.exercise.model.ExerciseGroupExtend; import com.qxueyou.scc.exercise.model.ExerciseGroupItemRe; import com.qxueyou.scc.exercise.model.ExerciseImportResult; import com.qxueyou.scc.exercise.model.ExerciseItem; import com.qxueyou.scc.exercise.model.ExerciseItemAnalisi; import com.qxueyou.scc.exercise.model.ExerciseItemAnswerU; import com.qxueyou.scc.exercise.model.ExerciseItemOption; import com.qxueyou.scc.exercise.model.ExerciseItemScore; import com.qxueyou.scc.exercise.model.ExerciseItemStatistics; import com.qxueyou.scc.exercise.model.ExerciseObjectImg; import com.qxueyou.scc.exercise.model.ExerciseOptionStatistics; import com.qxueyou.scc.exercise.model.ExerciseParse; import com.qxueyou.scc.exercise.model.ExerciseParseResult; import com.qxueyou.scc.exercise.model.ExerciseReCourse; import com.qxueyou.scc.exercise.model.ExerciseRecord; import com.qxueyou.scc.exercise.model.QExerciseGroup; import com.qxueyou.scc.exercise.model.QExerciseGroupItemRe; import com.qxueyou.scc.exercise.model.QExerciseItem; import com.qxueyou.scc.exercise.model.QExerciseItemAnalisi; import com.qxueyou.scc.exercise.model.QExerciseItemAnswerU; import com.qxueyou.scc.exercise.model.QExerciseItemOption; import com.qxueyou.scc.exercise.model.QExerciseObjectImg; import com.qxueyou.scc.exercise.service.IExerciseService; import com.qxueyou.scc.exercise.service.impl.node.Doc; import com.qxueyou.scc.exercise.util.ExerciseUtils; import com.qxueyou.scc.org.model.OrgCharger; import com.qxueyou.scc.school.model.SchClassSubject; import com.qxueyou.scc.school.model.SchCourseware; import com.qxueyou.scc.school.model.SchEvaluate; import com.qxueyou.scc.school.service.ICourseWareService; import com.qxueyou.scc.sys.model.SysFileUploadTrace; import com.qxueyou.scc.sys.service.IOssService; import com.qxueyou.scc.teach.subject.model.SubjectChapter; import com.qxueyou.scc.user.model.UserRegistration; /** * 练习 实现service 练习后台 * * @author zhiyong * */ @Service public class ExerciseService extends CommonAppService implements IExerciseService { private ExerciseDAO exerDAO; @Autowired IOssService ossService; @Autowired ICacheService cacheService; @Autowired IFileUploadService fileUploadService; @Autowired private ICourseWareService courseWareService; @SuppressWarnings("rawtypes") @Autowired private RedisTemplate redisTemplate; private final String[] letter = "A B C D E F G H I J K L M N O P Q".split(" "); private static Logger log = LogManager.getLogger("ExerciseService"); public ExerciseDAO getExerDAO() { return exerDAO; } /** * 依赖注入 * * @param exerExtendDAO */ @Autowired(required = false) public void setExerDAO(@Qualifier("exerciseDAO") ExerciseDAO exerDAO) { this.exerDAO = exerDAO; } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#insertExerciseGroup(java.lang.String, short, java.lang.String, java.lang.String) */ @Override public Result insertExerciseGroup(String name, short type, String lessonId, String chapterId) { int iCount = 0; if (type == 3) { // 查询当前class存在的存在的顺序、随机练习或者 章节练习 个数 // 可能结果:0、 新增三种;1,新增两种(顺序随机),2,新增一种(章节),3的话,不增加 String hsql = "from ExerciseGroup where classId = ? and case when type = ? then 1 when type = ? then 1 when type = ? and " + " attribute1 = ? and attribute2 = ? then 1 else 0 end = 1 and deleteFlag is false"; iCount = findCount(hsql, CollectionUtils.newList(ClientUtils.getClassId(), ExerciseGroup.TYPE_EXERCISE_RANDOM, ExerciseGroup.TYPE_EXERCISE_SEQUENCE, ExerciseGroup.TYPE_CHAPTER_ITEM, lessonId, chapterId)); } Result objResult = saveOrUpdateAll(initExerciseGroupList(name, type, lessonId, chapterId, iCount)); // 保存 return objResult; } /** * 新增练习组 * * @param name * 练习组名称 * @param type * 练习组类型 * @param lessonId * 课程id * @param chapterId * 章节id * @param 模拟考试 * 时间设置 * @return */ public Result insertExerciseGroup(String groupId,String name, short type, String lessonId, String chapterId, String attribute1, boolean repeatFlag) { if(StringUtils.isNotBlank(groupId)){ // 更新 return updateExerciseGroup(groupId, name, type, lessonId, chapterId, attribute1, repeatFlag); }else{ // 新增 return saveExerciseGroup(name, type, lessonId, chapterId, attribute1, repeatFlag); } } public Result updateExerciseGroup(String groupId,String name, short type, String subjectId, String chapterId, String attribute1, boolean repeatFlag) { ExerciseGroup group = read(ExerciseGroup.class, groupId); if(type == ExerciseGroup.TYPE_CHAPTER_ITEM){ // 章节练习 group.setAttribute2(chapterId); } if (type == ExerciseGroup.TYPE_MOCK_EXAM) {// 模拟考试 // 添加练习组时间 、是否重做 addExerciseGroupExtendTime(groupId, attribute1, repeatFlag); } if (type == ExerciseGroup.TYPE_HOMEWORK) {// 家庭作业 // 添加是否重做 addExerciseGroupExtendTime(groupId, null, repeatFlag); } group.setName(name); //group.setSubjectId(subjectId); TraceUtils.setUpdateTrace(group); return this.saveExerciseGroup(group); } public Result saveExerciseGroup(String name, short type, String lessonId, String chapterId, String attribute1, boolean repeatFlag) { int iCount = 0; if (type == ExerciseGroup.TYPE_EXERCISE_SEQUENCE) { // 查询当前class存在的存在的顺序、随机练习或者 章节练习 个数 // 可能结果:0、 新增三种;1,新增两种(顺序随机),2,新增一种(章节),3的话,不增加 String hsql = "from ExerciseGroup where classId = ? and case when type = ? then 1 when type = ? then 1 when type = ? and " + " attribute1 = ? and attribute2 = ? then 1 else 0 end = 1 and deleteFlag is false"; iCount = findCount(hsql, CollectionUtils.newList(ClientUtils.getClassId(), ExerciseGroup.TYPE_EXERCISE_RANDOM, ExerciseGroup.TYPE_EXERCISE_SEQUENCE, ExerciseGroup.TYPE_CHAPTER_ITEM, lessonId, chapterId)); } List lstExeGroup = initExerciseGroupList(name, type, lessonId, chapterId, iCount); // 兼容1.0版本 模拟考试时间设置 for (ExerciseGroup group : lstExeGroup) { group.setOrderNum(BigInteger.valueOf(SchCourseware.COURSEWARE_MAX_ORDER)); if (ExerciseGroup.TYPE_MOCK_EXAM == group.getType()) { group.setAttribute1(attribute1); } this.saveExerciseGroup(group); } //Result objResult = saveOrUpdateAll(lstExeGroup); if (type == ExerciseGroup.TYPE_MOCK_EXAM) {// 模拟考试 // 添加练习组时间 、是否重做 addExerciseGroupExtendTime(lstExeGroup.get(0).getGroupId(), attribute1, repeatFlag); } if (type == ExerciseGroup.TYPE_HOMEWORK) {// 家庭作业 // 添加是否重做 addExerciseGroupExtendTime(lstExeGroup.get(0).getGroupId(), null, repeatFlag); } // 保存 return new Result(true); } /** * 新增题库 * * @param name * 练习组名称 * @param type * 练习组类型 * @param lessonId * 课程id * @param chapterId * 章节id * @param 模拟考试 * 时间设置 * @return */ public Result insertOrgExercise(ExerciseGroup group, boolean repeatFlag) { if(StringUtils.isNotBlank(group.getGroupId())){ // 更新 return updateOrgExerciseGroup(group, repeatFlag); }else{ // 新增 return saveOrgExerciseGroup(group, repeatFlag); } } public Result updateOrgExerciseGroup(ExerciseGroup group, boolean repeatFlag) { ExerciseGroup oldGroup = read(ExerciseGroup.class, group.getGroupId()); if (oldGroup.getType() == ExerciseGroup.TYPE_MOCK_EXAM) {// 模拟考试 // 添加练习组时间 、是否重做 addExerciseGroupExtendTime(group.getGroupId(), group.getAttribute1(), repeatFlag); } if (oldGroup.getType() == ExerciseGroup.TYPE_HOMEWORK) {// 家庭作业 // 添加是否重做 addExerciseGroupExtendTime(group.getGroupId(), null, repeatFlag); } oldGroup.setName(group.getName()); TraceUtils.setUpdateTrace(oldGroup); return this.saveExerciseGroup(oldGroup); } public Result saveOrgExerciseGroup(ExerciseGroup group, boolean repeatFlag) { group.setGroupId(null); TraceUtils.setCreateTrace(group); group.setDeleteFlag(false); group.setOrgId(ClientUtils.getOrgId()); group.setAllCount(BigInteger.ZERO); this.saveExerciseGroup(group); group.setOriginExerciseId(group.getGroupId()); this.saveExerciseGroup(group); if (StringUtils.isNotBlank(group.getAttribute1())) { addExerciseGroupExtendTime(group.getGroupId(), group.getAttribute1(), repeatFlag); } if (group.getType() == ExerciseGroup.TYPE_HOMEWORK) {// 家庭作业 // 添加是否重做 addExerciseGroupExtendTime(group.getGroupId(), null, repeatFlag); } this.insertReCourse(group.getCollegeCourseId(), group.getGroupId()); return new Result(true); } /** * 拷贝练习 * * @param id * @param subjectId * @param collegeCourseId * @param chapterId * @return * @throws IllegalAccessException * @throws InstantiationException * @throws InvocationTargetException * @throws NoSuchMethodException */ public Result doCopyExerciseGroup(String id, String subjectId, String collegeCourseId, String chapterId) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { ExerciseGroup oldExercise = this.read(ExerciseGroup.class, id); ExerciseGroup newGroup = new ExerciseGroup(); TraceUtils.setCreateTrace(newGroup); newGroup.setGroupId(null); newGroup.setAllCount(oldExercise.getAllCount()); newGroup.setClassId(oldExercise.getClassId()); newGroup.setAttribute1(oldExercise.getAttribute1()); newGroup.setAttribute2(oldExercise.getAttribute2()); newGroup.setEditFlag(oldExercise.getEditFlag()); newGroup.setOriginExerciseId(oldExercise.getGroupId()); newGroup.setOrderNum(BigInteger.valueOf(SchCourseware.COURSEWARE_MAX_ORDER)); newGroup.setDoCount("0"); newGroup.setType(oldExercise.getType()); newGroup.setOrgId(ClientUtils.getOrgId()); newGroup.setName(oldExercise.getName()); newGroup.setSubjectId(subjectId); newGroup.setChapterId(chapterId); newGroup.setCollegeCourseId(collegeCourseId); this.saveExerciseGroup(newGroup); //班级拷贝不需要新增关联表 if(StringUtils.isEmpty(ClientUtils.getClassId())){ newGroup.setOriginExerciseId(newGroup.getGroupId()); this.saveExerciseGroup(newGroup); this.insertReCourse(collegeCourseId, newGroup.getGroupId()); } // 扩展表: extend this.doSaveCopyExtend(oldExercise,newGroup); this.doCopyExerciseItem(newGroup.getGroupId(), oldExercise.getGroupId(), null, 1);//拷贝 return new Result(true); } /** * 拷贝练习题 * * @param items * @param newGroupId * @param oldGroupId * @throws NoSuchMethodException * @throws InvocationTargetException * @throws InstantiationException * @throws IllegalAccessException */ public void doCopyExerciseItem(String newGroupId, String oldGroupId, List items, int type) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException{ if(items == null || items.size() == 0){ items = this.find("select i from ExerciseItem i, ExerciseGroupItemRe r where i.deleteFlag is false AND r.exerciseGroupId = ?"+ " and r.exerciseItemId = i.exerciseId AND r.deleteFlag IS FALSE", CollectionUtils.newList(oldGroupId), ExerciseItem.class); } if(items != null && !items.isEmpty()){ List analysisesNew = new ArrayList<>(); List reNew = new ArrayList<>(); List exerciseObjectImgNew = new ArrayList<>(); // 得到当前组题目的最大题号 int maxGroupItemOrder = queryExerciseGroupItemNo(newGroupId); for(ExerciseItem objExerciseItem : items){ ExerciseGroupItemRe oldExerciseGroupItemRe = this.findUnique("from ExerciseGroupItemRe where deleteFlag is false and exerciseGroupId = ? and exerciseItemId = ?", CollectionUtils.newList(oldGroupId, objExerciseItem.getExerciseId()), ExerciseGroupItemRe.class); //临时对象 ExerciseItem tem = new ExerciseItem(); tem = (ExerciseItem) BeanUtils.cloneBean(objExerciseItem); List exerciseObjectImg = this.find("from ExerciseObjectImg m where m.deleteFlag is false and m.exerciseObjectId = ?", CollectionUtils.newList(objExerciseItem.getExerciseId()), ExerciseObjectImg.class); ExerciseItemAnalisi analysises = this.findUnique("from ExerciseItemAnalisi m where m.deleteFlag is false and m.exerciseItemId = ?", CollectionUtils.newList(objExerciseItem.getExerciseId()), ExerciseItemAnalisi.class); List options = objExerciseItem.getOptions(); tem.setOptions(null); tem.setAnalysises(null); // tem.setGroups(null); tem.setScores(null); ExerciseItem objExerciseItemNew = new ExerciseItem(); BeanUtils.copyProperties(objExerciseItemNew, tem); objExerciseItemNew.setExerciseId(null); //拷贝的练习不同步 objExerciseItemNew.setOrgiExerciseId(type == 1?null:StringUtils.isEmpty(objExerciseItem.getOrgiExerciseId())?objExerciseItem.getExerciseId():objExerciseItem.getOrgiExerciseId()); TraceUtils.setCreateTrace(objExerciseItemNew); this.save(objExerciseItemNew); String exerciseIdNew = objExerciseItemNew.getExerciseId(); for(ExerciseItemOption objExerciseItemOption : options){ ExerciseItemOption objExerciseItemOptionNew = new ExerciseItemOption(); BeanUtils.copyProperties(objExerciseItemOptionNew, objExerciseItemOption); objExerciseItemOptionNew.setExerciseItemId(exerciseIdNew); objExerciseItemOptionNew.setOptionId(null); TraceUtils.setCreateTrace(objExerciseItemOptionNew); this.save(objExerciseItemOptionNew); //optionsNew.add(objExerciseItemOptionNew); List optionObjectImgs = this.find("from ExerciseObjectImg m where m.deleteFlag is false and m.exerciseObjectId = ?", CollectionUtils.newList(objExerciseItemOption.getOptionId()), ExerciseObjectImg.class); if(optionObjectImgs != null && !optionObjectImgs.isEmpty()){ for(ExerciseObjectImg optionObjectImg : optionObjectImgs){ ExerciseObjectImg objExerciseObjectImgNew = new ExerciseObjectImg(); BeanUtils.copyProperties(objExerciseObjectImgNew, optionObjectImg); objExerciseObjectImgNew.setExerciseObjectId(objExerciseItemOptionNew.getOptionId()); objExerciseObjectImgNew.setImgId(null); TraceUtils.setCreateTrace(objExerciseObjectImgNew); exerciseObjectImgNew.add(objExerciseObjectImgNew); } } } if(analysises != null){ ExerciseItemAnalisi objExerciseItemAnalisiNew = new ExerciseItemAnalisi(); BeanUtils.copyProperties(objExerciseItemAnalisiNew, analysises); objExerciseItemAnalisiNew.setExerciseItemId(exerciseIdNew); objExerciseItemAnalisiNew.setExerciseAnalisisId(null); TraceUtils.setCreateTrace(objExerciseItemAnalisiNew); analysisesNew.add(objExerciseItemAnalisiNew); } if(exerciseObjectImg != null && !exerciseObjectImg.isEmpty()){ for(ExerciseObjectImg objExerciseObjectImg : exerciseObjectImg){ ExerciseObjectImg objExerciseObjectImgNew = new ExerciseObjectImg(); BeanUtils.copyProperties(objExerciseObjectImgNew, objExerciseObjectImg); objExerciseObjectImgNew.setExerciseObjectId(exerciseIdNew); objExerciseObjectImgNew.setImgId(null); TraceUtils.setCreateTrace(objExerciseObjectImgNew); exerciseObjectImgNew.add(objExerciseObjectImgNew); } } ExerciseGroupItemRe re = new ExerciseGroupItemRe(); re.setDeleteFlag(false); re.setExerciseGroupId(newGroupId); re.setExerciseItemId(exerciseIdNew); re.setRelationId(null); if(oldExerciseGroupItemRe != null){ re.setDocOrder(oldExerciseGroupItemRe.getDocOrder()); } re.setItemOrder(++maxGroupItemOrder); reNew.add(re); } this.saveOrUpdateAll(reNew); //this.saveOrUpdateAll(optionsNew); this.saveOrUpdateAll(analysisesNew); this.saveOrUpdateAll(exerciseObjectImgNew); //更新统计 this.updateGroupUpdateTimeByList(this.find("from ExerciseGroup where groupId = ?", CollectionUtils.newList(newGroupId), ExerciseGroup.class)); } } /** * 插入练习和科目关联 * * @param collegeCourseId * @param handoutId */ private void insertReCourse(String collegeCourseId, String groupId){ // 序号 String hql = "select MAX(c.orderNum) from ExerciseReCourse c where c.deleteFlag is false and c.collegeCourseId = ? and orgId = ? "; Integer iMax = this.findUnique(hql, CollectionUtils.newList(collegeCourseId, ClientUtils.getOrgId()), Integer.class); if (iMax == null || iMax == 0) { iMax = 1; } else { iMax = iMax + 1; } ExerciseReCourse course = new ExerciseReCourse(); TraceUtils.setCreateTrace(course); course.setCollegeCourseId(collegeCourseId); course.setDeleteFlag(false); course.setGroupId(groupId); course.setOrgId(ClientUtils.getOrgId()); course.setOrderNum(iMax); save(course); } public Result insertAppointExercise(String groupIds[], String orgIds[], String classIds[]) { if (null == groupIds || groupIds.length == 0) { return new Result(false, "参数错误"); } // 一次性查询groupId对应的collegeCourseId String hql = " from ExerciseReCourse where groupId in (:groupIds) and deleteFlag is false"; Map argsMap = new HashMap(); argsMap.put("groupIds", groupIds); List courseList = findByComplexHql(hql, argsMap, ExerciseReCourse.class); // 放入map中 KEY:groupId VALUE:collegeCourseId Map groupReCourse = new HashMap(); for (ExerciseReCourse exerciseReCourse : courseList) { groupReCourse.put(exerciseReCourse.getGroupId(), exerciseReCourse.getCollegeCourseId()); } // 一次性查询classId对应的orgId Map classMap = new HashMap(); if (classIds.length > 0) { hql = " from ClsClass where classId in (:classIds) and deleteFlag is false"; argsMap = new HashMap(); argsMap.put("classIds", classIds); List classList = findByComplexHql(hql, argsMap, ClsClass.class); // 放入map中 KEY:classId VALUE:orgId for (ClsClass orgClass : classList) { classMap.put(orgClass.getClassId(), orgClass.getOrgId()); } } // 一次性查询groupId对应的orderNum Map orderMap = new HashMap(); hql = " from ExerciseReCourse where groupId in (:groupIds) and deleteFlag is false and orgId = :currOrgId"; argsMap = new HashMap(); argsMap.put("groupIds", groupIds); argsMap.put("currOrgId", ClientUtils.getOrgId()); List courseLst = findByComplexHql(hql, argsMap, ExerciseReCourse.class); // 放入map中 KEY:classId VALUE:orgId for (ExerciseReCourse c : courseLst) { orderMap.put(c.getGroupId(), c.getOrderNum()); } for (String groupId : groupIds) { if (orgIds.length > 0) { // 指定给机构 insertOrgGroup(groupId, orgIds, groupReCourse.get(groupId),orderMap); } if (classIds.length > 0) { // 指定给班级 ExerciseGroup group = read(ExerciseGroup.class, groupId); insertClassGroup(groupId, classIds, group, groupReCourse.get(groupId), classMap,orderMap); } } return new Result(true); } /** * 指定给机构 * * @param groupId * @param orgIds * @param groupReCourse * @return */ public void insertOrgGroup(String groupId, String orgIds[], String collegeCourseId,Map orderMap) { // 查询出所有不符合条件的数据 String hql = "select orgId from ExerciseReCourse where groupId = :groupId and deleteFlag is false and orgId in (:orgIds)"; Map args = new HashMap(); args.put("groupId", groupId); args.put("orgIds", orgIds); List strings = findByComplexHql(hql, args, String.class); List orgList = new ArrayList(); for (String orgId : orgIds) { orgList.add(orgId); } // 剔除掉不符合条件的orgId orgList.removeAll(strings); if(orgList.isEmpty()){ return; } for (String orgId : orgList) { ExerciseReCourse exerCourse = new ExerciseReCourse(); exerCourse.setExerciseCourseId(null); exerCourse.setOrgId(orgId); exerCourse.setGroupId(groupId); exerCourse.setCollegeCourseId(collegeCourseId); exerCourse.setDeleteFlag(false); exerCourse.setOrderNum(orderMap.get(groupId)); TraceUtils.setCreateTrace(exerCourse); save(exerCourse); this.courseWareService.insertOrgCourseware(groupId, ClientUtils.getOrgId(), orgId, collegeCourseId); } } /** * 指定给班级 * @param groupId * @param classIds * @param group * @param collegeCourseId * @param classMap */ public void insertClassGroup(String groupId, String classIds[], ExerciseGroup group, String collegeCourseId, Map classMap,Map orderMap) { //章节id Map origChapterMap = new HashMap(); Map subjectMap = new HashMap(); String hql = "from ExerciseGroupExtend where deleteFlag is false and groupId=? "; // 查询练习组扩展表 ExerciseGroupExtend extend = this.findUnique(hql, CollectionUtils.newList(groupId), ExerciseGroupExtend.class); //hql = " from ExerciseGroupItemRe where exerciseGroupId = ? and deleteFlag is false "; //List lstItem = find(hql, CollectionUtils.newList(groupId), ExerciseGroupItemRe.class); // 查询出所有不符合条件的数据 hql = "select classId from ExerciseGroup where classId in (:classIds) and originExerciseId = :groupId and deleteFlag is false"; Map args = new HashMap(); args.put("classIds", classIds); args.put("groupId", groupId); List strings = findByComplexHql(hql, args, String.class); List classList = new ArrayList(); for (String classId : classIds) { classList.add(classId); } // 剔除不符合的classId classList.removeAll(strings); if(classList.isEmpty()){ return; } if(StringUtils.isNotEmpty(group.getSubjectId())){ // 一次性查询班级ID对应的classSubjectId hql = " from SchClassSubject where classId in(:classIds) and origSubjectId = :subjectId and deleteFlag is false"; args = new HashMap(); args.put("classIds", classList.toArray()); args.put("subjectId", group.getSubjectId()); List lstClassSubject = findByComplexHql(hql, args, SchClassSubject.class); for (SchClassSubject schClassSubject : lstClassSubject) { subjectMap.put(schClassSubject.getClassId(), schClassSubject.getClassSubjectId()); } } for (String classId : classList) { ExerciseGroup newGroup = new ExerciseGroup(); newGroup.setAllCount(group.getAllCount()); newGroup.setAttribute1(group.getAttribute1()); newGroup.setAttribute2(group.getAttribute2()); newGroup.setCollegeCourseId(collegeCourseId); newGroup.setDeleteFlag(false); newGroup.setDoCount(group.getDoCount()); newGroup.setName(group.getName()); newGroup.setOrgId(classMap.get(classId)); newGroup.setType(group.getType()); newGroup.setClassId(classId); newGroup.setOriginExerciseId(groupId); newGroup.setOrderNum(group.getOrderNum()); newGroup.setSubjectId(subjectMap.get(classId)); if(null != origChapterMap.get(classId)){ newGroup.setChapterId(origChapterMap.get(classId).getChapterId()); }else{ newGroup.setChapterId(null); } TraceUtils.setCreateTrace(newGroup); this.saveExerciseGroup(newGroup); if (extend != null) { if (StringUtils.isNotBlank(extend.getExerciseTime())) { addExerciseGroupExtendTime(newGroup.getGroupId(), extend.getExerciseTime(), extend.getRepeatFlag()); } if (newGroup.getType() == ExerciseGroup.TYPE_HOMEWORK) {// 家庭作业 // 添加是否重做 addExerciseGroupExtendTime(newGroup.getGroupId(), null, extend.getRepeatFlag()); } } try { this.doCopyExerciseItem(newGroup.getGroupId(), groupId, null, 2); }catch (IllegalAccessException e) { log.error("下发练习出错", e); } catch (InvocationTargetException e) { log.error("下发练习出错", e); } catch (InstantiationException e) { log.error("下发练习出错", e); } catch (NoSuchMethodException e) { log.error("下发练习出错", e); } } } /** * 添加练习时间 * * @param groupId * @param exerciseTime * @return */ public Result addExerciseGroupExtendTime(String groupId, String exerciseTime, boolean repeatFlag) { String hql = "from ExerciseGroupExtend where deleteFlag is false and groupId=? "; // 查询练习组扩展表 ExerciseGroupExtend extend = this.findUnique(hql, CollectionUtils.newList(groupId), ExerciseGroupExtend.class); if (null == extend) { extend = new ExerciseGroupExtend(); extend.setGroupId(groupId); extend.setExerciseTime(exerciseTime); extend.setRepeatFlag(repeatFlag); insertExerciseGroupExtend(extend); } else { extend.setExerciseTime(exerciseTime); extend.setRepeatFlag(repeatFlag); updateExerciseGroupExtend(extend); } return new Result(true); } /** * 新增练习扩展表 * * @param extend * @return */ public Result insertExerciseGroupExtend(ExerciseGroupExtend extend) { extend.setDeleteFlag(false); TraceUtils.setCreateTrace(extend); this.save(extend); return new Result(true); } /** * 更新练习扩展表 * * @param extend * @return */ public Result updateExerciseGroupExtend(ExerciseGroupExtend extend) { TraceUtils.setUpdateTrace(extend); this.save(extend); return new Result(true); } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#readExerciseItems(java.lang.String) */ @Override public List readExerciseItems(String groupId) { ExerciseGroup group = read(ExerciseGroup.class, groupId); List lst = group.getItems(); TraceUtils.removeDelete(lst); return lst; } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#readExerciseItems(java.lang.String) 20150901:增加排序,习题数据和前台app顺序默认一致,题号保持一致。随机练习处理 */ @Override public List readExerciseItemsWithNo(String groupId) { ExerciseGroup group = read(ExerciseGroup.class, groupId); if (null == group) { return null; } // 默认章节练习 String hql = "select item,re.docOrder,re.relationId " + "from ExerciseItem item,ExerciseGroupItemRe re " + "where re.exerciseGroupId=? " + "and re.exerciseItemId=item.exerciseId " + "and item.deleteFlag is false " + "and re.deleteFlag is false " + "order by re.itemOrder "; // 随机练习,顺序练习 if (ExerciseGroup.TYPE_EXERCISE_RANDOM == group.getType() || ExerciseGroup.TYPE_EXERCISE_SEQUENCE == group.getType()) { hql = "select item,re.docOrder,re.relationId " + "from ExerciseItem item,ExerciseGroupItemRe re " + "where re.exerciseGroupId=? and " + "re.exerciseItemId=item.exerciseId " + "and item.deleteFlag is false " + "and re.deleteFlag is false " + "order by item.chapterId, re.itemOrder "; } List objs = this.exerDAO.findwithRawResult(hql, CollectionUtils.newList(groupId)); List items = new ArrayList(objs.size()); ExerciseItem item; ExerciseItem newitem; if (null != objs && !objs.isEmpty()) { for (int iNum = 0; iNum < objs.size(); iNum++) { if (null == objs.get(iNum)) { continue; } item = new ExerciseItem(); try { newitem = (ExerciseItem) objs.get(iNum)[0]; newitem.setOptions(null); newitem.setScores(null); newitem.setAnalysises(null); BeanUtils.copyProperties(item, newitem); } catch (IllegalAccessException e) { log.error(e, e); } catch (InvocationTargetException e) { log.error(e, e); } // 此序号和app一致 item.setItemNo(iNum + 1); // 此序号和导入的doc文档一致,如果是导入的习题 if (null != objs.get(iNum)[1]) { item.setDocNo((int) objs.get(iNum)[1]); } // 关联表ID if (null != objs.get(iNum)[2]) { item.setReId((String) objs.get(iNum)[2]); } items.add(item); } } return items; } /** * 查看问卷详情 * * @param groupId * 问题组id * @param evaluateTemId * 模板id * @return */ @Override public List readExerciseItems4Evaluate(String groupId) { ExerciseGroup group = this.read(ExerciseGroup.class, groupId); if (null == group) { new ResultJson(false, "习题组不存在"); } QExerciseItem qItem = QExerciseItem.exerciseItem; QExerciseGroupItemRe qRe = QExerciseGroupItemRe.exerciseGroupItemRe; List lstItems = this.getQueryFactory() .select(qItem) .from(qItem,qRe) .where(qItem.exerciseId.eq(qRe.exerciseItemId) .and(qRe.exerciseGroupId.eq(groupId)) .and(qItem.deleteFlag.eq(false)) .and(qRe.deleteFlag.eq(false))) .orderBy(qRe.itemOrder.asc()) .fetch(); if(lstItems.isEmpty()){ return lstItems; } // 0.组装参数 Map argsMap = new HashMap(); Object[] args = new Object[lstItems.size()]; for(int i=0; i lstAnalisis = this.findByComplexHql(hql_analisis, argsMap, ExerciseItemAnalisi.class); Map analisiMap = new HashMap(lstAnalisis.size()); for(ExerciseItemAnalisi analisis:lstAnalisis){ analisiMap.put(analisis.getExerciseItemId(), analisis); } // 2.查询练习题目答案选项 Map> optionsMap = new HashMap>(lstItems.size()); Map answerMap = new HashMap(); String hql_options = "from ExerciseItemOption where exerciseItemId in (:exerciseIds) and deleteFlag is false order by exerciseItemId, optionOrder "; List lstAllOptions = this.findByComplexHql(hql_options, argsMap, ExerciseItemOption.class); // 2.1.组装参数 用于查询练习选项图片 Map argsImgMap = new HashMap(); Object[] argImgs = new Object[lstAllOptions.size()]; for(int i=0; i lstItemImgs = this.findByComplexHql(hql_itemImgs, argsMap, ExerciseObjectImg.class); Map> imgItemMap = ExerciseUtils.packageExerciseItemImg(lstItemImgs); Map> imgOptionMap = null; if(argImgs.length > 0) { // 2-3-2查询题目选项是否关联图片 String hql_optionImgs = "from ExerciseObjectImg where exerciseObjectId in (:optionIds) and deleteFlag is false and objectType=2"; List lstOptionImgs = this.findByComplexHql(hql_optionImgs, argsImgMap, ExerciseObjectImg.class); imgOptionMap = ExerciseUtils.packageExerciseItemImg(lstOptionImgs); } // 重新组装练习 ExerciseUtils.packageExerciseItem(optionsMap, answerMap, lstAllOptions, imgOptionMap); // 4.重新组装返回结果 String exerciseId = null; for(ExerciseItem item:lstItems){ // 4.0 分析结果 exerciseId = item.getExerciseId(); // 得到练习组id if(StringUtils.isNotBlank(groupId)){ item.setExerciseGroupId(groupId); } // 4.3 题目选项 item.setOptions(optionsMap.get(exerciseId)); // 4.5题目中是否有图片 if(imgItemMap.get(exerciseId) != null){ item.setImgs(imgItemMap.get(exerciseId)); } if(analisiMap.get(exerciseId) != null){ item.setAnalisis(analisiMap.get(exerciseId)); } } return lstItems; } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#insertExerciseItem(java.lang.String, com.iqtogether.qxueyou.exercise.model.ExerciseItem, java.util.List) */ @Override public Result insertExerciseItem(String groupId, ExerciseItem item, List lstOptions, String analysis) { TraceUtils.setCreateTrace(lstOptions); // 1. 保存习题 ExerciseGroup group = this.read(ExerciseGroup.class, groupId); handlerExerciseItem(group, item); save(item); // 2. 保存习题和习题组关系 // 获取一个习题需要跟新的关系条数 List result = initExerciseGroup(groupId); // 得到当前组题目的最大题号 int maxGroupItemOrder = queryExerciseGroupItemNo(groupId); List groupRes = initExerciseGroupItemRe(result, item.getExerciseId(), getGroupReMaxOrder(groupId), ++maxGroupItemOrder ); // 得到最大的ORDER saveOrUpdateAll(groupRes); // 20150618:配合前台app,所有修改同时修改group表最后修改时间 updateGroupUpdateTimeByList(result); // 3. 保存习题解析 ExerciseItemAnalisi analysisVO = new ExerciseItemAnalisi(); analysisVO.setAnalysis(analysis); analysisVO.setAccuracy(BigDecimal.ZERO); analysisVO.setSubmitCorrectNumber(BigInteger.ZERO); analysisVO.setSubmitNumber(BigInteger.ZERO); item.setAnalisis(analysisVO); saveAnalysis(item); // 4. 保存习题选项 for (ExerciseItemOption option : lstOptions) { option.setExerciseItemId(item.getExerciseId()); save(option); // 新增习题选项图片 updateExerOptionObjImgId(option); } item.setOptions(lstOptions); // 新增习题图片 updateExerciseObjImgId(item); //保存题目分数 List lstExerciseItemScore = item.getScores(); if(lstExerciseItemScore!=null && lstExerciseItemScore.size()>0){ for (ExerciseItemScore score : lstExerciseItemScore) { TraceUtils.setCreateTrace(score); score.setGroupId(groupId); score.setExerciseItemId(item.getExerciseId()); save(score); } } // if(StringUtils.isEmpty(group.getClassId())){ // // 同步习题 // String hql = " from ExerciseGroup where originExerciseId = ? and deleteFlag is false and groupId != ?"; // List lstGroup = find(hql, CollectionUtils.newList(group.getOriginExerciseId(), groupId), ExerciseGroup.class); // List items = find("from ExerciseItem where exerciseId = ?", CollectionUtils.newList(item.getExerciseId()), ExerciseItem.class); // for (ExerciseGroup exerciseGroup : lstGroup) { // exerciseGroup.setAllCount(group.getAllCount()); // TraceUtils.setUpdateTrace(exerciseGroup); // this.saveExerciseGroup(exerciseGroup); // try { // this.doCopyExerciseItem(exerciseGroup.getGroupId(), groupId, items, 2); // } catch (IllegalAccessException | InstantiationException | InvocationTargetException // | NoSuchMethodException e) { // log.error("新增练习同步到班级错误", e); // } // } // } return new Result(true, item.getExerciseId()); } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#insertExerciseItem(java.lang.String, com.iqtogether.qxueyou.exercise.model.ExerciseItem, java.util.List) */ @Override public ResultJson insertExerciseItem4Evaluate(String groupId, ExerciseItem item, List lstOptions,String analysis,JSONArray titleImgs) { // 1. 保存习题 TraceUtils.setCreateTrace(item); this.save(item); // 2、保存习题关联组 QExerciseGroupItemRe qRe =QExerciseGroupItemRe.exerciseGroupItemRe; Integer maxGroupItemOrder = this.getQueryFactory().select(qRe.itemOrder.max()) .from(qRe).where(qRe.deleteFlag.eq(false).and(qRe.exerciseGroupId.eq(groupId))) .fetchOne(); if (maxGroupItemOrder == null) { maxGroupItemOrder = 0; } ExerciseGroupItemRe re = new ExerciseGroupItemRe(); re.setExerciseGroupId(groupId); re.setExerciseItemId(item.getExerciseId()); re.setItemOrder(maxGroupItemOrder); re.setDeleteFlag(false); this.save(re); // 题目组题目个数+1 QExerciseGroup g = QExerciseGroup.exerciseGroup; this.getQueryFactory() .update(g) .set(g.allCount, g.allCount.add(BigInteger.ONE)) .where(g.groupId.eq(groupId)) .execute(); // 3. 保存习题选项 for (int i = 0; i < lstOptions.size(); i++) { ExerciseItemOption option = lstOptions.get(i); option.setExerciseItemId(item.getExerciseId()); option.setOptionId(null); option.setOptionOrder(letter[i]); TraceUtils.setCreateTrace(option); this.save(option); // 更新选项图片 updateEvaExerOptionObjImgId(option); ExerciseItemScore objExerciseItemScore = new ExerciseItemScore(); TraceUtils.setCreateTrace(objExerciseItemScore); objExerciseItemScore.setAttribute1(option.getOptionId()); objExerciseItemScore.setExerciseItemId(item.getExerciseId()); objExerciseItemScore.setExerciseItemAnswer(letter[i]); objExerciseItemScore.setScore(String.valueOf(option.getScore())); this.save(objExerciseItemScore); } // 更新题目图片 this.updateEvaExerciseObjImgId(titleImgs,item.getExerciseId()); // 4. 保存习题解析 ExerciseItemAnalisi analysisVO = new ExerciseItemAnalisi(); analysisVO.setAnalysis(analysis); analysisVO.setAccuracy(BigDecimal.ZERO); analysisVO.setSubmitCorrectNumber(BigInteger.ZERO); analysisVO.setSubmitNumber(BigInteger.ZERO); TraceUtils.setCreateTrace(analysisVO); analysisVO.setDeleteFlag(false); analysisVO.setExerciseItemId(item.getExerciseId()); save(analysisVO); return new ResultJson(true); } /** * 更新习题选项图片对象结果 * * @param optionId * @param imgIds * @return */ private Result updateExerciseObjImgId(ExerciseItem item) { List imgs = item.getImgs(); if (imgs == null || imgs.isEmpty()) { return new Result(false); } Object[] imgIds = new Object[imgs.size()]; for (int i = 0; i < imgs.size(); i++) { imgIds[i] = imgs.get(i).getImgId(); } String hql = "update ExerciseObjectImg set exerciseObjectId='" + item.getExerciseId() + "' where imgId=? and deleteFlag is false"; this.bulkUpdateInLoop(hql, imgIds); return new Result(true); } /** * 更新习题选项图片对象结果 * * @param optionId * @param imgIds * @return */ private Result updateExerOptionObjImgId(ExerciseItemOption option) { List imgs = option.getImgs(); if (imgs == null || imgs.isEmpty()) { return new Result(false); } Object[] imgIds = new Object[imgs.size()]; for (int i = 0; i < imgs.size(); i++) { imgIds[i] = imgs.get(i).getImgId(); } String hql = "update ExerciseObjectImg set exerciseObjectId='" + option.getOptionId() + "' where imgId=? and deleteFlag is false"; this.bulkUpdateInLoop(hql, imgIds); return new Result(true); } /** * 处理exerciseItem * * @param groupId * @param item */ private void handlerExerciseItem(ExerciseGroup group, ExerciseItem item) { // 如果是章节练习,将章节写到exerciseItem if (ExerciseGroup.TYPE_CHAPTER_ITEM == group.getType()) { item.setChapterId(group.getAttribute2()); } TraceUtils.setCreateTrace(item); } private int getGroupReMaxOrder(String groupId) { String hql = "select max(itemOrder) from ExerciseGroupItemRe where deleteFlag is false and exerciseGroupId = ? "; Integer maxOrder = this.findUnique(hql, CollectionUtils.newList(groupId), Integer.class); if (null == maxOrder) { maxOrder = 0; } return maxOrder + 1; } /** * 刪除练习关联表数据 * * @param reIds * @return */ private Result deleteExerciseGroupRe(String[] reIds) { String hql = "update ExerciseGroupItemRe set deleteFlag=1 where relationId=? "; this.bulkUpdateInLoop(hql, reIds); return new Result(true); } /** * 删除练习题:只删除关系 (统一班级下,顺序随机 同步删除) * * @param exerciceIds * @param reIds * @param groupId * @return */ @SuppressWarnings("unchecked") public Result deleteExerciseItems(String[] exerciceIds, String[] reIds, String groupId) { ExerciseGroup group = this.read(ExerciseGroup.class, groupId); // 1.更新组练习数量值 总量减去本次删除个数 group.setAllCount(group.getAllCount().subtract(new BigInteger(String.valueOf(exerciceIds.length)))); TraceUtils.setUpdateTrace(group); this.save(group); // 2.删除练习组关联表数据 deleteExerciseGroupRe(reIds); // 3.重新排序此组的字段 updateExerciseItemNewNo(groupId); //清除缓存 redisTemplate.delete(groupId); return new Result(true); } /** * 重新排序 * * @param groupId * @return */ private Result updateExerciseItemNewNo(String groupId) { // 升序排序 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.isEmpty()) { return null; } // 重新排序 for (int i = 0; i < lstRe.size(); i++) { lstRe.get(i).setItemOrder(i + 1); } this.saveOrUpdateAll(lstRe); return new Result(true); } /** * 根据groupId 和 itemId 读取 ExerciseGroupItemRe * * @param groupId * @param itemId * @return */ /* * private ExerciseGroupItemRe readItemRe(String groupId,String itemId){ * * String hql = "from ExerciseGroupItemRe where exerciseGroupId = ? and exerciseItemId = ? "; ExerciseGroupItemRe itemRe = this.findUnique(hql, CollectionUtils.newList( groupId,itemId), ExerciseGroupItemRe.class); * * return itemRe; } */ /** * 查询最近的记录 * * @param hql * @param page * @param args * @return */ /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#importItems(java.lang.String, java.lang.String) */ @Override public Result doImportItems(String groupId, File file) { List items = null; try { items = parseFile(file); } catch (Exception e) { log.error(e, e); return new Result(false, "读取文档失败"); } insertItems(groupId, items); // 4.20150618:配合前台app,所有修改同时修改group表最后修改时间 List result = initExerciseGroup(groupId); updateGroupUpdateTimeByList(result); FileUtils.deleteQuietly(file.getParentFile()); return new Result(true, "已导入" + items.size() + "道习题"); } /** * 插入习题 * * @param items */ private void insertItems(String groupId, List items) { int i = 0; // 获取一个习题需要跟新的关系条数 List result = initExerciseGroup(groupId); ExerciseGroup group = this.read(ExerciseGroup.class, groupId); // 得到当前组题目的最大题号 int maxGroupItemOrder = queryExerciseGroupItemNo(groupId); /*String hql = " from ExerciseGroup where originExerciseId = ? and deleteFlag is false and groupId != ?"; List lstGroup = find(hql, CollectionUtils.newList(group.getOriginExerciseId(), groupId), ExerciseGroup.class);*/ for (ExerciseItem item : items) { TraceUtils.setCreateTrace(item); item.setDeleteFlag(false); // 1. 习题 handlerExerciseItem(group, item); save(item); // 2. 保存习题组-习题关系(练习和非练习) List groupRes = initExerciseGroupItemRe(result, item.getExerciseId(), item.getItemNo() == null ? i++ : item.getItemNo(), ++maxGroupItemOrder ); saveOrUpdateAll(groupRes); if(StringUtils.isEmpty(group.getClassId())){ // 同步习题 String hql = " from ExerciseGroup where originExerciseId = ? and deleteFlag is false and groupId != ?"; List lstGroup = find(hql, CollectionUtils.newList(group.getOriginExerciseId(), groupId), ExerciseGroup.class); List lstItems = find("from ExerciseItem where exerciseId = ?", CollectionUtils.newList(item.getExerciseId()), ExerciseItem.class); for (ExerciseGroup exerciseGroup : lstGroup) { exerciseGroup.setAllCount(group.getAllCount()); TraceUtils.setUpdateTrace(exerciseGroup); this.saveExerciseGroup(exerciseGroup); try { this.doCopyExerciseItem(exerciseGroup.getGroupId(), groupId, lstItems, 2); } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) { log.error("新增练习同步到班级错误", e); } } } // 3. 保存习题解析 if (item.getAnalisis() != null) { saveAnalysis(item); } // 4. 保存习题选项 for (ExerciseItemOption option : item.getOptions()) { TraceUtils.setCreateTrace(option); option.setDeleteFlag(false); option.setExerciseItemId(item.getExerciseId()); save(option); } } } /** * 保存习题解析 * * @param item */ private void saveAnalysis(ExerciseItem item) { ExerciseItemAnalisi analysis = item.getAnalisis(); if(StringUtils.isEmpty(analysis.getExerciseAnalisisId())){ TraceUtils.setCreateTrace(analysis); analysis.setDeleteFlag(false); analysis.setExerciseItemId(item.getExerciseId()); save(analysis); }else{ TraceUtils.setUpdateTrace(analysis); this.save(analysis); } } /** * 解析word * * @param groupId * 习题组id * @param file * word文件绝对路径 * @return * @throws RuntimeException */ private List parseFile(File file) throws Exception { Handler handler = new Handler(); // from office to txt,docx:自带序号无法解析出来,doc可以 String txtFilePath = transformDocToTxt(file); FileReader reader = null; BufferedReader br = null; try { reader = new FileReader(txtFilePath); br = new BufferedReader(reader); String currLine = ""; while ((currLine = br.readLine()) != null) { handler.parse(currLine); } } catch (Exception e) { throw new Exception("读取文档失败", e); } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(reader); } Doc doc = handler.result(); return doc.convertExerciseItems(); } /** * 从office转换到txt:2007转换:自带序号格式会丢失;2003会解析出来 * * @param file * office文档 * @return */ private String transformDocToTxt(File file) { FileInputStream fis = null; FileWriter writer = null; String strText = ""; try { String fileExtention = fileExtension(file.getName()); fis = new FileInputStream(file.getAbsolutePath()); if ("doc".equals(fileExtention)) { WordExtractor extractor = new WordExtractor(fis); // 获取Word文件中的文本+自带序号 strText = extractor.getText(); extractor.close(); } else if ("docx".equals(fileExtention)) { OPCPackage opcPackage = POIXMLDocument.openPackage(file.getAbsolutePath()); POIXMLTextExtractor extractor = new XWPFWordExtractor(opcPackage); // 只能获取Word文件中的文本,不能取到office序号 strText = extractor.getText(); extractor.close(); } else { throw new RuntimeException("文件格式错误, 请上传word文档(.doc及.docx)格式", null); } // 将得到的文本全角转半角 strText = formatFullToHalf(strText); // 解决空格保存为txt的时候,乱码为? byte bytes[] = { (byte) 0xC2, (byte) 0xA0 }; String UTFSpace = new String(bytes, "UTF-8"); strText = strText.replaceAll(UTFSpace, " "); File txtFile = new File(file.getParentFile().getAbsolutePath() + "/" + file.getName().substring(0, file.getName().lastIndexOf(".")) + ".txt"); writer = new FileWriter(txtFile, true); writer.write(strText); return txtFile.getAbsolutePath(); } catch (FileNotFoundException e) { throw new RuntimeException("office文档未找到", e); } catch (IOException e) { throw new RuntimeException("office文档读取失败", e); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { IOUtils.closeQuietly(writer); IOUtils.closeQuietly(fis); } } /** * 全角转半角 * * @param oriText * @return */ private String formatFullToHalf(String oriText) { if (null == oriText || oriText.length() <= 0) { return ""; } char[] charArray = oriText.toCharArray(); // 对全角字符转换的char数组遍历 for (int i = 0; i < charArray.length; ++i) { int charIntValue = (int) charArray[i]; // 如果符合转换关系,将对应下标之间减掉偏移量65248;如果是空格的话,直接做转换 if (charIntValue >= 65281 && charIntValue <= 65374) { charArray[i] = (char) (charIntValue - 65248); } else if (charIntValue == 12288) { charArray[i] = (char) 32; } else if (charIntValue == 58033) { // 空格 charArray[i] = (char) 32; } else if (charIntValue == 65380) { // 顿号 charArray[i] = (char) 12289; } else if (charIntValue == 65377) { // 句号 charArray[i] = (char) 12290; } } return new String(charArray); } /** * 解析文件后缀 * * @param filename * @return */ private String fileExtension(String filename) { return filename.substring(filename.lastIndexOf('.') + 1, filename.length()); } /* * (non-Javadoc) * * @see com.iqtogether.qxueyou.exercise.service.IExerciseService#updateExerciseItem(com.iqtogether.qxueyou.exercise.model.ExerciseItem, java.util.List) */ @Override public Result updateExerciseItem(ExerciseItem item, List lstOptions, String analysis) { //先删除所有的option,然后恢复已有的option this.bulkUpdate("update ExerciseItemOption set deleteFlag = true where exerciseItemId=?", new String[]{item.getExerciseId()}); // 保存Option String answer = ""; if(lstOptions!=null){ for (ExerciseItemOption option : lstOptions) { if(option.getChecked()){ if(item.getType()==ExerciseItem.TYPE_TRUE_OR_FALSE){ answer = answer.concat(option.getContent()).concat(","); }else{ answer = answer.concat(option.getOptionOrder()).concat(","); } } option.setExerciseItemId(item.getExerciseId()); if(StringUtils.isNotEmpty(option.getOptionId())){ option.setDeleteFlag(false); TraceUtils.setCreateTrace(option); }else{ TraceUtils.setCreateTrace(option); } save(option); } } // 保存item if(StringUtils.isNotBlank(answer)){ item.setAnswer(answer.substring(0,answer.length()-1)); } TraceUtils.setCreateTrace(item); save(item); // 保存解析 updateItemAnalysis(item, analysis); // 配合前台app,所有修改同时修改group表最后修改时间 // updateGroupUpdateTimeByList(initUpdateExerciseGroup(item.getExerciseId())); //保存题目分数 List lstExerciseItemScore = item.getScores(); if(lstExerciseItemScore!=null && lstExerciseItemScore.size()>0){ for (ExerciseItemScore score : lstExerciseItemScore) { TraceUtils.setCreateTrace(score); score.setGroupId(item.getExerciseGroupId()); save(score); } } return new Result(true, item.getExerciseId()); } /* * 评价模块修改题目 */ @Override public ResultJson updateExerciseItem4Evaluate(ExerciseItem item, List lstOptions, String analysis) { TraceUtils.setUpdateTrace(item); /* // 先移除全部习题 QExerciseItemOption qOption = QExerciseItemOption.exerciseItemOption; this.getQueryFactory() .update(qOption) .set(qOption.deleteFlag, true) .where(qOption.exerciseItemId.eq(item.getExerciseId())) .execute(); // 移除全部分数 QExerciseItemScore qScore = QExerciseItemScore.exerciseItemScore; this.getQueryFactory() .update(qScore) .set(qScore.deleteFlag, true) .where(qScore.exerciseItemId.eq(item.getExerciseId())) .execute();*/ // 先移除全部习题 String hql = "update ExerciseItemOption set DELETE_FLAG = 1 where EXERCISE_ITEM_ID = ?"; super.bulkUpdateInLoop(hql, new String[] { item.getExerciseId() }); // 移除全部分数 String hql2 = "update ExerciseItemScore set DELETE_FLAG = 1 where EXERCISE_ITEM_ID = ?"; super.bulkUpdateInLoop(hql2, new String[] { item.getExerciseId() }); // 1.保存item this.save(item); if(lstOptions != null && lstOptions.size() > 0) { TraceUtils.setCreateTrace(lstOptions); for (int i = 0; i < lstOptions.size(); i++) { ExerciseItemOption option = lstOptions.get(i); option.setExerciseItemId(item.getExerciseId()); if (StringUtils.isNotBlank(option.getOptionId()) && option.getOptionId().startsWith("#")) { option.setOptionId(null); } option.setOptionOrder(letter[i]); save(option); ExerciseItemScore objExerciseItemScore = new ExerciseItemScore(); TraceUtils.setCreateTrace(objExerciseItemScore); objExerciseItemScore.setAttribute1(option.getOptionId()); objExerciseItemScore.setExerciseItemId(item.getExerciseId()); objExerciseItemScore.setExerciseItemAnswer(letter[i]); objExerciseItemScore.setScore(String.valueOf(option.getScore())); objExerciseItemScore.setExerciseItemScoreId(option.getExerciseItemScoreId()); save(objExerciseItemScore); } } // 4. 更新习题解析 QExerciseItemAnalisi analysisVO = QExerciseItemAnalisi.exerciseItemAnalisi; this.getQueryFactory() .update(analysisVO) .set(analysisVO.analysis, analysis) .set(analysisVO.updateTime, new Date(System.currentTimeMillis())) .where(analysisVO.exerciseItemId.eq(item.getExerciseId())) .execute(); return new ResultJson(true); } /** * 更新解析 * * @param item * @param analysis */ private void updateItemAnalysis(ExerciseItem item, String analysis) { if (item.getAnalisis() == null) { ExerciseItemAnalisi analysisVO = new ExerciseItemAnalisi(); TraceUtils.setCreateTrace(analysisVO); analysisVO.setDeleteFlag(false); analysisVO.setAnalysis(analysis); analysisVO.setAccuracy(BigDecimal.ZERO); analysisVO.setSubmitCorrectNumber(BigInteger.ZERO); analysisVO.setSubmitNumber(BigInteger.ZERO); item.setAnalisis(analysisVO); saveAnalysis(item); } else { ExerciseItemAnalisi analysisVO = item.getAnalisis(); TraceUtils.setCreateTrace(analysisVO); analysisVO.setAnalysis(analysis); save(analysisVO); } } /** * 组装ExerciseGroup的list,传入一个groupid,得到同时需要修改的一个或者多个group对象 * * @param groupId * 主键 * @return */ @Override public List initExerciseGroup(String groupId) { // 0.获取groupID对应的type,如果是习题(顺机序、随和章节,需要按不同情况同时更新) // 1.如果是章节练习,需要同步修改顺序随机练习 // 2.如果是顺序,需同步修改随机;如果是随机练习亦然 ExerciseGroup group = read(ExerciseGroup.class, groupId); List result = new ArrayList(); short sType = 0; if (group != null) { sType = group.getType(); String hsql = ""; if (sType == ExerciseGroup.TYPE_CHAPTER_ITEM || sType == ExerciseGroup.TYPE_EXERCISE_RANDOM || sType == ExerciseGroup.TYPE_EXERCISE_SEQUENCE) { hsql = "from ExerciseGroup where classId = ? and (type = ? or type = ?) and deleteFlag is false "; result = find(hsql, CollectionUtils.newList(ClientUtils.getClassId(), ExerciseGroup.TYPE_EXERCISE_SEQUENCE, ExerciseGroup.TYPE_EXERCISE_RANDOM), ExerciseGroup.class); } if (sType != ExerciseGroup.TYPE_EXERCISE_SEQUENCE && sType != ExerciseGroup.TYPE_EXERCISE_RANDOM) { result.add(group); } } return result; } /** * 组装ExerciseGroup的list,传入一个groupid,得到同时需要修改的一个或者多个group对象 * * @param groupId * 主键 * @return */ public List initUpdateExerciseGroup(String exerciseId) { // 修改关联的exerciseId,deleteflag is false(暂时全部处理) List lstGroup = new ArrayList(); String hql = "select e.exerciseGroupId from ExerciseGroupItemRe e where deleteFlag is false and e.exerciseItemId = ? "; List groupId = find(hql, CollectionUtils.newList(exerciseId), Object.class); if (null != groupId && !groupId.isEmpty()) { String hql0 = " from ExerciseGroup e where e.deleteFlag is false and e.groupId in ( "; for (int i = 0; i < groupId.size(); i++) { if (i == groupId.size() - 1) { hql0 = hql0.concat(" ? ) "); } else { hql0 = hql0.concat(" ?, "); } } lstGroup = find(hql0, groupId, ExerciseGroup.class); } return lstGroup; } /** * 批量删除ExerciseGroup,删除逻辑:如果是练习,顺序和随机练习时同步删除的(此处代码) * * @param groupId * 主键,多个id时以","分隔 * @return */ public Result deleteExerciseGroup(String groupId) { // 逻辑删除,只需要修改exercise_group、exercise_item的删除标识即可 if (StringUtils.isNotBlank(groupId)) { // 需要删除的练习组 Object[] arrGroupId = groupId.split(","); // 存储顺序练习或者随机练习 List lstResults = initDeleteExerciseGroup(arrGroupId); // 需要删除的练习类型下的练习题 //List lstItem = initDeleteExerciseItem(lstResults); // 删除习题组,修改习题组最后修改时间 if (lstResults != null) { for (ExerciseGroup group : lstResults) { group.setDeleteFlag(true); TraceUtils.setUpdateTrace(group); this.saveExerciseGroup(group); // group.setUpdateTime(new Date(System.currentTimeMillis())); } } /*// 删除习题 if (lstItem != null) { for (ExerciseItem item : lstItem) { item.setDeleteFlag(true); } saveOrUpdateAll(lstItem); }*/ // 20150618:配合前台app,所有修改同时修改group表最后修改时间 //updateGroupUpdateTimeByList(lstResults); } return new Result(true); } /** * 组装练习组 * * @param name * 练习名称 * @param type * 练习组类型 * @param lessonId * 课程 * @param chapterId * 章节 * @return */ private List initExerciseGroupList(String name, short type, String lessonId, String chapterId, int iCount) { List lstExerciseGroup = new ArrayList(); List lstType = new ArrayList(); // iCount:0、 新增三种(选择了章节),增加两种:没有选择章节;1,新增两种(顺序随机),2,新增一种(章节),3的话,不增加 if (type == ExerciseGroup.TYPE_EXERCISE_SEQUENCE) { if (iCount == 0) { lstType.add(type); lstType.add(ExerciseGroup.TYPE_EXERCISE_RANDOM); if (StringUtils.isNotBlank(lessonId) && StringUtils.isNotBlank(chapterId)) { lstType.add(ExerciseGroup.TYPE_CHAPTER_ITEM); } } else if (iCount == 1) { lstType.add(type); lstType.add(ExerciseGroup.TYPE_EXERCISE_RANDOM); } else if (iCount == 2) { lstType.add(ExerciseGroup.TYPE_CHAPTER_ITEM); } else if (iCount == 3 && StringUtils.isNotBlank(chapterId)) {// 等于3,章节练习,顺序练习,随机练习都有,增加章节练习 lstType.add(ExerciseGroup.TYPE_CHAPTER_ITEM); } } else { lstType.add(type); } for (short iType : lstType) { lstExerciseGroup.add(initExerciseGroup(name, iType, lessonId, chapterId)); } return lstExerciseGroup; } /** * 组装练习 * * @param name * 练习名称 * @param type * 练习类型 * @param lessonId * 课程 * @param chapterId * 章节 * @return */ private ExerciseGroup initExerciseGroup(String name, short type, String lessonId, String chapterId) { // 构建实体 ExerciseGroup objExerciseGroup = new ExerciseGroup(); TraceUtils.setCreateTrace(objExerciseGroup); objExerciseGroup.setDeleteFlag(false); objExerciseGroup.setAllCount(BigInteger.ZERO); objExerciseGroup.setSubjectId(lessonId); objExerciseGroup.setChapterId(chapterId); if (ExerciseGroup.TYPE_EXERCISE_RANDOM == type) { objExerciseGroup.setName("随机练习"); } else if (ExerciseGroup.TYPE_EXERCISE_SEQUENCE == type) { objExerciseGroup.setName("顺序练习"); } else { objExerciseGroup.setName(name); } objExerciseGroup.setType(type); objExerciseGroup.setClassId(ClientUtils.getClassId()); objExerciseGroup.setOrgId(ClientUtils.getOrgId()); objExerciseGroup.setCollegeCourseId(ClientUtils.getCourseId()); // 章节练习需要存储 if (type == ExerciseGroup.TYPE_CHAPTER_ITEM) { // 章节练习存放lessonId //objExerciseGroup.setAttribute1(lessonId); // 章节练习存放chapterID objExerciseGroup.setAttribute2(chapterId); } return objExerciseGroup; } /** * 组装关联信息 * * @param lstGroup * 练习组 * @param itemId * 练习题id * @param itemOrder * 练习题序号 * @return */ private List initExerciseGroupItemRe(List lstGroup, String itemId, int docOrder,int maxGroupItemOrder) { List lstExerciseGroupItemRe = new ArrayList(); for (ExerciseGroup group : lstGroup) { ExerciseGroupItemRe re = new ExerciseGroupItemRe(); re.setExerciseGroupId(group.getGroupId()); re.setExerciseItemId(itemId); re.setItemOrder(maxGroupItemOrder); re.setDeleteFlag(false); if (docOrder > -1) { re.setDocOrder(docOrder); } lstExerciseGroupItemRe.add(re); } return lstExerciseGroupItemRe; } /** * 查询当前组的最大题号 * * @param groupId * @return */ private int queryExerciseGroupItemNo(String groupId) { String hql = "select max(itemOrder) from ExerciseGroupItemRe t where deleteFlag is false and exerciseGroupId=?"; Integer itemOrder = this.findUnique(hql, CollectionUtils.newList(groupId), Integer.class); if (itemOrder == null) { return 0; } return itemOrder; } /** * 组装需要删除的练习组 * * @param lstResult * 存储非顺序 练习非随机练习 * @param lstResults * 存储顺序练习或者随机练习 * @param arrGroupId * groupid的数组 */ private List initDeleteExerciseGroup(Object[] arrGroupId) { List lstResults = new ArrayList(); List lstResult = new ArrayList(); String hsql = " from ExerciseGroup where groupId in ( "; for (int i = 0; i < arrGroupId.length - 1; i++) { hsql = hsql.concat("? , "); } hsql = hsql.concat("? ) "); List result = find(hsql, CollectionUtils.newList(arrGroupId), ExerciseGroup.class); // 一个班级只有一个顺序练习和一个随机练习 int iNumber = 0; for (ExerciseGroup group : result) { if (group.getType() == ExerciseGroup.TYPE_EXERCISE_SEQUENCE || group.getType() == ExerciseGroup.TYPE_EXERCISE_RANDOM) { iNumber++; lstResults.add(group); } else { lstResult.add(group); } } // 一个班级只选择了顺序或者只选择了随机,两个类型都需要删除 if (iNumber == 1) { hsql = "from ExerciseGroup where type in (?,?) and classId = ? and deleteFlag is false "; lstResults = find(hsql, CollectionUtils.newList(ExerciseGroup.TYPE_EXERCISE_SEQUENCE, ExerciseGroup.TYPE_EXERCISE_RANDOM, lstResults.get(0).getClassId()), ExerciseGroup.class); } lstResults.addAll(lstResult); return lstResults; } /** * 获取需要删除的练习题(删除习题组时调用) * * @param lstResults * 需要删除的练习组 *//* private List initDeleteExerciseItem(List lstResults) { String hsql = "from ExerciseItem where exerciseId in ( select exerciseItemId from ExerciseGroupItemRe " + " where deleteFlag is false and exerciseGroupId in ( "; List arrGroupId = new ArrayList(); for (int i = 0; i < lstResults.size(); i++) { if (i != lstResults.size() - 1) { hsql = hsql.concat("? , "); } arrGroupId.add(lstResults.get(i).getGroupId()); } // 需要删除的练习题(为练习类型时) hsql = hsql.concat("? ) group by exerciseItemId having count(1) = 3 )"); // 这个SQL特别慢 List lstItem = find(hsql, arrGroupId, ExerciseItem.class); List lstItems = new ArrayList(); // 剔除顺序,随机、章节练习 List lstParams = new ArrayList(); for (ExerciseGroup group : lstResults) { if (group.getType() != ExerciseGroup.TYPE_EXERCISE_SEQUENCE && group.getType() != ExerciseGroup.TYPE_CHAPTER_ITEM && group.getType() != ExerciseGroup.TYPE_EXERCISE_RANDOM) { lstParams.add(group.getGroupId()); } } if (!lstParams.isEmpty()) { hsql = "from ExerciseItem where exerciseId in ( select exerciseItemId from ExerciseGroupItemRe where deleteFlag is false and exerciseGroupId in ( "; for (int i = 0; i < lstParams.size() - 1; i++) { hsql = hsql.concat("? , "); } hsql =hsql.concat( "? ) )"); lstItems = find(hsql, lstParams, ExerciseItem.class); } // 需要删除的习题 if (lstItem != null) { lstItem.addAll(lstItems); } return lstItem; }*/ /** * :后台 插入评估模板时调用 * * @param name * @param type * @return */ public ExerciseGroup insertExerciseGroup(String name, short type) { ExerciseGroup obj = new ExerciseGroup(); TraceUtils.setCreateTrace(obj); obj.setName(name); obj.setType(type); obj.setClassId(ClientUtils.getClassId()); obj.setOrgId(ClientUtils.getOrgId()); save(obj); // 保存 return obj; } /** * 查询练习列表,还需查询联系下面习题个数 * * @param hql * @param args * @return */ public List queryExerciceGroupList(String hql, List args) { return exerDAO.queryExerciceGroupList(hql, args); } /** * 所有练习修改操作需要同时修改group的updateTime * * @param lstGroup */ private void updateGroupUpdateTimeByList(List lstGroup) { if (null != lstGroup && !lstGroup.isEmpty()) { for (ExerciseGroup obj : lstGroup) { int iExerciseCount = this.findCount("select count(1) from ExerciseGroupItemRe where deleteFlag is false and exerciseGroupId = ?", CollectionUtils.newList(obj.getGroupId())); obj.setAllCount(BigInteger.valueOf(iExerciseCount)); obj.setUpdateTime(new Date()); this.saveExerciseGroup(obj); } //saveOrUpdateAll(lstGroup); } } /** * 后台:批量删除ExerciseGroup * * @param groupId * 主键,多个id时以","分隔 * @param type * 多个type时以","分隔 * @return */ public Result deleteExerciseGroup(String groupId, String type, String deleteType,Integer delAll, String orgIds[], String classIds[]) { if (StringUtils.isBlank(groupId) || StringUtils.isBlank(type)) { return new Result(true); } String[] groupIds = groupId.split(","); String[] types = type.split(","); if (groupIds.length != types.length) { return new Result(false); } if ("org".equals(deleteType)) { //管理员删除练习 deleteOrgGroup(groupIds,delAll,orgIds,classIds); return new Result(true); } // 删除逻辑:练习和其他分开处理(SQL执行简单) // 删除练习:随机和顺序是一致的;如果只删除随机或者顺序,只删除章节,则只删除习题组;如果只删除章节:同样只删除组 // 删除时:顺序或者随机+章节:删除组+章节对应的习题 boolean randomFlag = false; boolean chapterFlag = false; if (type.indexOf(String.valueOf(ExerciseGroup.TYPE_EXERCISE_RANDOM)) != -1 || type.indexOf(String.valueOf(ExerciseGroup.TYPE_EXERCISE_SEQUENCE)) != -1) { randomFlag = true; } if (type.indexOf(String.valueOf(ExerciseGroup.TYPE_CHAPTER_ITEM)) != -1) { chapterFlag = true; } // 拆除子方法 Result result = deleteChildExerciseGroup(groupIds, types, randomFlag, chapterFlag); if(!result.isSuccess()){ return result; } return new Result(true); } /** * 拆除子方法 * @param groupIds * @param types * @param randomFlag * @param chapterFlag * @return */ private Result deleteChildExerciseGroup(String[] groupIds, String[] types, boolean randomFlag, boolean chapterFlag) { // 1. 无练习 if (!randomFlag && !chapterFlag) { return deleteExercise(groupIds, groupIds); } // 2. 有随机有章节 if (randomFlag && chapterFlag) { return deleteExerciseAll(groupIds); } // 3.1. 随机、章节只有一种,删除组:第一种情况:保证顺序随机一致;第二种:删除章节 if (randomFlag) { return deleteExerciseSequence(groupIds, types); } return deleteExerciseChapter(groupIds, types); } private void deleteOrgGroup(String groupIds[],Integer delAll, String orgIds[], String classIds[]){ for (String string : groupIds) { if ((orgIds != null && orgIds.length != 0) || (classIds != null && classIds.length != 0)) { //删除要回撤的练习 deleteAppoint(string,orgIds,classIds); }else{ String hql = " from ExerciseReCourse where groupId = ? and deleteFlag is false and orgId = ?"; ExerciseReCourse erc = findUnique(hql, CollectionUtils.newList(string, ClientUtils.getOrgId()), ExerciseReCourse.class); if (erc != null) { erc.setDeleteFlag(true); TraceUtils.setUpdateTrace(erc); save(erc); this.courseWareService.deleteOrgCourseware(erc.getGroupId(), erc.getOrgId()); } /*ExerciseGroup group = this.read(ExerciseGroup.class, string); if(group != null){ TraceUtils.setUpdateTrace(group); group.setDeleteFlag(true); this.saveExerciseGroup(group); }*/ if(delAll==1){ //删除下级 deleteSub(string,ClientUtils.getOrgId()); } } } } @SuppressWarnings("unchecked") private void deleteSub(String groupId,String currOrgId){ // 机构层级视频是没有重新new ,查询出机构下级ID再删关联表 String sql = " select oa.organization_id from organization as oa,organization ob " + " where " + " ob.ORGANIZATION_ID = ? " + " and " + " oa.org_code like CONCAT(ob.org_code,'%' ) " + " and oa.delete_flag is false and ob.delete_flag is false "+ " order by oa.level,oa.org_code asc " ; List orgIds = this.findBySql(sql, CollectionUtils.newList(currOrgId)); String hql = " from ExerciseReCourse where groupId = :groupId and deleteFlag is false and orgId in (:orgIds)"; Map map = new HashMap(); map.put("groupId", groupId); map.put("orgIds", orgIds.toArray()); List groupCourses = findByComplexHql(hql, map, ExerciseReCourse.class); for (ExerciseReCourse groupCourse : groupCourses) { groupCourse.setDeleteFlag(true); TraceUtils.setUpdateTrace(groupCourse); this.save(groupCourse); } // 班主任层面视频指定过后都是new 出来的,通过originVideoId 可以查出所有指定过去的视频 hql = "select classId from ClsClass where orgId in (:orgIds) and deleteFlag is false"; map = new HashMap(); map.put("orgIds", orgIds.toArray()); List clsIds = findByComplexHql(hql, map, String.class); if(!clsIds.isEmpty()){ hql = " from ExerciseGroup where originExerciseId = :groupId and deleteFlag is false and groupId!=originExerciseId and classId in (:classIds)"; map = new HashMap(); map.put("groupId", groupId); map.put("classIds", clsIds.toArray()); List lstExerciseGroup = findByComplexHql(hql, map, ExerciseGroup.class); for (ExerciseGroup group : lstExerciseGroup) { group.setDeleteFlag(true); TraceUtils.setUpdateTrace(group); this.saveExerciseGroup(group); } } } private Result deleteAppoint(String groupId,String orgIds[],String classIds[]){ Map args = new HashMap(); // 删除需要回撤的机构视频 if (orgIds.length != 0) { String hql = " from ExerciseReCourse where groupId = :groupId and deleteFlag is false and orgId in (:orgIds) and orgId != :currOrgId"; args = new HashMap(); args.put("groupId", groupId); args.put("orgIds", orgIds); args.put("currOrgId", ClientUtils.getOrgId()); List courses = findByComplexHql(hql, args, ExerciseReCourse.class); for (ExerciseReCourse exercise : courses) { TraceUtils.setUpdateTrace(exercise); exercise.setDeleteFlag(true); save(exercise); this.courseWareService.deleteOrgCourseware(exercise.getGroupId(), exercise.getOrgId()); } } // 删除需要回撤的班主任视频 if (classIds.length != 0) { args = new HashMap(); args.put("groupId", groupId); args.put("classIds", classIds); String hql = " from ExerciseGroup where originExerciseId = :groupId and deleteFlag is false and classId in (:classIds)"; List groups = findByComplexHql(hql, args, ExerciseGroup.class); for (ExerciseGroup group : groups) { TraceUtils.setUpdateTrace(group); group.setDeleteFlag(true); this.saveExerciseGroup(group); } } return new Result(true); } /** * 有顺序和章节练习时的删除逻辑 * * @param groupIds * @param types * @return */ private Result deleteExerciseAll(String[] groupIds) { String hql = "select groupId from ExerciseGroup where deleteFlag is false and classId = ? and type in (?,?) "; List exeGroupId = find(hql, CollectionUtils.newList(ClientUtils.getClassId(), ExerciseGroup.TYPE_EXERCISE_RANDOM, ExerciseGroup.TYPE_EXERCISE_SEQUENCE), String.class); // 组 exeGroupId.addAll(Arrays.asList(groupIds)); return deleteExercise((String[]) exeGroupId.toArray(new String[exeGroupId.size()]), groupIds); } /** * 只有順序或者随机时删除逻辑 * * @param groupIds * @param types * @return */ private Result deleteExerciseSequence(String[] groupIds, String[] types) { String hql = "select groupId from ExerciseGroup where deleteFlag is false and classId = ? and type in (?,?) "; List exeGroupId = find(hql, CollectionUtils.newList(ClientUtils.getClassId(), ExerciseGroup.TYPE_EXERCISE_RANDOM, ExerciseGroup.TYPE_EXERCISE_SEQUENCE), String.class); // 1.组 exeGroupId.addAll(Arrays.asList(groupIds)); // 2.删除题,不处理练习 for (int i = 0; i < types.length; i++) { if (types[i] == String.valueOf(ExerciseGroup.TYPE_EXERCISE_RANDOM) || types[i] == String.valueOf(ExerciseGroup.TYPE_EXERCISE_SEQUENCE)) { groupIds[i] = ""; } } return deleteExercise((String[]) exeGroupId.toArray(new String[exeGroupId.size()]), groupIds); } /** * 只有章节练习是的删除逻辑 * * @param groupIds * @param types * @return */ private Result deleteExerciseChapter(String[] groupIds, String[] types) { // 1.组 groupIds // 2.删除题,不处理练习 String[] groupItemIds = new String[groupIds.length]; for (int i = 0; i < types.length; i++) { if (types[i] == String.valueOf(ExerciseGroup.TYPE_CHAPTER_ITEM)) { groupItemIds[i] = ""; } else { groupItemIds[i] = groupIds[i]; } } return deleteExercise(groupIds, groupItemIds); } /** * 后台:执行删除习题组操作 * * @param groupIds * 删除组的组id * @param groupItemIds * 需要删除题的组id * @return */ private Result deleteExercise(String[] groupIds, String[] groupItemIds) { // 1.删除组 bulkUpdateInLoop("update ExerciseGroup set deleteFlag = true where groupId = ? ", groupIds); // 1.删除课件 bulkUpdateInLoop("update SchCourseware set deleteFlag = true where id = ? ", groupIds); // 2.删除题 bulkUpdateInLoop("update ExerciseGroupItemRe set deleteFlag = true " + " where exerciseGroupId = ? and deleteFlag = false ", groupItemIds); return new Result(true); } /** * 发送练习系统通知 * * @param notice * @return * * private Result sendSysMsg(ExerciseGroup group){ * * ONSMsg msg = new ONSMsg(onsProducer.getTopic()); * * msg.put("msgType", "SYS_EXER_SAVE"); msg.put("groupId", group.getGroupId()); msg.put("classId", ClientUtils.getClassId()); * * try { * * onsProducer.sendMsg(msg); * * return new Result(true); * * } catch (Exception e) { log.error("call DocdealMsgSendService fail.userId: " + group.getGroupId(), e); } * * return new Result(false); } */ /** * 添加练习图片 * * @param imgPath * @param imgObjId * @param imgObjType * @return */ public List> doAddExerciseObjImg(String[] imgPath, String imgObjId, int imgObjType) { String hql = "from ExerciseObjectImg where deleteFlag is false and exerciseObjectId=? and objectType=? order by imgOrder desc"; // 查询此练习是否已经存在记录 List lstObjImg = this.find(hql, CollectionUtils.newList(imgObjId, imgObjType), ExerciseObjectImg.class); int imgOrder = 1; if (!lstObjImg.isEmpty()) { imgOrder = lstObjImg.get(0).getImgOrder() + 1; } List lstImg = new ArrayList(imgPath.length); ExerciseObjectImg img = new ExerciseObjectImg(); img.setObjectType(imgObjType); img.setImgPath(imgPath[0]); img.setExerciseObjectId(imgObjId); img.setImgOrder(imgOrder); img.setDeleteFlag(false); TraceUtils.setCreateTrace(img); lstImg.add(img); for (int i = 1; i < imgPath.length; i++) { img.setImgPath(imgPath[i]); img.setImgOrder(imgOrder++); lstImg.add(img); } this.saveOrUpdateAll(lstImg); List> lstResult = new ArrayList>(lstImg.size()); Map resultMap = null; for (ExerciseObjectImg obj : lstImg) { resultMap = new HashMap(2); resultMap.put("imgId", obj.getImgId()); resultMap.put("imgPath", obj.getImgPath()); lstResult.add(resultMap); } return lstResult; } /** * 删除图片 */ public Result dodelExerciseObjImg(String imgId) { ExerciseObjectImg img = this.read(ExerciseObjectImg.class, imgId); img.setDeleteFlag(true); TraceUtils.setUpdateTrace(img); this.save(img); return new Result(true); } /** * 导入习题:深度解析word文档 * * @param groupId * 习题组Id * @param file * @param uuid * @return */ public Result doDeepAnalysisDoc(String groupId,String fullPath){ return insertDeepAnalysis(fullPath,groupId); } /** * 新增深度解析记录 * * @param destPath * 文件路径 * @param groupId * 习题组ID * @return */ private Result insertDeepAnalysis(String destPath, String groupId) { ExerciseDeepAnalysis objDeepAna = new ExerciseDeepAnalysis(); TraceUtils.setCreateTrace(objDeepAna); objDeepAna.setDocPath(destPath); objDeepAna.setUserId(ClientUtils.getUserId()); objDeepAna.setUserAccount(ClientUtils.getUserAccount()); objDeepAna.setOrgId(ClientUtils.getOrgId()); objDeepAna.setOrgName(ClientUtils.getOrgName()); objDeepAna.setClassId(ClientUtils.getClassId()); objDeepAna.setClassName(ClientUtils.getClassName()); String hql = " from OrgCharger o where o.deleteFlag is false and o.userId = ? "; OrgCharger charger = this.findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), OrgCharger.class); objDeepAna.setChargerId(charger.getChargerId()); objDeepAna.setChargerName(charger.getName()); objDeepAna.setStatus(ExerciseDeepAnalysis.STATUS_TODO); objDeepAna.setExerciseGroupId(groupId); objDeepAna.setExerciseGroupName(this.read(ExerciseGroup.class, groupId).getName()); objDeepAna.setSubmitTime(new Date(System.currentTimeMillis())); this.insert(objDeepAna); return new Result(true); } /** * 导入习题,将解析结果返回到前台 * * @param groupId * 习题组ID * @param file * @return */ public ExerciseParseResult doParseItems(String groupId, String fullPath , String module ) { //取得当前上传文件类型 String filePart[] = fullPath.split("\\."); String fileType = filePart[filePart.length -1]; String uuid = UUIDUtils.generateUUID(); String filePath = ExerciseService.class.getClassLoader().getResource("../uploads").getPath().concat("exercise/"+ uuid + "/" + uuid + "."+fileType); File file = fileUploadService.doGetOssFile(fullPath, filePath, module,ClientUtils.getUserId()); ExerciseParseResult objResult = null ; try { objResult = parseWordFile(file); } catch (Exception e) { log.error(e, e); if ("文件格式错误, 请上传word文档(.doc及.docx)格式".equals(e.getMessage())) { return new ExerciseParseResult(false, e.getMessage()); } return new ExerciseParseResult(false, "读取文档失败"); } //更新上传文件使用轨迹 fileUploadService.updateUploadTrace(fullPath, module, SysFileUploadTrace.FILE_USE, groupId); objResult.setItemCount(objResult.getLstItems().size()); objResult.setLstItems(null); objResult.setParseFlag(true); if( null != file ){ fileUploadService.doDeleteTempOssFile(file.getParentFile(), module, ClientUtils.getUserId()); } return objResult; } /** * 解析word * * @param groupId * 习题组id * @param file * word文件绝对路径 * @return * @throws RuntimeException */ private ExerciseParseResult parseWordFile(File file) throws Exception { ExerciseParseResult parseResult = new ExerciseParseResult(); ArrayList lstResult = new ArrayList(); Handler handler = new Handler(); // from office to txt,docx:自带序号无法解析出来,doc可以 String txtFilePath = transformDocToTxt(file); FileReader reader = null; BufferedReader br = null; try { reader = new FileReader(txtFilePath); br = new BufferedReader(reader); String currLine = ""; ExerciseImportResult objResult; while ((currLine = br.readLine()) != null) { ExerciseParse objParser = handler.parse(currLine); int iResultType = objParser.getParseResult(); objResult = new ExerciseImportResult(); objResult.setLineText(objParser.getParseLine()); objResult.setType(iResultType); if (Handler.HANDLER_RESULT_CONTINUE == iResultType) { objResult.setLastParse(objParser.getParseType()); } lstResult.add(objResult); } } catch (Exception e) { throw new Exception("读取文档失败", e); } finally { IOUtils.closeQuietly(br); IOUtils.closeQuietly(reader); } Doc doc = handler.result(); parseResult.setLstItems(doc.convertExerciseItems()); parseResult.setLstResult(lstResult); return parseResult; } /** * 导入习题 校验习题,将解析结果返回到前台 * * @param content * 习题文本内容 * @return */ public ExerciseParseResult validateExercise(String content) { ExerciseParseResult parseResult = parsePlainText(content); parseResult.setLstItems(null); return parseResult; } /** * 导入习题:将传回的文本内容解析出来 * * @param content * 习题文本内容 * @return */ private ExerciseParseResult parsePlainText(String content) { ExerciseParseResult parseResult = new ExerciseParseResult(); Handler handler = new Handler(); ArrayList lstResult = new ArrayList(); List items = null; String[] arrLine = content.split("\n"); ExerciseImportResult objResult; for (String line : arrLine) { ExerciseParse objParser = handler.parse(line); int iResultType = objParser.getParseResult(); objResult = new ExerciseImportResult(); objResult.setLineText(objParser.getParseLine()); objResult.setType(iResultType); if (Handler.HANDLER_RESULT_CONTINUE == iResultType) { objResult.setLastParse(objParser.getParseType()); } lstResult.add(objResult); } Doc doc = handler.result(); items = doc.convertExerciseItems(); parseResult.setLstItems(items); parseResult.setLstResult(lstResult); parseResult.setItemCount(items.size()); parseResult.setParseFlag(true); return parseResult; } /** * 导入习题模块 :导入习题,将解析结果返回到前台 * * @param content * 文本内容 * @param groupId * 习题组ID * @return */ // public ExerciseParseResult doImportExercise(String content, String groupId) { // // ExerciseParseResult parseResult = parsePlainText(content); // // List lstItems = parseResult.getLstItems(); // // if (null == lstItems || lstItems.isEmpty()) { // return parseResult; // } // // insertItems(groupId, lstItems); // // // 修改习题组最后修改时间 // List result = initExerciseGroup(groupId); // updateGroupUpdateTimeByList(result); // // // 减少返回数据 // parseResult.setLstItems(null); // ONSMsg msg = new ONSMsg(onsProducer.getTopic()); // msg.put("msgType", "SYS_EXER_SAVE"); // msg.put("groupId", groupId); // msg.put("classId", ClientUtils.getClassId()); // msg.put("actionType", "new"); // try { // onsProducer.sendMsg(msg); // } catch (Exception e) { // log.error("exercise.sendMsg.groupId: " + groupId, e); // } // return parseResult; // } /** * 拷贝练习题 * * @param newGroupId * @param oldGroupId */ public void doCopyExerciseItem(String newGroupId, String oldGroupId) { //改用存储过程 Session session = getCommonDAO().getSessionFactory().getCurrentSession(); SQLQuery query = session.createSQLQuery("{call copy_exercise_item(?,?)}"); query.setString(0, newGroupId); query.setString(1, oldGroupId); //执行 query.executeUpdate(); } /** * 复制历史练习 * * @param fromClassId * @return */ public Result executeCopyExercise(String groupId, String subjectId, String subjectName, String chapterId) { try { ExerciseGroup source = this.read(ExerciseGroup.class, groupId); doCopyExercise(source, subjectId, subjectName, chapterId); } catch (IllegalAccessException e) { log.error(e, e); return new Result(false); } catch (InvocationTargetException e) { log.error(e, e); return new Result(false); } return new Result(true); } /** * 复制习题 * * @param sourceGroup * @param sequenceGroup * @param randomGroup * @return * @throws IllegalAccessException * @throws InvocationTargetException */ private Result doCopyExercise(ExerciseGroup sourceGroup, String subjectId, String subjectName, String chapterId) throws IllegalAccessException, InvocationTargetException { ExerciseGroup targetGroup = new ExerciseGroup(); // 主表:组 doSaveCopyGroup(sourceGroup, targetGroup, subjectId, subjectName, chapterId); // 关联表: 组 习题 doSaveCopyRe(sourceGroup, targetGroup); // 扩展表: extend doSaveCopyExtend(sourceGroup,targetGroup); return new Result(true); } private Result doSaveCopyExtend(ExerciseGroup sourceGroup, ExerciseGroup targetGroup) throws IllegalAccessException, InvocationTargetException{ String hql = "from ExerciseGroupExtend where deleteFlag is false and groupId = ? "; List lstSourceExtends = this.find(hql, CollectionUtils.newList(sourceGroup.getGroupId()), ExerciseGroupExtend.class); int iCount = this.findCount(hql, CollectionUtils.newList(targetGroup.getGroupId())); if(iCount > 0){ return new Result(true); } List lstTargetExtends = new ArrayList(lstSourceExtends.size()); for (ExerciseGroupExtend et : lstSourceExtends) { ExerciseGroupExtend objExtend = new ExerciseGroupExtend(); BeanUtils.copyProperties(objExtend, et); TraceUtils.setCreateTrace(objExtend); objExtend.setGroupExtendId(null); objExtend.setDoCount(BigInteger.ZERO); objExtend.setClassAccuracy(BigDecimal.ZERO); objExtend.setCorrectCount(BigInteger.ZERO); objExtend.setSubmitNumber(BigInteger.ZERO); objExtend.setGroupId(targetGroup.getGroupId()); lstTargetExtends.add(objExtend); } this.saveOrUpdateAll(lstTargetExtends); return new Result(true); } /** * 复制习题时,保存习题组 * * @param sourceGroup * @param targetGroup * @throws InvocationTargetException * @throws IllegalAccessException */ private Result doSaveCopyGroup(ExerciseGroup sourceGroup, ExerciseGroup targetGroup, String subjectId, String subjectName, String chapterId) throws IllegalAccessException, InvocationTargetException { BeanUtils.copyProperties(targetGroup, sourceGroup); targetGroup.setGroupId(null); targetGroup.setItems(null); targetGroup.setRecords(null); targetGroup.setClassId(ClientUtils.getClassId()); targetGroup.setSubjectId(subjectId); targetGroup.setChapterId(chapterId); targetGroup.setStatus(ExerciseGroup.STATUS_DRAFT); targetGroup.setCollegeCourseId(ClientUtils.getCourseId()); TraceUtils.setCreateTrace(targetGroup); targetGroup.setOrderNum(BigInteger.valueOf(SchCourseware.COURSEWARE_MAX_ORDER)); this.saveExerciseGroup(targetGroup); return new Result(true); } /** * 复制练习时 保存习题关联 * * @param sourceGroup * @param targetGroup * @throws IllegalAccessException * @throws InvocationTargetException */ private Result doSaveCopyRe(ExerciseGroup sourceGroup, ExerciseGroup targetGroup) throws IllegalAccessException, InvocationTargetException { String hql = " from ExerciseGroupItemRe where deleteFlag is false and exerciseGroupId = ? "; List lstSourceGroupRe = this.find(hql, CollectionUtils.newList(sourceGroup.getGroupId()), ExerciseGroupItemRe.class); List lstTargetItemRe = new ArrayList(lstSourceGroupRe.size()); for (ExerciseGroupItemRe it : lstSourceGroupRe) { ExerciseGroupItemRe ojbItemRe = new ExerciseGroupItemRe(); BeanUtils.copyProperties(ojbItemRe, it); ojbItemRe.setRelationId(null); ojbItemRe.setExerciseGroupId(targetGroup.getGroupId()); lstTargetItemRe.add(ojbItemRe); } this.saveOrUpdateAll(lstTargetItemRe); return new Result(true); } /** * 学员得分详情列表 * * @param groupId * @return */ @SuppressWarnings("unchecked") @Override public List> resultList(String groupId) { ExerciseGroup exeGroup = read(ExerciseGroup.class, groupId); String hql_u = " from UserRegistration where deleteFlag is false and classId = ? and status = ? "; List userRegLst = find(hql_u, CollectionUtils.newList(ClientUtils.getClassId(),UserRegistration.STATUS_ACTIVE),UserRegistration.class); Map userMap = new HashMap(); for (UserRegistration u : userRegLst) { userMap.put(u.getUserId(), u); } String hql_re = "select r.accuracy,r.update_Time,r.user_Id from (select * from Exercise_Record " + "where delete_Flag is false and accuracy <= 100 and exercise_Group_Id = ?"; if (exeGroup.getType() == ExerciseGroup.TYPE_HOMEWORK || exeGroup.getType() == ExerciseGroup.TYPE_MOCK_EXAM) { hql_re = hql_re.concat(" and status=" + ExerciseRecord.STATUS_SUBMIT); } hql_re = hql_re.concat(" order by accuracy desc ) r group by r.user_Id "); if (exeGroup.getType() == ExerciseGroup.TYPE_CHAPTER_ITEM || exeGroup.getType() == ExerciseGroup.TYPE_EXERCISE_TOPIC) { hql_re = hql_re.concat( " order by r.accuracy desc,r.status desc"); } else { hql_re = hql_re.concat(" order by r.status desc,r.accuracy desc"); } List reLst = findBySql(hql_re, CollectionUtils.newList(groupId)); Map recordMap = new HashMap(); for (Object[] obj : reLst) { recordMap.put(String.valueOf(obj[2]) , obj); } // 组装为Map List> lstMap = new ArrayList>(userRegLst.size()); Map map = null; int rank = 1; for (Object[] record : reLst) { map = new HashMap(5); UserRegistration re = userMap.get(record[2]); if(null != re){ map.put("accuracy",record[0]); map.put("time", record[1]); map.put("name", re.getUserName()); map.put("mobilePhone", re.getMobilePhone()); map.put("salesCode", re.getSalesCode()); map.put("createTime", re.getUpdateTime()); map.put("rank", rank); rank++; lstMap.add(map); } } for (UserRegistration user : userRegLst) { map = new HashMap(5); Object[] re = recordMap.get(user.getUserId()); if(null == re){ map.put("accuracy",0); map.put("time", null); map.put("name", user.getUserName()); map.put("mobilePhone", user.getMobilePhone()); map.put("salesCode", user.getSalesCode()); map.put("createTime", user.getUpdateTime()); map.put("rank", rank); rank++; lstMap.add(map); } } return lstMap; } /** * 初始化平均成绩和最高成绩 * * @param groupId * @return */ @Override public Map initScore(String groupId) { ExerciseGroup exeGroup = read(ExerciseGroup.class, groupId); String hql_u = " from UserRegistration where deleteFlag is false and classId = ? and status = ? "; List userRegLst = find(hql_u, CollectionUtils.newList(ClientUtils.getClassId(),UserRegistration.STATUS_ACTIVE),UserRegistration.class); String hql_re = "select max(accuracy) as accuracy from ExerciseRecord " + "where deleteFlag is false and accuracy <= 100 and exerciseGroupId = ?"; if (exeGroup.getType() == ExerciseGroup.TYPE_HOMEWORK || exeGroup.getType() == ExerciseGroup.TYPE_MOCK_EXAM) { hql_re = hql_re.concat( " and status=" + ExerciseRecord.STATUS_SUBMIT); } hql_re = hql_re.concat(" GROUP BY userId order by status desc,accuracy desc,updateTime"); List reLst = find(hql_re, CollectionUtils.newList(groupId), BigDecimal.class); Map map = new HashMap(3); map.put("groupName", exeGroup.getName()); if (reLst.isEmpty()) { map.put("avg", 0.00); map.put("max", 0.00); return map; } BigDecimal score = BigDecimal.ZERO; // 计算已做学员总分数 for (BigDecimal obj : reLst) { score = score.add(obj); } // 计算班级平均成绩 Double scoreNew = Double.valueOf(String.valueOf(score)) / userRegLst.size(); DecimalFormat df = new DecimalFormat("0.00"); map.put("avg", df.format(scoreNew)); map.put("max", df.format(reLst.get(0))); return map; } /** * 题目得分详情 * * @param groupId * @return */ @Override public List itemDetailList(String groupId) { String hql_itemStatis = "from ExerciseItemStatistics where deleteFlag is false and groupId = ?"; List itemStatisLst = this.find(hql_itemStatis, CollectionUtils.newList(groupId), ExerciseItemStatistics.class); if (itemStatisLst.isEmpty()) { return new ArrayList(); } // 获取组 ExerciseGroup group = read(ExerciseGroup.class, groupId); if (null == group) { return new ArrayList(); } // 默认章节练习 String hql = "select item from ExerciseItem item,ExerciseGroupItemRe re " + "where re.exerciseGroupId=? " + "and re.exerciseItemId=item.exerciseId " + "and item.deleteFlag is false " + "and re.deleteFlag is false " + "order by re.itemOrder "; // 随机练习,顺序练习 if (ExerciseGroup.TYPE_EXERCISE_RANDOM == group.getType() || ExerciseGroup.TYPE_EXERCISE_SEQUENCE == group.getType()) { hql = "select item from ExerciseItem item,ExerciseGroupItemRe re " + "where re.exerciseGroupId=? and " + "re.exerciseItemId=item.exerciseId " + "and item.deleteFlag is false " + "and re.deleteFlag is false " + "order by item.chapterId, re.itemOrder "; } // 查询当前组的所有题目 List itemAllLst = this.exerDAO.find(hql, CollectionUtils.newList(groupId), ExerciseItem.class); if (itemAllLst.isEmpty()) { return new ArrayList(); } // 同步编号 List exeItemStatisLst = new ArrayList(itemStatisLst.size()); ExerciseItemStatistics obj = null; for (int j = 0; j < itemAllLst.size(); j++) { for (int i = 0; i < itemStatisLst.size(); i++) { obj = itemStatisLst.get(i); if (obj.getExerciseItemId().equals(itemAllLst.get(j).getExerciseId())) { obj.setItemNo(j + 1); obj.setClassAccuracyShow(obj.getClassAccuracy() + "%"); obj.setOrgAccuracyShow(obj.getOrgAccuracy() + "%"); // 给类型赋值 setExerItemTypeNewName(obj); exeItemStatisLst.add(obj); break; } } } return exeItemStatisLst; } private void setExerItemTypeNewName(ExerciseItemStatistics obj) { // 判断类型文字显示 if (obj.getExerciseItemType() == ExerciseItem.TYPE_SINGLE_SELECT) { obj.setItemTypeName("单选题"); } else if (obj.getExerciseItemType() == ExerciseItem.TYPE_MULTI_SELECT) { obj.setItemTypeName("多选题"); } else if (obj.getExerciseItemType() == ExerciseItem.TYPE_TRUE_OR_FALSE) { obj.setItemTypeName("判断题"); } else if (obj.getExerciseItemType() == ExerciseItem.TYPE_ESSAY_QUESTION) { obj.setItemTypeName("问答题"); } } /** * 加载题目选项详情 - 班级、机构 * * @param groupId * @return */ @Override public List> loadOptionsList(String exerciseItemId) { String hql_option = "from ExerciseOptionStatistics where deleteFlag is false and exerciseItemId = ? and classId = ? and orgId = ? group by optionId"; List optionLst = this.find(hql_option, CollectionUtils.newList(exerciseItemId, ClientUtils.getClassId(), ClientUtils.getOrgId()), ExerciseOptionStatistics.class); ExerciseItem item = this.read(ExerciseItem.class, exerciseItemId); List> lstResult = new ArrayList>(optionLst.size()); Map map = null; for (ExerciseOptionStatistics optionStatis : optionLst) { map = new HashMap(12); map.put("content", optionStatis.getContent()); map.put("checked", optionStatis.getChecked()); map.put("classCorrectNum", optionStatis.getClassCorrectNum()); map.put("classTotalNum", optionStatis.getClassTotalNum()); map.put("classAccuracy", optionStatis.getClassAccuracy()); map.put("orgCorrectNum", optionStatis.getOrgCorrectNum()); map.put("orgTotalNum", optionStatis.getOrgTotalNum()); map.put("orgAccuracy", optionStatis.getOrgAccuracy()); map.put("exerciseItemTitel", item.getTitle()); map.put("correctAnswer", item.getAnswer()); if (optionStatis.getOptionOrder().equals("True")) {// 为True - 正确 map.put("optionOrder", "正确"); } else if (optionStatis.getOptionOrder().equals("False")) {// 为False - 错误 map.put("optionOrder", "错误"); } else { map.put("optionOrder", optionStatis.getOptionOrder()); } // 判断题目的类型 if ((short) item.getType() == ExerciseItem.TYPE_SINGLE_SELECT) { map.put("exerciseItemType", "单选题"); } else if ((short) item.getType() == ExerciseItem.TYPE_MULTI_SELECT) { map.put("exerciseItemType", "多选题"); } else if ((short) item.getType() == ExerciseItem.TYPE_TRUE_OR_FALSE) { map.put("exerciseItemType", "判断题"); } else if ((short) item.getType() == ExerciseItem.TYPE_ESSAY_QUESTION) { map.put("exerciseItemType", "问答题"); } lstResult.add(map); } return lstResult; } /** * 编辑练习保存 */ @Override public Result doSaveEditGroup(String groupId,String groupName) { ExerciseGroup group = read(ExerciseGroup.class, groupId); group.setName(groupName); TraceUtils.setUpdateTrace(group); this.bulkUpdate("update ExerciseGroup set name = ? where originExerciseId = ?", new Object[]{groupName, group.getGroupId()}); this.bulkUpdate("update SchCourseware set name = ? where id in(select groupId from ExerciseGroup where originExerciseId = ?)", new Object[]{groupName, group.getGroupId()}); return this.saveExerciseGroup(group); } /** * 排序 * * @param ids 排序id * @param index 序号 * @return */ public Result doOrder(List ids, List index){ // 循环修改order CommonDAO commonDAO = this.getCommonDAO(); for( int i=0;i< ids.size();i++){ String id = ids.get(i); commonDAO.bulkUpdate("update ExerciseGroup set orderNum = " + index.get(i) + " where groupId = ?", new Object[] { id }); commonDAO.bulkUpdate("update SchCourseware set orderNum = " + index.get(i) + " where id = ?", new Object[] { id }); } return new Result(true); } /** * 排序 * * @param ids 排序id * @param index 序号 * @return */ public Result doitemOrder(List ids, List index,String groupId){ // 循环修改order CommonDAO commonDAO = this.getCommonDAO(); for( int i=0;i< ids.size();i++){ String id = ids.get(i); commonDAO.bulkUpdate("update ExerciseGroupItemRe set itemOrder = " + index.get(i) + " where exerciseItemId = ? and exerciseGroupId = ?", new Object[] { id, groupId }); } return new Result(true); } /** * 保存练习接口 * * @param group * @return */ public Result saveExerciseGroup(ExerciseGroup group){ // boolean isClass = StringUtils.isNotEmpty(ClientUtils.getClassId()) || StringUtils.isNotEmpty(group.getClassId()); boolean isClass = false; Result result = new Result(false); TraceUtils.setUpdateTrace(group); Map order = courseWareService.getOrder(!isClass, group.getSubjectId(), group.getChapterId()); //同步排序 int subjectOrder = order.get("subjectOrder"); int chapterOrder = order.get("chapterOrder"); int partOrder = order.get("partOrder"); group.setSubjectOrder(subjectOrder); group.setChapterOrder(chapterOrder); group.setPartOrder(partOrder); result = this.save(group); short type = group.getType(); if(type != ExerciseGroup.TYPE_EXERCISE_RANDOM && type != ExerciseGroup.TYPE_INTERACT && type != ExerciseGroup.TYPE_EXERCISE_TEACH_EVALUATE && type != ExerciseGroup.TYPE_EXERCISE_SEQUENCE && type != ExerciseGroup.TYPE_EXERCISE_FREE){ SchCourseware courseware = null; if(isClass){ courseware = this.findUnique("from SchCourseware where id = ? and classId = ? and deleteFlag is false", CollectionUtils.newList(group.getGroupId(), group.getClassId()), SchCourseware.class); }else{ courseware = this.findUnique("from SchCourseware where id = ? and orgId = ? and classId is null and deleteFlag is false", CollectionUtils.newList(group.getGroupId(), ClientUtils.getOrgId()), SchCourseware.class); this.bulkUpdate("update SchCourseware set name = ?,remark = ? where id = ?", new Object[]{group.getName(),String.valueOf(group.getAllCount()), group.getGroupId()}); } String parentChapterId = null; if(StringUtils.isNotEmpty(group.getChapterId())){ SubjectChapter chapter = this.read(SubjectChapter.class, group.getChapterId()); parentChapterId = chapter == null?null : chapter.getParentChapterId(); } if(courseware == null){ courseware = new SchCourseware(); courseware.setChapterId(group.getChapterId()); courseware.setId(group.getGroupId()); courseware.setCollegeCourseId(group.getCollegeCourseId()); courseware.setcType(group.getType()); courseware.setType(SchCourseware.COURSEWARE_TYPE_EXERCISE); courseware.setName(group.getName()); courseware.setRemark(String.valueOf(group.getAllCount())); courseware.setDeleteFlag(group.getDeleteFlag()); courseware.setOrderNum(group.getOrderNum() == null?SchCourseware.COURSEWARE_MAX_ORDER:group.getOrderNum().intValue()); courseware.setSubjectId(group.getSubjectId()); courseware.setStatus(group.getStatus()); courseware.setOrgId(StringUtils.isEmpty(group.getOrgId())?ClientUtils.getOrgId():group.getOrgId()); courseware.setClassId(group.getClassId()); courseware.setParentChapterId(parentChapterId); courseware.setSubjectOrder(group.getSubjectOrder()); courseware.setChapterOrder(group.getChapterOrder()); courseware.setPartOrder(group.getPartOrder()); TraceUtils.setCreateTrace(courseware); }else{ courseware.setChapterId(group.getChapterId()); //courseware.setCollegeCourseId(group.getCollegeCourseId()); courseware.setcType(group.getType()); courseware.setName(group.getName()); courseware.setRemark(String.valueOf(group.getAllCount())); courseware.setDeleteFlag(group.getDeleteFlag()); courseware.setOrderNum(group.getOrderNum() == null?SchCourseware.COURSEWARE_MAX_ORDER:group.getOrderNum().intValue()); courseware.setSubjectId(group.getSubjectId()); courseware.setStatus(group.getStatus()); courseware.setParentChapterId(parentChapterId); courseware.setSubjectOrder(group.getSubjectOrder()); courseware.setChapterOrder(group.getChapterOrder()); courseware.setPartOrder(group.getPartOrder()); TraceUtils.setUpdateTrace(courseware); } this.save(courseware); } return result; } /** * (后台管理系统) * 管理员同步习题到班级 * * @param exerciseItemId * @return * @throws InvocationTargetException * @throws IllegalAccessException */ public Result doSynExercise(String[] exerciseItemIds) throws IllegalAccessException, InvocationTargetException{ if(exerciseItemIds == null || exerciseItemIds.length == 0){ return new Result(false, "参数错误"); } List lstSaveObject = new ArrayList<>(); for(String exerciseItemId : exerciseItemIds){ //待同步的练习 ExerciseItem sourceItem = this.read(ExerciseItem.class, exerciseItemId); if(sourceItem == null){ continue; } List lstSourceOption = sourceItem.getOptions(); List lstSourceAnalisi = sourceItem.getAnalysises(); List lstSourceImg = this.find("from ExerciseObjectImg where exerciseObjectId = ? and deleteFlag is false and objectType = ?", CollectionUtils.newList(exerciseItemId, ExerciseObjectImg.OBJECT_TYPE_ITEM), ExerciseObjectImg.class); //下发的练习 List lstExerciseItem = this.find("from ExerciseItem where deleteFlag is false and orgiExerciseId = ?", CollectionUtils.newList(exerciseItemId), ExerciseItem.class); if(lstExerciseItem == null || lstExerciseItem.size() == 0){ continue; } //同步题目 for(ExerciseItem exerciseItem :lstExerciseItem){ exerciseItem.setTitle(sourceItem.getTitle()); exerciseItem.setAnswer(sourceItem.getAnswer()); TraceUtils.setUpdateTrace(exerciseItem); //同步更新练习组的时间 this.bulkUpdate("update ExerciseGroup p set p.updateTime = sysdate() where EXISTS "+ " (select 1 from ExerciseGroupItemRe i where i.exerciseItemId = ? and i.deleteFlag is false and i.exerciseGroupId = p.groupId)", new Object[]{exerciseItem.getExerciseId()}); List lstExerciseItemAnalisi = exerciseItem.getAnalysises(); List lstExerciseObjectImg = this.find("from ExerciseObjectImg where exerciseObjectId = ? and deleteFlag is false and objectType = ?", CollectionUtils.newList(exerciseItem.getExerciseId(), ExerciseObjectImg.OBJECT_TYPE_ITEM), ExerciseObjectImg.class); //同步选项 if(lstSourceOption != null && lstSourceOption.size() > 0){ ExerciseItemOption option; //删除选项的题目 this.bulkUpdate("update ExerciseItemOption p set p.deleteFlag = true where exerciseItemId = ?", new Object[]{exerciseItem.getExerciseId()}); for(ExerciseItemOption sourceOption : lstSourceOption){ ExerciseObjectImg objExerciseObjectImg; option = this.findUnique("from ExerciseItemOption where exerciseItemId = ? and optionOrder = ?", CollectionUtils.newList(exerciseItem.getExerciseId(), sourceOption.getOptionOrder()), ExerciseItemOption.class); ExerciseObjectImg objSourceImg = this.findUnique("from ExerciseObjectImg where exerciseObjectId = ? and deleteFlag is false and objectType = ?", CollectionUtils.newList(sourceOption.getOptionId(), ExerciseObjectImg.OBJECT_TYPE_ITEM_OPTION), ExerciseObjectImg.class); if(option == null){ option = new ExerciseItemOption(); BeanUtils.copyProperties(option, sourceOption); option.setExerciseItemId(exerciseItem.getExerciseId()); option.setOptionId(null); TraceUtils.setCreateTrace(option); if(objSourceImg != null){//选项图片 objExerciseObjectImg = new ExerciseObjectImg(); BeanUtils.copyProperties(objExerciseObjectImg, objSourceImg); objExerciseObjectImg.setExerciseObjectId(option.getOptionId()); objExerciseObjectImg.setImgId(null); TraceUtils.setCreateTrace(objExerciseObjectImg); lstSaveObject.add(objExerciseObjectImg); } }else{ option.setContent(sourceOption.getContent()); option.setChecked(sourceOption.getChecked()); option.setDeleteFlag(false); TraceUtils.setUpdateTrace(option); objExerciseObjectImg = this.findUnique("from ExerciseObjectImg where exerciseObjectId = ? and deleteFlag is false and objectType = ?", CollectionUtils.newList(option.getOptionId(), ExerciseObjectImg.OBJECT_TYPE_ITEM_OPTION), ExerciseObjectImg.class); if(objSourceImg != null){ if(objExerciseObjectImg != null){ objExerciseObjectImg.setImgPath(objSourceImg.getImgPath()); TraceUtils.setUpdateTrace(objExerciseObjectImg); }else{ objExerciseObjectImg = new ExerciseObjectImg(); BeanUtils.copyProperties(objExerciseObjectImg, objSourceImg); objExerciseObjectImg.setExerciseObjectId(option.getOptionId()); objExerciseObjectImg.setImgId(null); TraceUtils.setCreateTrace(objExerciseObjectImg); } lstSaveObject.add(objExerciseObjectImg); } } lstSaveObject.add(option); } } //同步解析 if(lstSourceAnalisi != null && lstSourceAnalisi.size() > 0){ ExerciseItemAnalisi objExerciseItemAnalisi; if(lstExerciseItemAnalisi == null || lstExerciseItemAnalisi.size() == 0){ objExerciseItemAnalisi = new ExerciseItemAnalisi(); BeanUtils.copyProperties(objExerciseItemAnalisi, lstSourceAnalisi.get(0)); objExerciseItemAnalisi.setExerciseItemId(exerciseItem.getExerciseId()); objExerciseItemAnalisi.setExerciseAnalisisId(null); TraceUtils.setCreateTrace(objExerciseItemAnalisi); }else{ objExerciseItemAnalisi = lstExerciseItemAnalisi.get(0); TraceUtils.setUpdateTrace(objExerciseItemAnalisi); objExerciseItemAnalisi.setAnalysis(lstSourceAnalisi.get(0).getAnalysis()); } lstSaveObject.add(objExerciseItemAnalisi); } //同步题目图片 if(lstSourceImg != null && lstSourceImg.size() > 0){ ExerciseObjectImg objExerciseObjectImg; if(lstExerciseObjectImg == null || lstExerciseObjectImg.size() == 0){ objExerciseObjectImg = new ExerciseObjectImg(); BeanUtils.copyProperties(objExerciseObjectImg, lstSourceImg.get(0)); objExerciseObjectImg.setExerciseObjectId(exerciseItem.getExerciseId()); objExerciseObjectImg.setImgId(null); TraceUtils.setCreateTrace(objExerciseObjectImg); }else{ objExerciseObjectImg = lstExerciseObjectImg.get(0); objExerciseObjectImg.setImgPath(lstSourceImg.get(0).getImgPath()); TraceUtils.setUpdateTrace(objExerciseObjectImg); } lstSaveObject.add(objExerciseObjectImg); } lstSaveObject.add(exerciseItem); } } this.saveOrUpdateAll(lstSaveObject); return new Result(true); } /** * 数据同步接口,同步下发到班级的数据 * * @param orgId * @param groupId * @return */ public Result doSynExerciseItem(String orgId, String groupId){ List lstGroup = null; if(StringUtils.isNoneBlank(orgId)){ String hql = "select e from ExerciseGroup e ,OrgCollegeCourse o ,ExerciseReCourse c " + " where e.groupId = c.groupId" + " and o.collegeCourseId = c.collegeCourseId " + " and c.orgId=? " + " and o.deleteFlag is false " + " and c.deleteFlag is false " + " and e.deleteFlag is false "; lstGroup = this.find(hql, CollectionUtils.newList(orgId), ExerciseGroup.class); }else if(StringUtils.isNotBlank(groupId)){ lstGroup = this.find("from ExerciseGroup g where g.groupId = ?", CollectionUtils.newList(groupId), ExerciseGroup.class); }else{ return new Result(false, "参数错误"); } if(lstGroup == null || lstGroup.size() == 0){ return new Result(false, "数据为空"); } for(ExerciseGroup group : lstGroup){ String id = group.getGroupId(); List subListGroup = this.find("from ExerciseGroup e where e.originExerciseId = ? and deleteFlag is false and e.groupId <> ?", CollectionUtils.newList(id, id), ExerciseGroup.class); if(subListGroup == null || subListGroup.size() == 0){ continue; } List orgiExerciseItem = group.getItems(); for(ExerciseGroup subGroup : subListGroup){ List subExerciseItem = subGroup.getItems(); for(ExerciseItem item : subExerciseItem){ int index = orgiExerciseItem.indexOf(item); if(index > -1){ item.setOrgiExerciseId(orgiExerciseItem.get(index).getExerciseId()); TraceUtils.setUpdateTrace(item); this.save(item); } } } } return new Result(true, "成功"); } @SuppressWarnings("unchecked") @Override public Result saveExerciseItemBatch(String groupId,List items) { if (items == null || items.size() == 0) { return new Result(false, "没有要保存或更新的题目数据!"); } ExerciseGroup group = this.read(ExerciseGroup.class, groupId); int allCount= group.getAllCount()==null?0:group.getAllCount().intValue(); List lstExerciseItemIds = new ArrayList(); for (ExerciseItem item : items) { if (StringUtils.isEmpty(item.getExerciseId())) { this.insertExerciseItem(groupId, item, item.getOptions(), item.getAnalisis().getAnalysis()); group.setAllCount(BigInteger.valueOf(++allCount)); lstExerciseItemIds.add(item.getExerciseId()); } else { this.updateExerciseItem(item, item.getOptions(), item.getAnalisis()==null?null:item.getAnalisis().getAnalysis()); lstExerciseItemIds.add(item.getExerciseId()); } } this.save(group); redisTemplate.delete(groupId); return new Result(true, "成功",lstExerciseItemIds.toArray()); } /** * 问卷评估 复制练习 * @param groupId * @return */ @Override public String doCopyExerciseByEvaluate(String groupId) { // 1、复制练习组 ExerciseGroup group = this.read(ExerciseGroup.class, groupId); ExerciseGroup newGroup = new ExerciseGroup(); try { BeanUtils.copyProperties(newGroup, group); newGroup.setGroupId(null); newGroup.setRecords(null); } catch (Exception e) { log.error("问卷复制:复制练习BeanUtils.copyProperties()方法copy失败", e); } TraceUtils.setCreateTrace(newGroup); this.save(newGroup); // 2、复制题目 this.doCopyEvaExerciseItem(newGroup.getGroupId(), groupId); return newGroup.getGroupId(); } /** * 拷贝练习题 * * @param newGroupId * @param oldGroupId */ public void doCopyEvaExerciseItem(String newGroupId, String oldGroupId) { //改用存储过程 //执行 this.executeProduce("{call copy_exercise_item(?,?)}", new Object[]{newGroupId, oldGroupId}); } /** * 查询问卷用户练习详情 * @param recordId * @param evaluateId * @return */ @Override public ResultJson queryUserEvaExerciseDetail(String recordId, String evaluateId) { ExerciseRecord objExerciseRecord = this.read(ExerciseRecord.class, recordId); QExerciseItem item = QExerciseItem.exerciseItem; QExerciseGroupItemRe re = QExerciseGroupItemRe.exerciseGroupItemRe; // 查询题目list List itemLst = this.getQueryFactory().select(item).from(item,re) .where(item.exerciseId.eq(re.exerciseItemId) .and(item.deleteFlag.eq(false)) .and(re.deleteFlag.eq(false)) .and(re.exerciseGroupId.eq(objExerciseRecord.getExerciseGroupId()))).fetch(); QExerciseItemAnswerU answerU = QExerciseItemAnswerU.exerciseItemAnswerU; QExerciseObjectImg objImg = QExerciseObjectImg.exerciseObjectImg; QExerciseItemOption option = QExerciseItemOption.exerciseItemOption; SchEvaluate objSchEvaluate = this.read(SchEvaluate.class, evaluateId); List lstExerciseObjectImg = null; for (ExerciseItem objExerciseItem : itemLst) { if(objExerciseItem.getType() == ExerciseItem.TYPE_ATTACHMENT){//附件题读取题目的图片信息 lstExerciseObjectImg = this.getQueryFactory().selectFrom(objImg) .where(objImg.exerciseObjectId.in( this.getQueryFactory().select(option.optionId).from(option) .where(option.exerciseItemId.eq(objExerciseItem.getExerciseId()).and(option.deleteFlag.eq(false)))) .and(objImg.deleteFlag.eq(false)) .and(objImg.createId.eq(objExerciseRecord.getUserId())) ) .fetch(); } //查询用户答题 List lstExerciseItemAnswerU = this.getQueryFactory().selectFrom(answerU) .where(answerU.deleteFlag.eq(false) .and(answerU.exerciseRecordId.eq(objExerciseRecord.getRecordId())) .and(answerU.exerciseItemId.eq(objExerciseItem.getExerciseId()))) .fetch(); objExerciseItem.setExerciseItemAnswerU(lstExerciseItemAnswerU); } //拼装前端所需要的数据 Map resultMap = ExerciseUtils.packageUserExerciseDetail(itemLst, objSchEvaluate, lstExerciseObjectImg); return new ResultJson(true,"success",resultMap); } /** * 删除问卷图片 */ @Override public ResultJson dodelEvaExerciseObjImg(String imgObjId) { ExerciseObjectImg img = this.read(ExerciseObjectImg.class, imgObjId); img.setDeleteFlag(true); TraceUtils.setUpdateTrace(img); this.save(img); return new ResultJson(true,"操作成功"); } /** * 新增问卷图片 */ @Override public List> doAddEvaExerciseObjImg(String[] imgPath, String imgObjId, int imgObjType) { // 查询此练习是否已经存在记录 QExerciseObjectImg objImg = QExerciseObjectImg.exerciseObjectImg; List lstObjImg = this.getQueryFactory() .selectFrom(objImg) .where(objImg.exerciseObjectId.eq(imgObjId) .and(objImg.objectType.eq(imgObjType) .and(objImg.deleteFlag.eq(false)))) .orderBy(objImg.imgOrder.desc()) .fetch(); int imgOrder = 1; if (!lstObjImg.isEmpty()) { imgOrder = lstObjImg.get(0).getImgOrder() + 1; } List lstImg = new ArrayList(imgPath.length); ExerciseObjectImg img = new ExerciseObjectImg(); img.setObjectType(imgObjType); img.setImgPath(imgPath[0]); img.setExerciseObjectId(imgObjId); img.setImgOrder(imgOrder); img.setDeleteFlag(false); TraceUtils.setCreateTrace(img); lstImg.add(img); for (int i = 1; i < imgPath.length; i++) { img.setImgPath(imgPath[i]); img.setImgOrder(imgOrder++); lstImg.add(img); } this.saveOrUpdateAll(lstImg); List> lstResult = new ArrayList>(lstImg.size()); Map resultMap = null; for (ExerciseObjectImg obj : lstImg) { resultMap = new HashMap(2); resultMap.put("imgId", obj.getImgId()); resultMap.put("imgPath", obj.getImgPath()); lstResult.add(resultMap); } return lstResult; } /** * 查询问卷图片 */ @Override public List> queryEvaExerciseObjImg(String imgObjId, int imgObjType) { // 查询此练习是否已经存在记录 QExerciseObjectImg objImg = QExerciseObjectImg.exerciseObjectImg; List lstObjImg = this.getQueryFactory() .selectFrom(objImg) .where(objImg.exerciseObjectId.eq(imgObjId) .and(objImg.objectType.eq(imgObjType) .eq(objImg.deleteFlag.eq(false)))) .orderBy(objImg.imgOrder.asc()) .fetch(); if(lstObjImg.isEmpty()){ return null; } List> lstResult = new ArrayList>(lstObjImg.size()); Map resultMap = null; for(ExerciseObjectImg obj:lstObjImg){ resultMap = new HashMap(2); resultMap.put("imgId", obj.getImgId()); resultMap.put("imgPath", obj.getImgPath()); lstResult.add(resultMap); } return lstResult; } /** * 更新习题选项图片对象结果 * * @param optionId * @param imgIds * @return */ private Result updateEvaExerciseObjImgId(JSONArray titleImgs,String exerciseId) { if (titleImgs == null || titleImgs.isEmpty()) { return new Result(false); } List imgIds = new ArrayList(titleImgs.size()); for(int i=0;i imgs = option.getImgs(); if (imgs == null || imgs.isEmpty()) { return new Result(false); } List imgIds = new ArrayList(imgs.size()); for (int i = 0; i < imgs.size(); i++) { imgIds.add(imgs.get(i).getImgId()); } QExerciseObjectImg objImg = QExerciseObjectImg.exerciseObjectImg; this.getQueryFactory().update(objImg).set(objImg.exerciseObjectId, option.getOptionId()) .where(objImg.imgId.in(imgIds) .and(objImg.deleteFlag.eq(false))).execute(); return new Result(true); } }