派生自 projectDept/qhighschool

EricsHu
2022-12-05 068fc7f2e81178e55fa191a13709af64b1a163f6
src/main/java/com/qxueyou/scc/exercise/service/impl/ExerciseVerService.java
@@ -68,13 +68,13 @@
import com.qxueyou.scc.school.service.IRankService;
/**
 * 练习  实现service  APP V2.0接口
 * 练习  实现service  APP V2.0接口
 * @author zhiyong
 *
 */
@Service
public class ExerciseVerService extends CommonAppService implements IExerciseVerService {
   /** ons生产者 */
   /** ons生产者 */
//   @Autowired
//   CommonONSProducer onsProducer;
@@ -82,19 +82,19 @@
   private static final double  SIMILARITY_PASS_LINE =0.8;
   /** 缓存service */
   /** 缓存service */
   @Autowired
   ICacheService cacheService;
   /** 排名service */
   /** 排名service */
   @Autowired
   IRankService  rankService;
   /** 扩展练习service */
   /** 扩展练习service */
   @Autowired
   private IExerciseExtendService exerciseExtendService;
   /** 扩展练习service */
   /** 扩展练习service */
   @Autowired
   private IExerciseService exerciseService;
@@ -105,23 +105,23 @@
   @Autowired
   IMsgInfoService msgInfoService;
   /** 日志 */
   /** 日志 */
   private static Logger log = LogManager.getLogger("ExerciseVerService");
   /**    ---------------练习成绩统计  start---------------- */
   /**    ---------------练习成绩统计  start---------------- */
   /**
    * 更新统计 - 提交数据调用、单击统计按钮调用
    * @param groupId       习题组Id
    * @param orgId         机构Id
    * @param classId       班级Id
    * @param btnFlag       调用入口(true)
    * 更新统计 - 提交数据调用、单击统计按钮调用
    * @param groupId       习题组Id
    * @param orgId         机构Id
    * @param classId       班级Id
    * @param btnFlag       调用入口(true)
    */
   @SuppressWarnings("unchecked")
   @Override
   public Result updateRefreshStatistical(String groupId, String orgId, String classId,boolean btnFlag) {
      // 结果Map
      // 结果Map
      Map<String, Object> resultMap = packageMapValue(groupId, orgId, classId, btnFlag);
      if(null == resultMap){
@@ -132,13 +132,13 @@
      List<ExerciseOptionStatistics> newOrgOStaLst = new ArrayList<ExerciseOptionStatistics>();
      for (ExerciseItem item : (List<ExerciseItem>) resultMap.get("itemLst")) {
         // 获取当前机构该题目的所有记录
         // 获取当前机构该题目的所有记录
         for (ExerciseItemStatistics orgItemSta : (List<ExerciseItemStatistics>) resultMap.get("orgIStaLst")) {
            if (orgItemSta.getExerciseItemId().equals(item.getExerciseId())) {
               newOrgIStaLst.add(orgItemSta);
            }
         }
         // 获取当前机构该题目选项的所有记录
         // 获取当前机构该题目选项的所有记录
         for (ExerciseOptionStatistics orgOptionSta : (List<ExerciseOptionStatistics>)resultMap.get("orgOStaLst")) {
            if (orgOptionSta.getExerciseItemId().equals(item.getExerciseId())) {
               newOrgOStaLst.add(orgOptionSta);
@@ -154,7 +154,7 @@
   }
   /**
    * 组装数据返回Map值
    * 组装数据返回Map值
    * @param groupId
    * @param orgId
    * @param classId
@@ -163,13 +163,13 @@
    */
   private Map<String, Object> packageMapValue(String groupId,String orgId,String classId,boolean btnFlag){
      // 组装参数 - 练习组Id、机构Id、班级Id
      // 组装参数 - 练习组Id、机构Id、班级Id
      Map<String, String> paramsMap = new HashMap<String, String>();
      paramsMap.put("groupId", groupId);
      paramsMap.put("orgId", orgId);
      paramsMap.put("classIdTo", classId);
      // 组装习题组下所有题目的编号
      // 组装习题组下所有题目的编号
      Map<String, Object> exerciseItemMap = new HashMap<String, Object>();
      List<ExerciseItem> itemLst = packageMapValue1(paramsMap, exerciseItemMap, btnFlag);
@@ -177,19 +177,19 @@
         return null;
      }
      // 组装当前班级的ExerciseItemStatistics数据
      // 组装当前班级的ExerciseItemStatistics数据
      Map<String, ExerciseItemStatistics> itemStatisMap = new HashMap<String, ExerciseItemStatistics>();
      // 组装当前习题组所有题目的所有做题记录
      // 组装当前习题组所有题目的所有做题记录
      Map<String, Object> answerUMap = new HashMap<String, Object>();
      // 组装当前习题组所有题目当前班级的做题记录
      // 组装当前习题组所有题目当前班级的做题记录
      Map<String, Object> classAnswerUMap = new HashMap<String, Object>();
      // 组装所有题目的当前班级统计记录
      // 组装所有题目的当前班级统计记录
      Map<String, Object> optionStatisMap = new HashMap<String, Object>();
      // 组装所有题目的选项
      // 组装所有题目的选项
      Map<String, Object> itemOptionMap = new HashMap<String, Object>();
      // 组装所有题目的所有做题记录
      // 组装所有题目的所有做题记录
      String hql_answerUorg = "from ExerciseItemAnswerU where deleteFlag is false and exerciseItemId in (:exerciseItemIds) order by exerciseItemId";
      List<ExerciseItemAnswerU> answerULstO = this.findByComplexHql(hql_answerUorg, exerciseItemMap, ExerciseItemAnswerU.class);
      if(answerULstO.isEmpty()){
@@ -197,18 +197,18 @@
      }
      ExerciseUtils.packageExerciseItemAnswerStatis(answerULstO, answerUMap);
      // 查询当前题目当前班级的所有做题记录
      // 查询当前题目当前班级的所有做题记录
      String hql_answerUclass = "select u from ExerciseRecord r,ExerciseItemAnswerU u where r.deleteFlag is false "
            + "and u.deleteFlag is false and r.recordId = u.exerciseRecordId and r.exerciseGroupId = ? order by u.exerciseItemId";
      List<ExerciseItemAnswerU> answerULstC = this.find(hql_answerUclass, CollectionUtils.newList(groupId), ExerciseItemAnswerU.class);
      ExerciseUtils.packageExerciseItemAnswerStatis(answerULstC, classAnswerUMap);
      // 组装所有题目的选项
      // 组装所有题目的选项
      String hql_option = "from ExerciseItemOption where deleteFlag is false and exerciseItemId in (:exerciseItemIds) order by exerciseItemId";
      List<ExerciseItemOption> itemOptionLst = this.findByComplexHql(hql_option, exerciseItemMap, ExerciseItemOption.class);
      ExerciseUtils.packageExerciseItemOption(itemOptionLst, itemOptionMap);
      // 当前机构的所有题目统计 —— 题目的全站统计
      // 当前机构的所有题目统计 —— 题目的全站统计
      exerciseItemMap.put("orgId", paramsMap.get("orgId"));
      String hql_orgItemStatis = "from ExerciseItemStatistics where exerciseItemId in (:exerciseItemIds) and orgId=:orgId and deleteFlag is false";
      List<ExerciseItemStatistics> orgItemStatisLst = this.findByComplexHql(hql_orgItemStatis, exerciseItemMap, ExerciseItemStatistics.class);
@@ -222,7 +222,7 @@
         itemStatisMap.put(item.getExerciseItemId(), item);
      }
      // 当前机构的所有题目选项统计 —— 题目选项的全站统计
      // 当前机构的所有题目选项统计 —— 题目选项的全站统计
      String hql_optionStatisO = "from ExerciseOptionStatistics where deleteFlag is false and exerciseItemId in (:exerciseItemIds) and orgId=:orgId";
      List<ExerciseOptionStatistics> orgOptionStatisLst = this.findByComplexHql(hql_optionStatisO, exerciseItemMap, ExerciseOptionStatistics.class);
      List<ExerciseOptionStatistics> claOptionStatisLst = new ArrayList<ExerciseOptionStatistics>(orgOptionStatisLst.size());
@@ -249,7 +249,7 @@
   }
   /**
    * 组装数据返回Map值
    * 组装数据返回Map值
    * @param paramsMap
    * @param exerciseItemMap
    * @param btnFlag
@@ -259,7 +259,7 @@
   private List<ExerciseItem> packageMapValue1(Map<String, String> paramsMap,Map<String, Object> exerciseItemMap,boolean btnFlag){
      String groupId = paramsMap.get("groupId");
      // 组装习题组下所有题目的编号
      // 组装习题组下所有题目的编号
      Object[] itemArgs = null;
      List<ExerciseItem> itemLst = null;
@@ -276,13 +276,13 @@
         String hql = "from ExerciseItem where exerciseId in (:exerciseItemIds) and deleteFlag is false";
         itemLst = findByComplexHql(hql, exerciseItemMap, ExerciseItem.class);
      }else{
         // 判断5分钟内 是否有当前组ID的缓存
         // 判断5分钟内 是否有当前组ID的缓存
         String cache = cacheService.get(Constants.REFRESH_STATIS_GROUPID_CACHE_KEY + groupId , String.class);
         if (cache != null) {
            return null;
         }
         // 将当前组ID放在缓存中
         // 将当前组ID放在缓存中
         cacheService.set(Constants.REFRESH_STATIS_GROUPID_CACHE_KEY + groupId , Constants.EXE_STATIS_UPDATE_MINUTES, groupId);
         String hql = "select g.items from ExerciseGroup g where g.groupId=? and g.deleteFlag is false";
         itemLst = find(hql, CollectionUtils.newList(groupId), ExerciseItem.class);
@@ -302,8 +302,8 @@
   /**
    * 刷新更新统计
    * @param exerciseItem     练习
    * 刷新更新统计
    * @param exerciseItem     练习
    * @param newOrgIStaLst
    * @param newOrgOStaLst
    * @param resultMap
@@ -313,26 +313,26 @@
   public Result updateExerciseStatis(ExerciseItem exerciseItem, List<ExerciseItemStatistics> newOrgIStaLst,
         List<ExerciseOptionStatistics> newOrgOStaLst, Map<String, Object> resultMap) {
      // 所有题目的所有做题记录
      // 所有题目的所有做题记录
      Map<String, Object> answerUMap = (Map<String, Object>) resultMap.get("answerUMap");
      // 当前习题组所有题目当前班级的做题记录
      // 当前习题组所有题目当前班级的做题记录
      Map<String, Object> classAnswerUMap = (Map<String, Object>) resultMap.get("classAnswerUMap");
      // 所有题目的当前班级统计记录
      // 所有题目的当前班级统计记录
      Map<String, Object> optionStatisMap = (Map<String, Object>)resultMap.get("optionStatisMap");
      // 所有题目的选项
      // 所有题目的选项
      Map<String, Object> itemOptionMap = (Map<String, Object>) resultMap.get("itemOptionMap");
      // 当前班级的ExerciseItemStatistics数据
      // 当前班级的ExerciseItemStatistics数据
      Map<String, ExerciseItemStatistics> itemStatisMap = (Map<String, ExerciseItemStatistics>) resultMap.get("itemStatisMap");
      // 组装参数 - 练习组Id、机构Id、班级Id
      // 组装参数 - 练习组Id、机构Id、班级Id
      Map<String, String> paramsMap = (Map<String, String>)resultMap.get("paramsMap");
      // 查询当前题目的所有做题记录
      // 查询当前题目的所有做题记录
      List<ExerciseItemAnswerU> answerULstO = (List<ExerciseItemAnswerU>) answerUMap.get(exerciseItem.getExerciseId());
      if(null == answerULstO){
         return null;
      }
      String orgAnswer = "";// 组装已选的答案 - 机构
      int orgCorrectNum = 0;// 组装正确的次数 - 机构
      String orgAnswer = "";// 组装已选的答案 - 机构
      int orgCorrectNum = 0;// 组装正确的次数 - 机构
      for (ExerciseItemAnswerU item : answerULstO) {
         if (item.getCorrect() == 1) {
            orgCorrectNum++;
@@ -340,13 +340,13 @@
         orgAnswer = orgAnswer.concat(item.getAnswer()).concat(",");
      }
      // 查询当前题目的当前班级做题记录
      // 查询当前题目的当前班级做题记录
      List<ExerciseItemAnswerU> answerULstC = (List<ExerciseItemAnswerU>) classAnswerUMap.get(exerciseItem.getExerciseId());
      if(null == answerULstC){
         return null;
      }
      String classAnswer = "";// 组装已选的答案 - 班级
      int classCorrectNum = 0;// 组装正确的次数 - 班级
      String classAnswer = "";// 组装已选的答案 - 班级
      int classCorrectNum = 0;// 组装正确的次数 - 班级
      for (ExerciseItemAnswerU item : answerULstC) {
         if (item.getCorrect() == 1) {
            classCorrectNum++;
@@ -354,17 +354,17 @@
         classAnswer = classAnswer.concat(item.getAnswer()).concat(",") ;
      }
      // 查询当前班级是否有当前题目的统计记录
      // 查询当前班级是否有当前题目的统计记录
      List<ExerciseOptionStatistics> optionStatisLst = (List<ExerciseOptionStatistics>) optionStatisMap.get(exerciseItem.getExerciseId());
      // 查询当前题目的选项
      // 查询当前题目的选项
      List<ExerciseItemOption> itemOptionLst = (List<ExerciseItemOption>) itemOptionMap.get(exerciseItem.getExerciseId());
      // 更新数据 - 题目
      // 更新数据 - 题目
      updateItemStatistics(itemStatisMap.get(exerciseItem.getExerciseId()), exerciseItem, paramsMap, orgCorrectNum, classCorrectNum, answerULstO.size(), answerULstC.size());
      // 更新数据 - 题目的选项
      // 更新数据 - 题目的选项
      updateOptionStatistics(optionStatisLst, itemOptionLst, newOrgOStaLst, paramsMap, orgAnswer, classAnswer, answerULstO.size(), answerULstC.size());
      // 更新全站数据 - 题目
      // 更新全站数据 - 题目
      for (ExerciseItemStatistics itemStatis : newOrgIStaLst) {
         itemStatis.setOrgCorrectNum(new BigInteger(String.valueOf(orgCorrectNum)));
         itemStatis.setOrgTotalNum(new BigInteger(String.valueOf(answerULstO.size())));
@@ -373,7 +373,7 @@
         save(itemStatis);
      }
      // 更新全站数据 - 题目的选项
      // 更新全站数据 - 题目的选项
      for (ExerciseOptionStatistics optionSta : newOrgOStaLst) {
         optionSta.setOrgTotalNum(new BigInteger(String.valueOf(answerULstO.size())));
         optionSta.setOrgAccuracy(new BigDecimal(optionSta.getOrgCorrectNum().doubleValue() / optionSta.getOrgTotalNum().doubleValue() * 100));
@@ -385,11 +385,11 @@
   }
   /**
    * 新增或修改ExerciseOptionStatistics记录
    * 新增或修改ExerciseOptionStatistics记录
    *
    * @param itemStatis       练习题目
    * @param exerciseItem     练习
    * @param paramsMap        参数map - 练习组Id、机构Id、班级Id
    * @param itemStatis       练习题目
    * @param exerciseItem     练习
    * @param paramsMap        参数map - 练习组Id、机构Id、班级Id
    * @param orgCorrectNum
    * @param classCorrectNum
    * @param answerULstO
@@ -399,14 +399,14 @@
   public Result updateItemStatistics(ExerciseItemStatistics itemStatis, ExerciseItem exerciseItem, Map<String, String> paramsMap,
         int orgCorrectNum, int classCorrectNum, int answerULstO, int answerULstC) {
      Result result = null;
      if (itemStatis != null && StringUtils.isNoneBlank(itemStatis.getItemStatisticsId())) { // 有记录 更新
      if (itemStatis != null && StringUtils.isNoneBlank(itemStatis.getItemStatisticsId())) { // 有记录 更新
         itemStatis.setClassTotalNum(new BigInteger(String.valueOf(answerULstC)));
         itemStatis.setClassCorrectNum(new BigInteger(String.valueOf(classCorrectNum)));
         itemStatis.setClassAccuracy(new BigDecimal(itemStatis.getClassCorrectNum().doubleValue() / itemStatis.getClassTotalNum().doubleValue() * 100));
         TraceUtils.setUpdateTrace(itemStatis);
         save(itemStatis);
      } else {// 否则新增
      } else {// 否则新增
         ExerciseItemStatistics newItemStatis = new ExerciseItemStatistics();
@@ -430,13 +430,13 @@
   }
   /**
    * 新增或修改ExerciseOptionStatistics记录
    * 新增或修改ExerciseOptionStatistics记录
    *
    * @param optionStatisLst     练习题目选项
    * @param itemOptionLst       练习
    * @param optionStatisLst     练习题目选项
    * @param itemOptionLst       练习
    * @param orgOptionStatisLst
    * @param orgOptionStatisLst  提交题目的常见错误答案map
    * @param paramsMap           参数map - 练习组Id、机构Id、班级Id
    * @param orgOptionStatisLst  提交题目的常见错误答案map
    * @param paramsMap           参数map - 练习组Id、机构Id、班级Id
    * @param classAnswer
    * @param orgAnswer
    * @param answerULstO
@@ -447,7 +447,7 @@
         List<ExerciseOptionStatistics> orgOptionStatisLst, Map<String, String> paramsMap,
         String orgAnswer, String classAnswer, int answerULstO, int answerULstC) {
      Result result = null;
      if (null != optionStatisLst) { // 有记录 更新
      if (null != optionStatisLst) { // 有记录 更新
         for (ExerciseOptionStatistics optionSta : optionStatisLst) {
@@ -467,7 +467,7 @@
               }
            }
         }
      } else {// 否则新增
      } else {// 否则新增
         for (ExerciseItemOption itemOption : itemOptionLst) {
            ExerciseOptionStatistics newOptionSta = new ExerciseOptionStatistics();
@@ -500,7 +500,7 @@
   }
   /**
    * 获取某个字符的个数
    * 获取某个字符的个数
    *
    * @return
    */
@@ -515,20 +515,20 @@
   }
   /**
    * 提交题目发送消息 - 保存成绩统计
    * 提交题目发送消息 - 保存成绩统计
    * @param notice
    * @return
    *//*
   private Result sendMsgExerciseStatistics(List<ExerciseItemAnswerU> lstNewAnswerU,String groupId){
      // 4、获取提交当前题目的客户端班级、机构
      // 4、获取提交当前题目的客户端班级、机构
      String classId = ClientUtils.getClassId();
      String orgId = ClientUtils.getOrgId();
      // 2、答案记录放在缓存中
      // 2、答案记录放在缓存中
      cacheService.set(Constants.REFRESH_STATIS_GROUPID_LSTNEWANSWERU_CACHE_KEY + groupId, Constants.EXE_STATIS_UPDATE_MINUTES, lstNewAnswerU);
      // 3、异步调用 发送消息
      // 3、异步调用 发送消息
      ONSMsg msg = new ONSMsg(onsProducer.getTopic());
      msg.put("msgType", "EXER_STATIS_SAVE");
@@ -549,14 +549,14 @@
      return new Result(false);
   }*/
   /**    ---------------练习成绩统计  end---------------- */
   /**    ---------------练习成绩统计  end---------------- */
   /** ------------------------- APP V2.0  start------------------------------------------*/
   /**
    * 重新组装新结果
    * 重新组装新结果
    * @param answerData
    * @return
    */
@@ -566,7 +566,7 @@
         return answerData;
      }
      // 1.组装参数
      // 1.组装参数
      List<ExerciseItemAnswerData> lstAnswers = answerData.getItems();
      Map<String, Object> argsMap = new HashMap<String, Object>(lstAnswers.size());
@@ -576,7 +576,7 @@
      }
      argsMap.put("exerciseIds", args);
      // 2.查询正确答案
      // 2.查询正确答案
      String hql_answerU = "from ExerciseItem where exerciseId in (:exerciseIds) ";
      List<ExerciseItem> lstItem= this.findByComplexHql(hql_answerU, argsMap, ExerciseItem.class);
@@ -587,18 +587,18 @@
      ExerciseItem item = null;
      int correctCount=0;
      // 2.重新组装结果
      // 2.重新组装结果
      for(ExerciseItemAnswerData data:lstAnswers){
         item = itemMap.get(data.getExerciseId());
         if(null == item){
            continue;
         }
         //简答题都需要进行主观评分,用户答案统一标识为错误
         if(checkIsCorrect(item,data.getAnswer())){// 答案正确
         //简答题都需要进行主观评分,用户答案统一标识为错误
         if(checkIsCorrect(item,data.getAnswer())){// 答案正确
            data.setCorrect(String.valueOf(ExerciseItemAnswerU.CORRECT_RIGHT));
            correctCount++;
         }else{// 答案错误
         }else{// 答案错误
            data.setCorrect(String.valueOf(ExerciseItemAnswerU.CORRECT_ERROR));
         }
      }
@@ -652,7 +652,7 @@
            if(tmpCorrectAsw.equals(tmpUsertAsw)){
               ++tempRightFillCount;
            }else{
               //如果不完全相同,则根据hanlp计算相似度
               //如果不完全相同,则根据hanlp计算相似度
               if(this.checkSimilarity(tmpCorrectAsw, tmpUsertAsw)){
                  ++tempRightFillCount;
               }
@@ -665,12 +665,12 @@
   }
   /**
    * 操作用户 练习组排名信息
    * 操作用户 练习组排名信息
    * @param record
    * @return
    */
   public Result doOperExerciseGroupRank(ExerciseRecord record){
      // 查询该用户在排名表中 此组是否有值
      // 查询该用户在排名表中 此组是否有值
      String hql = "from SchRank where rankType=? and userId=? and scopeType=? and scopeId=? ";
      String userId = record.getUserId();
@@ -679,7 +679,7 @@
                  userId,SchRank.SCOPE_TYPE_CLASS_GROUP,
                  record.getExerciseGroupId()), SchRank.class);
      if(null == rank){// 新增记录
      if(null == rank){// 新增记录
         rank = new SchRank();
         rank.setRankType(SchRank.RANK_TYPE_EXERCISE_SCORE);
@@ -689,20 +689,20 @@
         rank.setUserId(userId);
         rank.setDeleteFlag(false);
         TraceUtils.setCreateTrace(rank);
      }else{// 更新记录
      }else{// 更新记录
         rank.setValue(record.getAccuracy());
         TraceUtils.setUpdateTrace(rank);
      }
      // 保存结果
      // 保存结果
      this.save(rank);
      return new Result(true);
   }
   /**
    * 操作最近一次记录
    * 操作最近一次记录
    * @param record
    * @return
    */
@@ -714,10 +714,10 @@
            CollectionUtils.newList(record.getExerciseGroupId(), record.getUserId()), ExerciseRecentRecord.class);
      String recentRecordId = null;
      if(null == rRecord){//新增记录
      if(null == rRecord){//新增记录
         recentRecordId = insertExerciseRecentRecord(record);
      }else{// 更新记录
      }else{// 更新记录
         updateExerciseRecentRecord(rRecord, record.getRecordId());
@@ -728,7 +728,7 @@
   }
   /**
    * 新增记录 最近一次做题记录
    * 新增记录 最近一次做题记录
    * @param record
    * @return
    */
@@ -752,7 +752,7 @@
   }
   /**
    * 更新记录 最近一次做题记录
    * 更新记录 最近一次做题记录
    * @param record
    * @return
    */
@@ -767,7 +767,7 @@
   }
   /**
    * 新增练习记录
    * 新增练习记录
    * @param groupId
    * @return
    * @throws ParseException
@@ -786,7 +786,7 @@
   }
   /**
    * 新增练习记录
    * 新增练习记录
    * @param groupId
    * @return
    */
@@ -805,7 +805,7 @@
   }
   /**
    * 更新练习记录
    * 更新练习记录
    * @param groupId
    * @return
    */
@@ -814,18 +814,18 @@
         record.setTitleMaxNumber(answerData.getCurrTitleNum());
      }
      //如果是考试
      //如果是考试
      if(String.valueOf(ExerciseGroup.TYPE_EXERCISE_EXAM_ITEM).equals(answerData.getType())){
         if(answerData.getScore()!=null){
            record.setScore(answerData.getScore());
         }else{
            //判断是否是随机考试,如果是随机考试,则按照配置来计算得分
            //判断是否是随机考试,如果是随机考试,则按照配置来计算得分
            ExamInfo examInfo =  null;
            List<ExerciseItemSet> lstItemSets = null;
            if(StringUtils.isNotEmpty(record.getExamBatchId())&& StringUtils.isNotEmpty(record.getClassId())){
               examInfo =  this.read(ExamBatchInfo.class,record.getExamBatchId()).getExamInfo();
            }else {
               //TODO 这里是因为补考考试的时候添加的记录的批次ID改成了考试ID,并且没有添加ClassID
               //TODO 这里是因为补考考试的时候添加的记录的批次ID改成了考试ID,并且没有添加ClassID
               examInfo =  this.read(ExamInfo.class,record.getExamBatchId());
            }
@@ -838,11 +838,11 @@
            }
         }
      }else{
         //如果是作业
         //如果是作业
         record.setScore(answerData.getScore());
      }
      //设置状态,如果没有主观题,并是提交状态,则直接设置状态为已批阅
      //设置状态,如果没有主观题,并是提交状态,则直接设置状态为已批阅
      if(record.getSubItemCount()==0 && answerData.getStatus().equals(String.valueOf(ExerciseRecord.STATUS_SUBMIT))){
         record.setStatus(ExerciseRecord.STATUS_CHECK);
      }else{
@@ -851,12 +851,12 @@
      record.setRemainingSeconds(answerData.getRemainingSeconds());
      //设置提交时间
      //设置提交时间
      if(answerData.getStatus().equals(String.valueOf(ExerciseRecord.STATUS_SUBMIT))){
         record.setSubmitTime(new Date());
      }
      //保存客观题分数和主观题分数
      //保存客观题分数和主观题分数
      if(answerData.getStatus().equals(String.valueOf(ExerciseRecord.STATUS_CHECK))){
         record.setSubScore(record.getScore().subtract(record.getObjScore()));
      }else{
@@ -869,7 +869,7 @@
   }
   //后台计算考试得分
   //后台计算考试得分
   private  BigDecimal  calculateScore(String groupId,List<ExerciseItemAnswerData> items){
      BigDecimal resultScore = BigDecimal.ZERO;
@@ -877,13 +877,13 @@
         return BigDecimal.ZERO;
      }
      //查询题目分数信息
      //查询题目分数信息
      List<Object[]> lstObj =  this.find("select c.exerciseItemId,c.score,i.answer from ExerciseItemScore c,ExerciseItem i where c.exerciseItemId = i.exerciseId and c.groupId=? and c.deleteFlag is false",  CollectionUtils.newList(groupId), Object[].class);
      if(lstObj==null || lstObj.isEmpty()){
         return BigDecimal.ZERO;
      }
      //组装题目分数MAP
      //组装题目分数MAP
      Map<String,Object[]> exerciseScoreMap = new HashMap<String,Object[]>(lstObj.size());
      for(Object[] arrObj : lstObj){
         exerciseScoreMap.put((String)arrObj[0],arrObj);
@@ -892,7 +892,7 @@
      BigDecimal tempScore = null,itemScore = null;
      String itemAnswer = "";
      for(ExerciseItemAnswerData data : items){
         //如果正确并且存在分数信息,则处理
         //如果正确并且存在分数信息,则处理
         if(exerciseScoreMap.containsKey(data.getExerciseId())){
            itemScore = new BigDecimal((String)exerciseScoreMap.get(data.getExerciseId())[1]);
            itemAnswer = (String)exerciseScoreMap.get(data.getExerciseId())[2];
@@ -900,16 +900,16 @@
            itemScore =BigDecimal.ZERO;
         }
         if(data.getType()==ExerciseItem.TYPE_ESSAY_QUESTION){   //问答题计算分数
         if(data.getType()==ExerciseItem.TYPE_ESSAY_QUESTION){   //问答题计算分数
            if(StringUtils.isNotEmpty(data.getTeacherScore())){
               tempScore = new BigDecimal(data.getTeacherScore());
            }else{
               tempScore = BigDecimal.ZERO;
            }
            tempScore = tempScore.compareTo(itemScore)>0?itemScore:tempScore;
         }else if(data.getType()==ExerciseItem.TYPE_FILL_BLANKS){ //填空题计算分数
         }else if(data.getType()==ExerciseItem.TYPE_FILL_BLANKS){ //填空题计算分数
            tempScore  = this.calFillBlanksItemScore(itemAnswer, data.getAnswer(), itemScore.floatValue());
            data.setTeacherScore(tempScore.toPlainString()); //设置填空题分数
            data.setTeacherScore(tempScore.toPlainString()); //设置填空题分数
         }else{
            tempScore = Integer.valueOf(data.getCorrect())>0?itemScore:BigDecimal.ZERO;
         }
@@ -920,13 +920,13 @@
   }
   /**
    * 根据随机选题配置计算题目得分
    * 根据随机选题配置计算题目得分
    * @param lstItemSet
    * @param items
    * @return
    */
   private BigDecimal calculateScore(String groupId,List<ExerciseItemSet> lstItemSet,List<ExerciseItemAnswerData> items) {
      //获取填空题答案信息
      //获取填空题答案信息
      Map<String,String> exerciseFillItemMap= null;
      List<Object[]> lstObj =  this.find("select i.exerciseId,i.answer from ExerciseGroupItemRe r, ExerciseItem i where r.exerciseItemId=i.exerciseId and  r.exerciseGroupId=? and r.deleteFlag is false and i.type=? and i.deleteFlag is false",
               CollectionUtils.newList(groupId,ExerciseItem.TYPE_FILL_BLANKS), Object[].class);
@@ -1019,7 +1019,7 @@
      String[] arrUserAnswer = null;
      String[] arrItemAnswer = null;
      //填空题计算分数
      //填空题计算分数
      tempRightFillCount =0;
      if(StringUtils.isNotEmpty(itemAnswer) && StringUtils.isNotEmpty(useranswer)){
         arrUserAnswer = useranswer.split(FILL_BLANKS_ANSWER_SPLIT_STR);
@@ -1040,7 +1040,7 @@
            if(tmpCorrectAsw.equals(tmpUsertAsw)){
               ++tempRightFillCount;
            }else{
               //如果不完全相同,则根据hanlp计算相似度
               //如果不完全相同,则根据hanlp计算相似度
               if(this.checkSimilarity(tmpCorrectAsw, tmpUsertAsw)){
                  ++tempRightFillCount;
               }
@@ -1064,7 +1064,7 @@
//      System.out.println(correctLst);
//      System.out.println(userLst);
      //根据正确的list进行参照,如果user中含有正确的词汇+1
      //根据正确的list进行参照,如果user中含有正确的词汇+1
      for(String t :correctLst){
         if(userLst.contains(t)){
            correctWord++;
@@ -1080,39 +1080,39 @@
   }
   /**
    * 提交用户本次做题数据结果 以及分析结果
    * 提交用户本次做题数据结果 以及分析结果
    * @return
    */
   public Result doSubmitExerciseAnswerDataNew(ExerciseSubmitAnswerData answerData, String exerciseRecordId) {
      // 1.组装参数
      // 1.组装参数
      String exerciseGroupId = answerData.getExerciseGroupId();
      List<ExerciseItemAnswerData> lstAnswers = answerData.getItems();
      //TODO 添加用户做题答案时,判断提交的做题记录是否为空
      //TODO 添加用户做题答案时,判断提交的做题记录是否为空
      if (lstAnswers!=null&& !lstAnswers.isEmpty()) {
         Object[] args = new Object[lstAnswers.size()];
         for(int i=0; i<lstAnswers.size(); i++){
            args[i] = lstAnswers.get(i).getExerciseId();
         }
         // 1.记录练习答案  ExerciseItemAnswerU
         // 1.记录练习答案  ExerciseItemAnswerU
         this.doOperExerciseItemAnswerUNew(lstAnswers, exerciseRecordId,exerciseGroupId, CollectionUtils.newObjectMap("exerciseIds",args));
      }
      // 2.重新计算做题记录正确个数 做题个数  正确率
      // 2.重新计算做题记录正确个数 做题个数  正确率
      Result result = this.doCalcExericseRecordStatisData(exerciseGroupId, exerciseRecordId, answerData);
      // 3.计算组已经提交人数
      // 3.计算组已经提交人数
      this.doCalcExericseGroupSubmitNumber(exerciseGroupId);
      // 4、计算班级正确率
      // 4、计算班级正确率
      this.doUpdateExerGroupClsAccuracy(exerciseGroupId, answerData.getDoCount(), answerData.getCorrectCount());
      return result;
   }
   /**
    * 计算组已经提交人数
    * 计算组已经提交人数
    * @param exerciseGroupId
    * @return
    */
@@ -1140,22 +1140,22 @@
   }
   /**
    * 发送个人统计 全站统计消息
    * 发送个人统计 全站统计消息
    * @param lstAnswers
    * @return
    */
   @Override
   public Result sendUpdateExerItemStatisticsMsg(String exerciseGroupId, ExerciseSubmitAnswerData answerData){
      // 1、 获取当前时间
      // 1、 获取当前时间
      DateUtils objDateUtils = new DateUtils();
      String currTime = objDateUtils.getDateFormat(objDateUtils.getCurrDateTime(),"yyyyMMddHHmmss");
      // 2、答案记录放在缓存中   默认放入10分钟
      // 2、答案记录放在缓存中   默认放入10分钟
      cacheService.set(Constants.EXER_ITEM_STATISTICAL_CACHE_KEY
            + ClientUtils.getUserId() + exerciseGroupId +  currTime, 600, answerData);
      // 异步调用 发送消息
      // 异步调用 发送消息
//      ONSMsg msg = new ONSMsg(onsProducer.getTopic());
//
//      msg.put("msgType", "USER_EXER_ITEM_STATIS");
@@ -1177,7 +1177,7 @@
   }
   /**
    * 重新计算做题记录正确个数 做题个数  正确率
    * 重新计算做题记录正确个数 做题个数  正确率
    * @param exerciseGroupId
    * @param exerciseRecordId
    * @return
@@ -1186,7 +1186,7 @@
   public Result doCalcExericseRecordStatisData(String exerciseGroupId, String exerciseRecordId
         , ExerciseSubmitAnswerData answerData){
      // 1.计算做题个数   做题正确个数
      // 1.计算做题个数   做题正确个数
      String sql_answerU = "select count(1) doCount, sum(CORRECT=1) correctCount"
            + " from exercise_item_answer_u where DELETE_FLAG=0 and EXERCISE_RECORD_ID=? ";
      List<Object[]> lstAnswerU = this.findBySql(sql_answerU, CollectionUtils.newList(exerciseRecordId));
@@ -1194,7 +1194,7 @@
      String doCount = String.valueOf(lstAnswerU.get(0)[0]);
      String correctCount = String.valueOf(lstAnswerU.get(0)[1] == null ? 0 : lstAnswerU.get(0)[1]);
      // 3.查询总题目数
      // 3.查询总题目数
      ExerciseGroup group = this.read(ExerciseGroup.class, exerciseGroupId);
      BigInteger allCount = group.getAllCount();
@@ -1202,13 +1202,13 @@
         allCount = BigInteger.valueOf(this.findCount("from ExerciseGroupItemRe  where exerciseGroupId=? and deleteFlag is false", CollectionUtils.newList(exerciseGroupId)));;
      }
      // 4.查询做题记录obj
      // 4.查询做题记录obj
      ExerciseRecord record = this.read(ExerciseRecord.class, exerciseRecordId);
      BigDecimal accuracy = ExerciseUtils.parseStrToBigDecimal(correctCount, String.valueOf(allCount));
      BigDecimal completionRate =  ExerciseUtils.parseStrToBigDecimal(doCount,  String.valueOf(allCount));
      // 更新最新值
      // 更新最新值
      record.setAccuracy(accuracy);
      record.setCompletionRate(completionRate);
      record.setStatus(answerData.getStatus());
@@ -1218,14 +1218,14 @@
      this.save(record);
      // 5.操作练习组此次排名情况
      // 5.操作练习组此次排名情况
//      doOperExerciseGroupRank(record);
      return new Result(true);
   }
   /**
    * 计算考试分数
    * 计算考试分数
    *
    * @param exerciseGroupId
    * @param exerciseRecordId
@@ -1242,7 +1242,7 @@
         return BigDecimal.ZERO;
      }
      // 1.计算做题个数   做题正确个数
      // 1.计算做题个数   做题正确个数
      String sql_answerU = "SELECT COUNT(1), SUM(u.CORRECT = 1), SUM(u.CORRECT = 0),"
            + "i.TYPE FROM exercise_item_answer_u u, exercise_item i "
            + "WHERE u.EXERCISE_RECORD_ID = ? AND i.EXERCISE_ID = u.EXERCISE_ITEM_ID GROUP BY i.type";
@@ -1271,7 +1271,7 @@
   }
   /**
    * 操作练习答案结果
    * 操作练习答案结果
    * @param answer
    * @param userId
    * @param exerciseRecordId
@@ -1279,7 +1279,7 @@
    */
   public Result doOperExerciseItemAnswerUNew(List<ExerciseItemAnswerData> lstAnswers,
         String exerciseRecordId, String exerciseGroupId, Map<String, Object> argsMap) {
      // 记录练习答案  ExerciseItemAnswerU
      // 记录练习答案  ExerciseItemAnswerU
      String hql_answerU = "from ExerciseItemAnswerU where exerciseItemId in (:exerciseIds) and "
            + " exerciseRecordId=:exerciseRecordId and  deleteFlag is false ";
      argsMap.put("exerciseRecordId",exerciseRecordId);
@@ -1294,17 +1294,17 @@
      List<ExerciseItemAnswerU> lstNewAnswerU = new ArrayList<ExerciseItemAnswerU>(lstAnswers.size());
      ExerciseItemAnswerU answerU = null;
      byte currCorrect;
      // 批量操作
      // 批量操作
      for(ExerciseItemAnswerData answer:lstAnswers){
         answerU=answerUMap.get(answer.getExerciseId());
         // 1.组装批量练习答案
         // 1.组装批量练习答案
         if(answerU == null){
            //为空 新增一个
//            if(StringUtils.isBlank(answer.getAnswer())){//答案为空 跳过
            //为空 新增一个
//            if(StringUtils.isBlank(answer.getAnswer())){//答案为空 跳过
//               continue;
//            }
            // 组装答案记录
            // 组装答案记录
            answerU = new ExerciseItemAnswerU();
            answerU.setExerciseItemId(answer.getExerciseId());
            answerU.setExerciseRecordId(exerciseRecordId);
@@ -1315,23 +1315,23 @@
            answerU.setTeacherScore(answer.getTeacherScore());
            answerU.setUpdateStatus(ExerciseItemAnswerU.STATUS_ADD);
            TraceUtils.setCreateTrace(answerU);
         }else{//更新
            // 本次修改结果
         }else{//更新
            // 本次修改结果
            currCorrect = Byte.valueOf(answer.getCorrect());
            if(answerU.getCorrect() == ExerciseItemAnswerU.CORRECT_ERROR &&
                  currCorrect == ExerciseItemAnswerU.CORRECT_RIGHT){//上次错误本次修改为正确 统计正确结果 +1
                  currCorrect == ExerciseItemAnswerU.CORRECT_RIGHT){//上次错误本次修改为正确 统计正确结果 +1
               answerU.setUpdateStatus(ExerciseItemAnswerU.STATUS_UPDATE_CORRECT);
            }else if(answerU.getCorrect() == ExerciseItemAnswerU.CORRECT_RIGHT &&
                  currCorrect == ExerciseItemAnswerU.CORRECT_ERROR){// 上次正确本次修改为错误 统计正确结果 -1
                  currCorrect == ExerciseItemAnswerU.CORRECT_ERROR){// 上次正确本次修改为错误 统计正确结果 -1
               answerU.setUpdateStatus(ExerciseItemAnswerU.STATUS_UPDATE_ERROR);
            }
            answerU.setLastAnswer(answerU.getAnswer());// 存储上一次答案
            answerU.setLastAnswer(answerU.getAnswer());// 存储上一次答案
            answerU.setAnswer(answer.getAnswer());
            answerU.setCorrect(currCorrect);
            answerU.setTeacherScore(answer.getTeacherScore());
            if(StringUtils.isBlank(answer.getAnswer())){// 取消答案 删除
            if(StringUtils.isBlank(answer.getAnswer())){// 取消答案 删除
               answerU.setDeleteFlag(true);
            }
@@ -1341,11 +1341,11 @@
         lstNewAnswerU.add(answerU);
      }
      //批量保存
      //批量保存
      this.saveOrUpdateAll(lstNewAnswerU);
//      this.flush();
      // -----------------开始答题结果统计-------------------
      // -----------------开始答题结果统计-------------------
//      sendMsgExerciseStatistics(lstNewAnswerU, exerciseGroupId);
      return new Result(true);
@@ -1354,17 +1354,17 @@
   /**
    *
    * 统计用户做题结果数据
    * 统计用户做题结果数据
    * @return
    */
   @Override
   public Result doStatisUserExerciseItemData(String userId, String userName, ExerciseSubmitAnswerData answerData) {
      // 数据统计
      // 数据统计
      List<ExerciseItemAnswerData> lstAnswers = answerData.getItems();
      if(lstAnswers.isEmpty()){
         return new Result(false,"数据为空");
         return new Result(false,"数据为空");
      }
      ExerciseItemAnalisi analisis = null;
@@ -1379,11 +1379,11 @@
         number = 0;
         exerciseItemId = answer.getExerciseId();
         if(ExerciseItemAnswerU.CORRECT_RIGHT_STR.equals(answer.getCorrect())){// 答案正确
         if(ExerciseItemAnswerU.CORRECT_RIGHT_STR.equals(answer.getCorrect())){// 答案正确
            number = 1;
         }
         // 1、全站统计
         // 1、全站统计
         hql_analisis = "update ExerciseItemAnalisi"
               + " set submitNumber=IFNULL(submitNumber,0)+1"
               + ",submitCorrectNumber=IFNULL(submitCorrectNumber,0)+"+number
@@ -1394,7 +1394,7 @@
         result = this.bulkUpdate(hql_analisis, new String[]{exerciseItemId});
         if(Integer.parseInt(String.valueOf(result.getData("doCount"))) < 1){// 为空 新增记录
         if(Integer.parseInt(String.valueOf(result.getData("doCount"))) < 1){// 为空 新增记录
            analisis = new ExerciseItemAnalisi();
            analisis.setDeleteFlag(false);
            analisis.setExerciseItemId(exerciseItemId);
@@ -1412,7 +1412,7 @@
            this.save(analisis);
         }
         // 2、个人统计
         // 2、个人统计
         hql_analisisU = "update ExerciseItemAnalisiU"
               + " set submitNumber=IFNULL(submitNumber,0)+1"
               + ",submitCorrectNumber=IFNULL(submitCorrectNumber,0)+"+number
@@ -1425,7 +1425,7 @@
         result = this.bulkUpdate(hql_analisisU, new String[]{exerciseItemId});
         if(Integer.parseInt(String.valueOf(result.getData("doCount"))) < 1){// 为空 新增记录
         if(Integer.parseInt(String.valueOf(result.getData("doCount"))) < 1){// 为空 新增记录
            analisisU = new ExerciseItemAnalisiU();
            analisisU.setDeleteFlag(false);
            analisisU.setExerciseItemId(exerciseItemId);
@@ -1450,29 +1450,29 @@
   /**
    * 查询每道题 做题个数,正确个数
    * 查询每道题 做题个数,正确个数
    * @return
    */
   private Map<String,ExerciseItemStatis> getExerciseItemAnalisisResultDataList(Map<String, Object> argsMap){
      String sql = "select tmp.EXERCISE_ITEM_ID,sum(allCount),sum(correctCount) from ("
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_item_answer_u t"// 1.(公共答案表)查询每道题 做题个数,正确个数
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_item_answer_u t"// 1.(公共答案表)查询每道题 做题个数,正确个数
               + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.DELETE_FLAG=0"
               + "       group by t.EXERCISE_ITEM_ID "
               + "    union all "
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault t"   // 2.错题本
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault t"   // 2.错题本
               + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.answer is not null and t.DELETE_FLAG=0"
               + "       group by t.EXERCISE_ITEM_ID "
               + "    union all "
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault_his t"// 3.错题本历史
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault_his t"// 3.错题本历史
               + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.answer is not null and t.DELETE_FLAG=0"
               + "       group by t.EXERCISE_ITEM_ID "
               + "    union all "
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite t"// 4.收藏本
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite t"// 4.收藏本
               + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.answer is not null and t.DELETE_FLAG=0"
               + "       group by t.EXERCISE_ITEM_ID "
               + "    union all "
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite_his t"// 5.收藏本历史
               + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite_his t"// 5.收藏本历史
               + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.answer is not null and t.DELETE_FLAG=0"
               + "       group by t.EXERCISE_ITEM_ID "
               + ") tmp group by tmp.EXERCISE_ITEM_ID ";
@@ -1488,17 +1488,17 @@
      for(Object[] obj:lstResult){
         statis = new ExerciseItemStatis();
         statis.setExerciseId(String.valueOf(obj[0]));
         statis.setAllCount(Integer.parseInt(String.valueOf(obj[1])));// 总个数
         statis.setCorrectCount(Integer.parseInt(String.valueOf(obj[2])));// 正确个数
         statis.setAllCount(Integer.parseInt(String.valueOf(obj[1])));// 总个数
         statis.setCorrectCount(Integer.parseInt(String.valueOf(obj[2])));// 正确个数
         resultMap.put(String.valueOf(obj[0]), statis);// 练习id
         resultMap.put(String.valueOf(obj[0]), statis);// 练习id
      }
      return resultMap;
   }
   /**
    * 练习题目的全站统计
    * 练习题目的全站统计
    * @param answer
    * @return
    */
@@ -1506,17 +1506,17 @@
      Object[] exerIds = (Object[]) argsMap.get("exerciseIds");
      if(exerIds.length<1){
         return new Result(false,"数据为空");
         return new Result(false,"数据为空");
      }
      // 1.查询每道题 做题个数,正确个数
      // 1.查询每道题 做题个数,正确个数
      Map<String,ExerciseItemStatis> analisResultMap = getExerciseItemAnalisisResultDataList(argsMap);
      if(analisResultMap.isEmpty()){
         return new Result(false,"查询全站统计数据为空,异常");
         return new Result(false,"查询全站统计数据为空,异常");
      }
      // 2.题目的全站统计  ExerciseItemAnalisi
      // 2.题目的全站统计  ExerciseItemAnalisi
      String hql_analisis = "from ExerciseItemAnalisi where deleteFlag is false and exerciseItemId in (:exerciseIds) ";
      List<ExerciseItemAnalisi> lstAnalisis = this.findByComplexHql(hql_analisis, argsMap, ExerciseItemAnalisi.class);
@@ -1530,13 +1530,13 @@
      String exerciseItemId = null;
      ExerciseItemStatis statis = null;
      // 批量操作
      // 批量操作
      for(Object obj:exerIds){
         exerciseItemId = String.valueOf(obj);
         // 1.组装批量练习答案
         if(analisisMap.get(exerciseItemId) == null){//为空 新增一个
            // 组装答案记录
         // 1.组装批量练习答案
         if(analisisMap.get(exerciseItemId) == null){//为空 新增一个
            // 组装答案记录
            analisis = new ExerciseItemAnalisi();
            analisis.setDeleteFlag(false);
            analisis.setExerciseItemId(exerciseItemId);
@@ -1553,7 +1553,7 @@
         analisis.setUpdateTime(DateUtils.getCurrTime());
         analisis.setUpdator(userName);
         // 更新统计数据
         // 更新统计数据
         statis = analisResultMap.get(exerciseItemId);
         if(null != statis){
            analisis.setSubmitNumber(new BigInteger(String.valueOf(statis.getAllCount())));
@@ -1569,14 +1569,14 @@
         lstNewAnalisis.add(analisis);
      }
      //批量保存
      //批量保存
      this.saveOrUpdateAll(lstNewAnalisis);
      return new Result(true);
   }
   /**
    * 练习题目的个人统计
    * 练习题目的个人统计
    * @param answer
    * @return
    */
@@ -1585,17 +1585,17 @@
      Object[] exerIds =   (Object[]) argsMap.get("exerciseIds");
      if(exerIds.length<1){
         return new Result(false,"数据为空");
         return new Result(false,"数据为空");
      }
      // 1. 查询个人 每道题 做题个数,正确个数
      // 1. 查询个人 每道题 做题个数,正确个数
      Map<String,ExerciseItemStatis> analisUResultMap = getExerciseItemAnalisisUResultDataList(userId, argsMap);
      if(analisUResultMap.isEmpty()){
         return new Result(false,"查询全站统计数据为空,异常");
         return new Result(false,"查询全站统计数据为空,异常");
      }
      // 2.题目的个人统计  ExerciseItemAnalisiU
      // 2.题目的个人统计  ExerciseItemAnalisiU
      String hql_analisisU = "from ExerciseItemAnalisiU where deleteFlag is false "
            + " and exerciseItemId in (:exerciseIds) and userId=:userId ";
      argsAnalisiMap.put("userId", userId);
@@ -1610,14 +1610,14 @@
      ExerciseItemStatis statis = null;
      String exerciseItemId = null;
      // 批量操作
      // 批量操作
      for(Object obj:exerIds){
         exerciseItemId = String.valueOf(obj);
         // 1.组装批量练习答案
         if(analisisUMap.get(exerciseItemId) == null){//为空 新增一个
            // 组装答案记录
         // 1.组装批量练习答案
         if(analisisUMap.get(exerciseItemId) == null){//为空 新增一个
            // 组装答案记录
            analisisU = new ExerciseItemAnalisiU();
            analisisU.setDeleteFlag(false);
            analisisU.setExerciseItemId(exerciseItemId);
@@ -1630,7 +1630,7 @@
            analisisU = analisisUMap.get(exerciseItemId);
         }
         // 更新统计数据
         // 更新统计数据
         statis = analisUResultMap.get(exerciseItemId);
         if(null != statis){
            analisisU.setSubmitNumber(new BigInteger(String.valueOf(statis.getAllCount())));
@@ -1650,7 +1650,7 @@
         lstNewAnalisiU.add(analisisU);
      }
      //批量保存
      //批量保存
      this.saveOrUpdateAll(lstNewAnalisiU);
      return new Result(true);
@@ -1658,7 +1658,7 @@
   /**
    * 查询个人 每道题 做题个数,正确个数
    * 查询个人 每道题 做题个数,正确个数
    * @return
    */
   private Map<String,ExerciseItemStatis> getExerciseItemAnalisisUResultDataList(String userId, Map<String, Object> argsMap){
@@ -1666,26 +1666,26 @@
      argsMap.put("userId", userId);
      String sql = "select tmp.EXERCISE_ITEM_ID,sum(allCount),sum(correctCount) from ("
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_item_answer_u t"// 1.(公共答案表)查询每道题 做题个数,正确个数
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_item_answer_u t"// 1.(公共答案表)查询每道题 做题个数,正确个数
            + "       where t.EXERCISE_ITEM_ID in (:exerciseIds) and t.user_id=:userId  and t.DELETE_FLAG=0"
            + "       group by t.EXERCISE_ITEM_ID "
            + "    union all "
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault t, exercise_fault_book b "// 2.错题本
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault t, exercise_fault_book b "// 2.错题本
            + "       where t.RESUME_BOOK_ID=b.RESUME_BOOK_ID and t.EXERCISE_ITEM_ID in (:exerciseIds) and b.user_id=:userId"
            + "       and t.answer is not null and t.DELETE_FLAG=0"
            + "         group by t.EXERCISE_ITEM_ID "
            + "    union all "
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault_his t, exercise_fault_book b "// 3.错题本历史
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_fault_his t, exercise_fault_book b "// 3.错题本历史
            + "       where t.RESUME_BOOK_ID=b.RESUME_BOOK_ID and t.EXERCISE_ITEM_ID in (:exerciseIds) and b.user_id=:userId"
            + "       and t.answer is not null and t.DELETE_FLAG=0"
            + "         group by t.EXERCISE_ITEM_ID "
            + "    union all "
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite t, exercise_favorite_book b "// 4.收藏本
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite t, exercise_favorite_book b "// 4.收藏本
            + "          where t.FAVORITE_BOOK_ID=b.FAVORITE_BOOK_ID and t.EXERCISE_ITEM_ID in (:exerciseIds) and b.user_id=:userId"
            + "       and t.answer is not null and t.DELETE_FLAG=0 "
            + "         group by t.EXERCISE_ITEM_ID "
            + "    union all "
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite_his t, exercise_favorite_book b "// 5.收藏本历史
            + "      select t.EXERCISE_ITEM_ID,count(1) allCount,sum(t.CORRECT=1) correctCount from exercise_favorite_his t, exercise_favorite_book b "// 5.收藏本历史
            + "          where t.FAVORITE_BOOK_ID=b.FAVORITE_BOOK_ID and t.EXERCISE_ITEM_ID in (:exerciseIds) and b.user_id=:userId"
            + "       and t.answer is not null and t.DELETE_FLAG=0 "
            + "         group by t.EXERCISE_ITEM_ID "
@@ -1702,17 +1702,17 @@
      for(Object[] obj:lstResult){
         statis = new ExerciseItemStatis();
         statis.setExerciseId(String.valueOf(obj[0]));
         statis.setAllCount(Integer.parseInt(String.valueOf(obj[1])));// 总个数
         statis.setCorrectCount(Integer.parseInt(String.valueOf(obj[2])));// 正确个数
         statis.setAllCount(Integer.parseInt(String.valueOf(obj[1])));// 总个数
         statis.setCorrectCount(Integer.parseInt(String.valueOf(obj[2])));// 正确个数
         resultMap.put(String.valueOf(obj[0]), statis);// 练习id
         resultMap.put(String.valueOf(obj[0]), statis);// 练习id
      }
      return resultMap;
   }
   /**
    *  查询自由练习练习做题组
    *  查询自由练习练习做题组
    * @param exerType
    * @param subjectId
    * @param pager
@@ -1734,22 +1734,22 @@
      List<Object> args = CollectionUtils.newList((short)exerType, ClientUtils.getClassId(),ClientUtils.getUserId(), ExerciseGroup.STATUS_PUBLISHED);
      if(selected == 1){//未开始
      if(selected == 1){//未开始
         hql.append(" and r.status=? and (r.doCount=0 or r.doCount is null) ");
         args.add(ExerciseRecord.STATUS_NOT_SUBMIT);
      }else if(selected == 2){//做题中
      }else if(selected == 2){//做题中
         hql.append(" and r.status=? and r.doCount>0 ");
         args.add(ExerciseRecord.STATUS_NOT_SUBMIT);
      }else if(selected == 3){//已提交
      }else if(selected == 3){//已提交
         hql.append( " and r.status=? ");
         args.add(ExerciseRecord.STATUS_SUBMIT);
      }
//      if(StringUtils.isNotBlank(subjectId)){// 高校  课程id
//      if(StringUtils.isNotBlank(subjectId)){// 高校  课程id
//         hql.append("  and g.subjectId=? ");
//         args.add(subjectId);
//      }
@@ -1762,7 +1762,7 @@
   }
   /**
    * 查询通用练习做题组
    * 查询通用练习做题组
    * @param exerType
    * @param subjectId
    * @param pager
@@ -1779,7 +1779,7 @@
      List<Object> args = CollectionUtils.newList((short)exerType, ClientUtils.getClassId(), ExerciseGroup.STATUS_PUBLISHED);
      if(selected == 1){//未开始
      if(selected == 1){//未开始
         hql.append(" and not EXISTS" +
               " (select 1 from ExerciseRecord r,ExerciseRecentRecord rr " +
               " where r.recordId=rr.exerciseRecordId " +
@@ -1791,7 +1791,7 @@
         args.add(ClientUtils.getUserId());
         args.add(ExerciseRecord.STATUS_SUBMIT);
      }else if(selected == 2){//做题中
      }else if(selected == 2){//做题中
         hql.append(" and EXISTS" +
               " (select 1 from ExerciseRecord r,ExerciseRecentRecord rr " +
               " where r.recordId=rr.exerciseRecordId " +
@@ -1803,7 +1803,7 @@
         args.add(ClientUtils.getUserId());
         args.add(ExerciseRecord.STATUS_NOT_SUBMIT);
      }else if(selected == 3){//已提交
      }else if(selected == 3){//已提交
         hql.append(" and EXISTS" +
               " (select 1 from ExerciseRecord r,ExerciseRecentRecord rr " +
               " where r.recordId=rr.exerciseRecordId " +
@@ -1817,11 +1817,11 @@
      }
      if(StringUtils.isNotBlank(subjectId)){// 高校  课程id
      if(StringUtils.isNotBlank(subjectId)){// 高校  课程id
         hql.append("  and g.subjectId=? ");
         args.add(subjectId);
      }
      if(StringUtils.isNotBlank(chapterId)){// 章节id
      if(StringUtils.isNotBlank(chapterId)){// 章节id
         hql.append("  and (g.chapterId=? or g.chapterId in(select c.chapterId from SchChapter c where c.parentChapterId = ? and c.deleteFlag is false)) ");
         args.add(chapterId);
         args.add(chapterId);
@@ -1842,11 +1842,11 @@
   }
   /**
    * 查询练习列表数据
    * 查询练习列表数据
    * @param exerType
    * @param subjectId
    * @param pager
    * @param selected // 0:全部  1:未开始 2:做题中 3:已提交
    * @param selected // 0:全部  1:未开始 2:做题中 3:已提交
    * @return
    */
   @Override
@@ -1855,12 +1855,12 @@
      List<ExerciseGroup> lstGroup = null;
      // 1.查询当前用户所在班级的练习组
      if(exerType == ExerciseGroup.TYPE_EXERCISE_FREE){//自由练习
      // 1.查询当前用户所在班级的练习组
      if(exerType == ExerciseGroup.TYPE_EXERCISE_FREE){//自由练习
         lstGroup = queryFreeExerciseGroupList(exerType, subjectId, pager, selected);
      }else{// 非自由练习
      }else{// 非自由练习
         lstGroup = queryCommonExerciseGroupList(exerType, subjectId, pager, selected, chapterId);
      }
@@ -1869,7 +1869,7 @@
         return null;
      }
      // 3.组装参数
      // 3.组装参数
      Map<String, Object> argsMap = new HashMap<String, Object>(2);
      Object[] argss = new Object[lstGroup.size()];
      for(int i=0; i<lstGroup.size(); i++){
@@ -1877,7 +1877,7 @@
      }
      argsMap.put("groupIds", argss);
      // 4.0查询练习组extend
      // 4.0查询练习组extend
      String hql_extend = "from ExerciseGroupExtend "
            + " where groupId in (:groupIds) and deleteFlag is false ";
      List<ExerciseGroupExtend> lstExtend = this.findByComplexHql(hql_extend, argsMap, ExerciseGroupExtend.class);
@@ -1886,7 +1886,7 @@
         extendMap.put(record.getGroupId(), record);
      }
      // 4.查询做题记录集合
      // 4.查询做题记录集合
      argsMap.put("userId", ClientUtils.getUserId());
      String hql_record = "select r from ExerciseRecord r,ExerciseRecentRecord rd "
            + " where r.recordId=rd.exerciseRecordId and rd.exerciseGroupId in (:groupIds) and rd.userId=:userId ";
@@ -1896,21 +1896,21 @@
         recordMap.put(record.getExerciseGroupId(), record);
      }
      // 4.2获取该用户组内排名
      // 4.2获取该用户组内排名
      Map<String, String> groupRankMap = getUserExerGroupRank(argss);
      // 4.3获取个人用户组对应的错题记录 题目更新时间
      // 4.3获取个人用户组对应的错题记录 题目更新时间
      Map<String, Map<String, Object>> faultMap = exerciseExtendService.queryFaultRecordByGroup(subjectId, argss);
      // 4.4获取个人用户组对应的收藏记录 题目更新时间
      // 4.4获取个人用户组对应的收藏记录 题目更新时间
      Map<String, Map<String, Object>> favorMap = exerciseExtendService.queryFavorRecordByGroup(subjectId, argss);
      // 5.组装参数
      // 5.组装参数
      List<ExerGroupResponseData> lstResult = new ArrayList<ExerGroupResponseData>(lstRecord.size());
      ExerGroupResponseData result;
      for(ExerciseGroup g:lstGroup){
         // 组装练习列表返回数据
         // 组装练习列表返回数据
         result = packagingExerciseListData(exerType, extendMap, recordMap,
               groupRankMap, faultMap, favorMap, g);
@@ -1921,7 +1921,7 @@
   }
   /**
    * 组装练习列表返回数据
    * 组装练习列表返回数据
    * @param exerType
    * @param extendMap
    * @param recordMap
@@ -1941,7 +1941,7 @@
      String groupId = g.getGroupId();
      ExerGroupResponseData result = new ExerGroupResponseData();
      // 5.1.赋值练习记录字段
      // 5.1.赋值练习记录字段
      ExerciseRecord record=recordMap.get(groupId);
      if(null != record){
         BeanUtils.copyProperties(record, result);
@@ -1959,38 +1959,38 @@
         result.setStatus("0");
      }
      // 5.3.赋值练习组字段
      // 5.3.赋值练习组字段
      BeanUtils.copyProperties(g, result);
      // 5.4 获取练习组扩展表
      // 5.4 获取练习组扩展表
      ExerciseGroupExtend extend = extendMap.get(groupId);
      if(null != extend){// 扩展表字段
      if(null != extend){// 扩展表字段
         result.setExerciseTime(extend.getExerciseTime());
         result.setExerciseMode(extend.getExerciseMode());
         result.setExerciseStrategy(extend.getExerciseStrategy());
         result.setExerciseSource(extend.getExerciseSource());
         result.setRepeatFlag(!extend.getRepeatFlag());// true 可以重做 false不能重做
         result.setRepeatFlag(!extend.getRepeatFlag());// true 可以重做 false不能重做
         result.setClassAccuracy(extend.getClassAccuracy() == null ? "--" : extend.getClassAccuracy()+"%");
         result.setSubmitNumber(extend.getSubmitNumber());
      }else{
         result.setClassAccuracy("--");
         if(exerType == ExerciseGroup.TYPE_HOMEWORK){// 家庭作业
         if(exerType == ExerciseGroup.TYPE_HOMEWORK){// 家庭作业
            result.setRepeatFlag(false);
         }else{
            result.setRepeatFlag(true);
         }
      }
      // 5.5  获取用户组内排名
      // 5.5  获取用户组内排名
      result.setClassRank(groupRankMap.get(groupId) == null ? "--" : groupRankMap.get(groupId));
      // 5.6更新个人用户组对应的错题时间
      // 5.6更新个人用户组对应的错题时间
      if(faultMap != null && faultMap.get(groupId) !=null){
         result.setFaultUpdateTime((Timestamp)faultMap.get(groupId).get("updateTime"));
         result.setFaultCount((BigInteger)faultMap.get(groupId).get("allCount"));
      }
      // 5.7更新个人用户组对应的收藏时间
      // 5.7更新个人用户组对应的收藏时间
      if(favorMap != null && favorMap.get(groupId) !=null){
         result.setFavorUpdateTime((Timestamp)favorMap.get(groupId).get("updateTime"));
         result.setFavorCount((BigInteger)favorMap.get(groupId).get("allCount"));
@@ -2001,7 +2001,7 @@
   /**
    * 根据groupid得出该用户的组内排名
    * 根据groupid得出该用户的组内排名
    * @param argss
    * @return
    */
@@ -2038,19 +2038,19 @@
         String exerciseRecordId, boolean getExercise, boolean getAnswer,
         short exerType) {
      // 1.获取练习题目
      // 1.获取练习题目
      List<ExerciseItem> lstItem = null;
      if(getExercise){
         lstItem = queryExerciseItemList(groupId);
      }
      // 2.获取练习答案
      // 2.获取练习答案
      List<ExerciseItemAnswerU> lstAnswer = null;
      if(getAnswer && StringUtils.isNotBlank(exerciseRecordId)){
         lstAnswer = queryExerciseItemAnswerList(exerciseRecordId);
      }
      // 3.组装返回参数
      // 3.组装返回参数
      ExerItemResponseData result = new ExerItemResponseData();
      result.setItems(lstItem);
@@ -2061,14 +2061,14 @@
   }
   /**
    * 查询练习答案list
    * 查询练习答案list
    * @param groupId
    * @param exerciseRecordId
    * @return
    */
   private  List<ExerciseItemAnswerU> queryExerciseItemAnswerList(String exerciseRecordId){
      //3.1 查询个人做题答案
      //3.1 查询个人做题答案
      String sql_answerU = "from ExerciseItemAnswerU where exerciseRecordId=?  and deleteFlag is false order by createTime asc ";
      List<ExerciseItemAnswerU> lstAnswerU = this.find(sql_answerU,
@@ -2078,7 +2078,7 @@
   }
   /**
    * 查询练习题目list
    * 查询练习题目list
    * @param groupId
    * @return
    */
@@ -2089,7 +2089,7 @@
      List<ExerciseItem> lstItems = boundValueOperations.get();
      if(lstItems==null){
         // 1.查询练习题目信息
         // 1.查询练习题目信息
         String hql = "select item from ExerciseItem item, ExerciseGroupItemRe re, ExerciseGroup g"
               + " where item.exerciseId=re.exerciseItemId "
               + "   and re.exerciseGroupId=g.groupId"
@@ -2101,11 +2101,11 @@
         lstItems = this.find(hql, CollectionUtils.newList(groupId), ExerciseItem.class);
         // 为空
         // 为空
         if(lstItems.isEmpty()){
            return lstItems;
         }
         // 2.组装答案
         // 2.组装答案
         lstItems = getCommonExerItemDetail(lstItems, groupId);
         boundValueOperations.setIfAbsent(lstItems);
@@ -2116,7 +2116,7 @@
   }
   /**
    * 重新组装练习题 加入分析结果
    * 重新组装练习题 加入分析结果
    * @param lstItems
    * @param exerciseGroupId
    * @param currTitleNumber
@@ -2127,7 +2127,7 @@
   public List<ExerciseItem> getCommonExerItemDetail(List<ExerciseItem> lstItems, String exerciseGroupId){
      String userId = ClientUtils.getUserId();
      // 0.组装参数
      // 0.组装参数
      Map<String, Object> argsMap = new HashMap<String, Object>();
      Object[] args = new Object[lstItems.size()];
      for(int i=0; i<lstItems.size(); i++){
@@ -2135,7 +2135,7 @@
      }
      argsMap.put("exerciseIds", args);
      // 1.查询练习题目全站分析
      // 1.查询练习题目全站分析
      String hql_analisis = "from ExerciseItemAnalisi  where exerciseItemId in (:exerciseIds)  and deleteFlag is false ";
      List<ExerciseItemAnalisi> lstAnalisis = this.findByComplexHql(hql_analisis, argsMap, ExerciseItemAnalisi.class);
      Map<String, ExerciseItemAnalisi> analisiMap = new HashMap<String, ExerciseItemAnalisi>(lstAnalisis.size());
@@ -2143,12 +2143,12 @@
         analisiMap.put(analisis.getExerciseItemId(), analisis);
      }
      // 2.查询练习题目答案选项
      // 2.查询练习题目答案选项
      Map<String, List<ExerciseItemOption>> optionsMap = new HashMap<String, List<ExerciseItemOption>>(lstItems.size());
      Map<String, String> answerMap = new HashMap<String, String>();
      String hql_options = "from ExerciseItemOption where exerciseItemId in (:exerciseIds) and deleteFlag is false order by exerciseItemId, optionOrder ";
      List<ExerciseItemOption> lstAllOptions = this.findByComplexHql(hql_options, argsMap, ExerciseItemOption.class);
      // 2.1.组装参数 用于查询练习选项图片
      // 2.1.组装参数 用于查询练习选项图片
      Map<String, Object> argsImgMap = new HashMap<String, Object>();
      Object[] argImgs = new Object[lstAllOptions.size()];
      for(int i=0; i<lstAllOptions.size(); i++){
@@ -2156,20 +2156,20 @@
      }
      argsImgMap.put("optionIds", argImgs);
      // 2-3-1查询题目是否关联图片
      // 2-3-1查询题目是否关联图片
//      String hql_itemImgs = "from ExerciseObjectImg where exerciseObjectId in (:exerciseIds) and deleteFlag is false and objectType=1 order by exerciseObjectId,imgOrder ";
//      List<ExerciseObjectImg> lstItemImgs = this.findByComplexHql(hql_itemImgs, argsMap, ExerciseObjectImg.class);
//      Map<String, List<ExerciseObjectImg>> imgItemMap = ExerciseUtils.packageExerciseItemImg(lstItemImgs);
      // 2-3-2查询题目选项是否关联图片
      // 2-3-2查询题目选项是否关联图片
//      String hql_optionImgs = "from ExerciseObjectImg where exerciseObjectId in (:optionIds) and deleteFlag is false and objectType=2 order by exerciseObjectId,imgOrder ";
//      List<ExerciseObjectImg> lstOptionImgs = this.findByComplexHql(hql_optionImgs, argsImgMap, ExerciseObjectImg.class);
//      Map<String, List<ExerciseObjectImg>> imgOptionMap = ExerciseUtils.packageExerciseItemImg(lstOptionImgs);
      // 重新组装练习
      // 重新组装练习
      ExerciseUtils.packageExerciseItem(optionsMap, answerMap, lstAllOptions, Collections.EMPTY_MAP);
      // 3.查询练习题目个人分析
      // 3.查询练习题目个人分析
      String hql_analisisU = "from ExerciseItemAnalisiU where exerciseItemId in (:exerciseIds) and userId=:userId and deleteFlag is false ";
      argsMap.put("userId", userId);
      List<ExerciseItemAnalisiU> lstAnalisisU = this.findByComplexHql(hql_analisisU, argsMap, ExerciseItemAnalisiU.class);
@@ -2179,7 +2179,7 @@
      }
      // 4.重新组装返回结果
      // 4.重新组装返回结果
      ExerciseAnalisisResult analisiResult = null;
      ExerciseItemAnalisi analisis = null;
      ExerciseItemAnalisiU analisiU = null;
@@ -2187,15 +2187,15 @@
      for(ExerciseItem item:lstItems){
         analisiResult = new ExerciseAnalisisResult();
         // 4.0  分析结果
         // 4.0  分析结果
         exerciseId = item.getExerciseId();
         // 得到练习组id
         // 得到练习组id
         if(StringUtils.isNotBlank(exerciseGroupId)){
            item.setExerciseGroupId(exerciseGroupId);
         }
         // 4.1 全站分析结果
         // 4.1 全站分析结果
         analisis = analisiMap.get(exerciseId);
         if(null != analisis){
            analisiResult.setAllAccuracy(analisis.getAccuracy());
@@ -2207,7 +2207,7 @@
            analisiResult.setSubmitAllNumber(BigInteger.ZERO);
         }
         // 4.2 个人分析结果
         // 4.2 个人分析结果
         analisiU = analisiUMap.get(exerciseId);
         if(analisiU != null){
            analisiResult.setAccuracy(analisiU.getAccuracy());
@@ -2220,10 +2220,10 @@
            analisiResult.setSubmitErrorNumber(BigInteger.ZERO);
         }
         // 4.3 题目选项
         // 4.3 题目选项
         item.setOptions(optionsMap.get(exerciseId));
//         // 4.5题目中是否有图片
//         // 4.5题目中是否有图片
//         if(imgItemMap.get(exerciseId) != null){
//            item.setImgs(imgItemMap.get(exerciseId));
//         }
@@ -2240,14 +2240,14 @@
   }
   /**
    * 根据条件获取自由练习
    * 根据条件获取自由练习
    *
    *  * {
    *    source: 练习来源(1:练习题库 2:考试题库  3:家庭作业)   多个以逗号分开
      strategy:做题方式(1:未做题优先  2:错题优先)
      mode:做题模式(1:练习模式 2:考试模式)
      count:数量(30 50 100 200)
      exerciseTime:练习时间
    *    source: 练习来源(1:练习题库 2:考试题库  3:家庭作业)   多个以逗号分开
      strategy:做题方式(1:未做题优先  2:错题优先)
      mode:做题模式(1:练习模式 2:考试模式)
      count:数量(30 50 100 200)
      exerciseTime:练习时间
    * }
    *
    * @return
@@ -2258,37 +2258,37 @@
      Result resultMsg = new Result(false);
      ExerItemResponseData result = new ExerItemResponseData();
      /** 1.得到练习题目  */
      /** 1.得到练习题目  */
      List<ExerciseItem> lstItems = getExerciseItemListForFree(subjectId, source, strategy, count);
      if(lstItems.isEmpty()){
         resultMsg.setMsg("当前题库中题目数量为空");
         resultMsg.setMsg("当前题库中题目数量为空");
         result.setResult(resultMsg);
         return result;
      }
      if(lstItems.size() < count){//题库中题目不够
         resultMsg.setMsg("当前题库中题目数量少于"+count+",请重新组合");
      if(lstItems.size() < count){//题库中题目不够
         resultMsg.setMsg("当前题库中题目数量少于"+count+",请重新组合");
         result.setResult(resultMsg);
         return result;
      }
      /** 2.生成此次做题练习组  */
      /** 2.生成此次做题练习组  */
      ExerciseGroup group = generateExerciseGroupByFree(subjectId, source,
            strategy, mode, count, exerciseTime);
      String exerciseGroupId = group.getGroupId();
      /** 3.生成此次做题record  */
      /** 3.生成此次做题record  */
      ExerciseRecord record = generateExerciseRecordByFree(subjectId, exerciseGroupId);
      /** 4.根据题练习组生成练习组关联表数据  */
      /** 4.根据题练习组生成练习组关联表数据  */
      generateExerciseGroupItemRe(lstItems, exerciseGroupId);
      /** 5.组装练习数据  */
      /** 5.组装练习数据  */
      lstItems = getCommonExerItemDetail(lstItems, exerciseGroupId);
      /** 6.返回结果  */
      /** 6.返回结果  */
      result.setItems(lstItems);
      result.setExerciseGroupId(exerciseGroupId);
      result.setExerciseRecordId(record.getRecordId());
@@ -2306,12 +2306,12 @@
   }
   /**
    * 得到练习类型
    * 得到练习类型
    * @param source
    * @return
    */
   private Object[] getExerciseTypeForFree(String source){
      //  练习来源(1:练习题库 2:考试题库  3:家庭作业)   多个以逗号分开
      //  练习来源(1:练习题库 2:考试题库  3:家庭作业)   多个以逗号分开
      String[] types = source.split(",");
      Object[] groupTypes = new Object[4];
@@ -2319,7 +2319,7 @@
      int i = 0;
      for(String type:types){
         if(type.equals(Constants.EXERCISE_SOURCE_EXERICSE)){//练习题库  -章节、专题
         if(type.equals(Constants.EXERCISE_SOURCE_EXERICSE)){//练习题库  -章节、专题
            groupTypes[i]= ExerciseGroup.TYPE_CHAPTER_ITEM;
@@ -2329,13 +2329,13 @@
            i++;
         }else if(type.equals(Constants.EXERCISE_SOURCE_EXAMS)){// 考试题库 - 模拟考试
         }else if(type.equals(Constants.EXERCISE_SOURCE_EXAMS)){// 考试题库 - 模拟考试
            groupTypes[i]= ExerciseGroup.TYPE_MOCK_EXAM;
            i++;
         }else if(type.equals(Constants.EXERCISE_SOURCE_HOMEWORK)){// 家庭作业
         }else if(type.equals(Constants.EXERCISE_SOURCE_HOMEWORK)){// 家庭作业
            groupTypes[i]= ExerciseGroup.TYPE_HOMEWORK;
@@ -2348,7 +2348,7 @@
   }
   /**
    * 得到练习题
    * 得到练习题
    * @param subjectId
    * @param source
    * @param strategy
@@ -2358,29 +2358,29 @@
   private List<ExerciseItem> getExerciseItemListForFree(String subjectId,
            String source, String strategy, int count){
      // 得到组类型集合
      // 得到组类型集合
      Object[] groupTypes = getExerciseTypeForFree(source);
      // 查询结果练习item list
      // 查询结果练习item list
      List<ExerciseItem> lstItems = null;
      // 查询结果不够时,新增练习item list
      // 查询结果不够时,新增练习item list
      List<ExerciseItem> lstAddItems = null;
      /** 1.获取题目  */
      if(Constants.EXERCISE_STRATEGY_NO_DO.equals(strategy)){// 未做题
      /** 1.获取题目  */
      if(Constants.EXERCISE_STRATEGY_NO_DO.equals(strategy)){// 未做题
         // 1.获取未做题
         // 1.获取未做题
         lstItems = getFreeExerciseForNoDo(subjectId, count, groupTypes);
      }else if(Constants.EXERCISE_STRATEGY_FAULT.equals(strategy)){// 错题
      }else if(Constants.EXERCISE_STRATEGY_FAULT.equals(strategy)){// 错题
         // 1.获取错题
         // 1.获取错题
         lstItems = getFreeExerciseForFault(subjectId, count, groupTypes);
      }
      // 2.错题不够,从普通题目中挑选
      // 2.错题不够,从普通题目中挑选
      if(lstItems.size() < count){
         Object[] exerciseIds = new Object[lstItems.size()];
@@ -2392,18 +2392,18 @@
               count-exerciseIds.length, groupTypes,exerciseIds);
         // 3.组合为最新的一个练习 item list
         // 3.组合为最新的一个练习 item list
         lstItems.addAll(lstAddItems);
      }
      // 打乱顺序
      // 打乱顺序
      Collections.shuffle(lstItems);
      return lstItems;
   }
   /**
    * 生成练习组关联关系
    * 生成练习组关联关系
    * @param lstItems
    * @param groupId
    * @return
@@ -2430,7 +2430,7 @@
   }
   /**
    * 生成练习record数据
    * 生成练习record数据
    *
    * @param subjectId
    * @param exerciseGroupId
@@ -2443,14 +2443,14 @@
      this.insertExerciseRecordNew(record, exerciseGroupId, subjectId);
      // 操作最近一次做题记录
      // 操作最近一次做题记录
      doOperExerciseRecentRecord(record);
      return record;
   }
   /**
    * 生成 练习组以及扩展数据
    * 生成 练习组以及扩展数据
    * @param subjectId
    * @param source
    * @param strategy
@@ -2462,7 +2462,7 @@
   private ExerciseGroup generateExerciseGroupByFree(String subjectId, String source,
         String strategy, String mode, int count, String exerciseTime){
      // 1.练习组
      // 1.练习组
      ExerciseGroup group = new ExerciseGroup();
      group.setClassId(ClientUtils.getClassId());
@@ -2474,11 +2474,11 @@
      group.setDeleteFlag(false);
      group.setStatus(ExerciseGroup.STATUS_PUBLISHED);
      TraceUtils.setCreateTrace(group);
      group.setName("自由练习-"+DateTimeUtils.formatDate(group.getCreateTime(),"MMdd_HHmmss"));
      group.setName("自由练习-"+DateTimeUtils.formatDate(group.getCreateTime(),"MMdd_HHmmss"));
      this.exerciseService.saveExerciseGroup(group);
      // 2.练习组扩展表
      // 2.练习组扩展表
      ExerciseGroupExtend extend = new ExerciseGroupExtend();
      extend.setGroupId(group.getGroupId());
      extend.setExerciseSource(source);
@@ -2494,7 +2494,7 @@
   }
   /**
    * 得到已经做完的题目 个人
    * 得到已经做完的题目 个人
    * @param subjectId
    * @return
    */
@@ -2516,7 +2516,7 @@
      List<Object[]> lstObjs = this.findwithRawResult(hql.toString(), args);
      // 组装练习ids
      // 组装练习ids
      Object[] exerciseIds = new Object[lstObjs.size()];
      for(int i=0; i<lstObjs.size(); i++){
@@ -2529,14 +2529,14 @@
   }
   /**
    * 根据条件获取错题练习   未做题
    * 根据条件获取错题练习   未做题
    * @param subjectId
    * @param count
    * @param groupTypes
    * @return
    */
   private List<ExerciseItem> getFreeExerciseForNoDo(String subjectId, int count, Object[] groupTypes){
      // 获取已经做完的题目
      // 获取已经做完的题目
      Object[] exerciseIds = getExerciseIsHasDo(subjectId);
      StringBuffer hql = new StringBuffer(512);
@@ -2563,11 +2563,11 @@
         argsMap.put("subjectId", subjectId);
      }
      // 1.查询分页数据
      // 1.查询分页数据
      Pager pager = getFreeExercisePagerData("select count(distinct i.exerciseId) " + hql.toString(),
            argsMap, count);
      // 2.分页查询结果list
      // 2.分页查询结果list
      List<ExerciseItem> lstItems = this.findByComplexHql("select distinct i " + hql.toString(),
            pager, argsMap, ExerciseItem.class);
@@ -2575,7 +2575,7 @@
   }
   /**
    * 得到自由练习分页数据
    * 得到自由练习分页数据
    * @param hql
    * @param argsMap
    * @param count
@@ -2585,19 +2585,19 @@
      int iAllCount = this.findCountByComplexHql(hql, argsMap);
      // 总页数
      // 总页数
      int allPage = iAllCount / pageSize;
      // 页码
      // 页码
      int pageNum = 0;
      if(allPage < 1){
         pageNum = 1;
      }else{
         pageNum = new Random().nextInt(allPage);//随机取页数
         pageNum = new Random().nextInt(allPage);//随机取页数
      }
      // 分页
      // 分页
      Pager page = new Pager();
      page.setPageNum(pageNum);
      page.setPageSize(pageSize);
@@ -2606,7 +2606,7 @@
   }
   /**
    * 获取题目 根据题目类型
    * 获取题目 根据题目类型
    * @param subjectId
    * @param count
    * @param groupTypes
@@ -2615,7 +2615,7 @@
   private List<ExerciseItem> getFreeExerciseForCommon(String subjectId,
            int count, Object[] groupTypes, Object[] exerciseIds){
      // 获取题目
      // 获取题目
      Pager page = new Pager();
      page.setPageNum(1);
      page.setPageSize(count);
@@ -2645,7 +2645,7 @@
      }
      // 获取题目
      // 获取题目
      List<ExerciseItem> lstItem = this.findByComplexHql(hql.toString(), page, argsMap, ExerciseItem.class);
@@ -2653,7 +2653,7 @@
   }
   /**
    * 根据条件获取错题练习  错题
    * 根据条件获取错题练习  错题
    * @param subjectId
    * @param count
    * @param groupTypes
@@ -2681,11 +2681,11 @@
         argsMap.put("subjectId", subjectId);
      }
      // 1.查询分页数据
      // 1.查询分页数据
      Pager pager = getFreeExercisePagerData("select count(distinct i.exerciseId) " + hql.toString(),
            argsMap, count);
      // 2.获取题目list
      // 2.获取题目list
      List<ExerciseItem> lstItems = this.findByComplexHql("select distinct i " + hql.toString(),
            pager, argsMap, ExerciseItem.class);
@@ -2693,13 +2693,13 @@
   }
   /**
    * 查询题目统计分析结果 个人统计 全站统计
    * 查询题目统计分析结果 个人统计 全站统计
    * @param groupId
    * @return
    */
   @Override
   public List<Map<String, Object>> queryExerciseItemStatisics(String groupId) {
      // 1.查询个人统计
      // 1.查询个人统计
      String hql_analisisU = "select a from ExerciseItemAnalisiU a,ExerciseGroupItemRe re"
            + " where a.exerciseItemId=re.exerciseItemId and re.exerciseGroupId=? "
            + " and a.userId=? and a.deleteFlag is false and re.deleteFlag is false ";
@@ -2711,7 +2711,7 @@
         anasisUMap.put(analisisU.getExerciseItemId(), analisisU);
      }
      // 2.查询全站统计
      // 2.查询全站统计
      String hql_analisis = "select a from ExerciseItemAnalisi a,ExerciseGroupItemRe re"
            + " where a.exerciseItemId=re.exerciseItemId and re.exerciseGroupId=? "
            + " and a.deleteFlag is false and re.deleteFlag is false ";
@@ -2726,7 +2726,7 @@
         return null;
      }
      // 3.查询此组所有题目
      // 3.查询此组所有题目
      String hql_group = "from ExerciseGroupItemRe re where re.deleteFlag is false and re.exerciseGroupId = ? order by re.itemOrder";
      List<ExerciseGroupItemRe> lstGroup = this.find(hql_group,
            CollectionUtils.newList(groupId), ExerciseGroupItemRe.class);
@@ -2737,23 +2737,23 @@
      ExerciseItemAnalisi analisis;
      ExerciseItemAnalisiU analisisU;
      // 3.组装结果
      // 3.组装结果
      // 循坏组所有题目
      // 循坏组所有题目
      for(ExerciseGroupItemRe group:lstGroup){
         // 结果map
         // 结果map
         resultMap = new HashMap<String, Object>(10);
         exerciseItemId = group.getExerciseItemId();
         // 1.个人分析结果
         // 1.个人分析结果
         analisisU = anasisUMap.get(exerciseItemId);
         // 2.全站分析结果
         // 2.全站分析结果
         analisis = anasisMap.get(exerciseItemId);
         resultMap.put("exerciseId", exerciseItemId);
         // 3.个人统计
         if(null == analisisU){// 为空
         // 3.个人统计
         if(null == analisisU){// 为空
            resultMap.put("doAll_u", 0);
            resultMap.put("doError_u", 0);
            resultMap.put("doAccuracy_u", 0);
@@ -2763,8 +2763,8 @@
            resultMap.put("doAccuracy_u", analisisU.getAccuracy());
         }
         // 4.全站统计
         if(null == analisis){// 为空
         // 4.全站统计
         if(null == analisis){// 为空
            resultMap.put("doAll", 0);
            resultMap.put("doAccuracy", 0);
         }else{
@@ -2780,7 +2780,7 @@
   }
   /**
    * 操作本次做题记录
    * 操作本次做题记录
    * @return
    */
   @Override
@@ -2799,7 +2799,7 @@
      TraceUtils.setCreateTrace(record);
      this.save(record);
      // 操作最近一次做题记录
      // 操作最近一次做题记录
      doOperExerciseRecentRecord(record);
      Map<String,Object> resultMap = new HashMap<String, Object>(3);
@@ -2812,7 +2812,7 @@
   }
   /**
    * 操作本次做题记录
    * 操作本次做题记录
    * @return
    */
   @Deprecated
@@ -2834,7 +2834,7 @@
      TraceUtils.setCreateTrace(record);
      this.save(record);
      // 操作最近一次做题记录
      // 操作最近一次做题记录
      doOperExerciseRecentRecord(record);
      Map<String,Object> resultMap = new HashMap<String, Object>(3);
@@ -2848,7 +2848,7 @@
   /**
    * 更新练习组班级正确率信息
    * 更新练习组班级正确率信息
    * @return
    */
   @Override
@@ -2864,12 +2864,12 @@
   }
   /**
    * 发送班级排名请求消息
    * 发送班级排名请求消息
    * @return
    */
   @Override
   public Result sendUpdateClassRankMsg(String groupId) {
      // 更新练习得分排名
      // 更新练习得分排名
      rankService.reqUpdateRank(ClientUtils.getUserId(), SchRank.RANK_TYPE_EXERCISE_SCORE,
            SchRank.SCOPE_TYPE_CLASS_GROUP, groupId);
@@ -2878,14 +2878,14 @@
   /**
    * 请求修改该组班级正确率
    * 请求修改该组班级正确率
    * @param record
    * @return
    */
   @Override
   public Result sendUpdateClassAccuracyMsg(String exerciseGroupId, String doCount, String correctCount){
      // 异步调用 发送消息
      // 异步调用 发送消息
//      ONSMsg msg = new ONSMsg(onsProducer.getTopic());
//
//      msg.put("msgType", "EXER_GROUP_ACCURACY");
@@ -2910,18 +2910,18 @@
   public Result doUpdateExerciseRecord(String exerciseRecordId,
         String groupId, String currTitleNum) {
      if(StringUtils.isBlank(exerciseRecordId)){ // 记录ID为空
         return new Result(false, "记录id为空");
      if(StringUtils.isBlank(exerciseRecordId)){ // 记录ID为空
         return new Result(false, "记录id为空");
      }
      ExerciseRecord record = this.read(ExerciseRecord.class, exerciseRecordId);
      if(record == null
            || !ClientUtils.getUserId().equals(record.getUserId())){
         return new Result(false, "非法操作,不是当前用户更新题号");
         return new Result(false, "非法操作,不是当前用户更新题号");
      }
      if(StringUtils.isNotBlank(currTitleNum)){// 当前题号
      if(StringUtils.isNotBlank(currTitleNum)){// 当前题号
         record.setTitleMaxNumber(currTitleNum);
      }
@@ -2929,7 +2929,7 @@
      return new Result(true);
      /*// 2.重新生成新的记录    ios导致重做  先关闭此段代码
      /*// 2.重新生成新的记录    ios导致重做  先关闭此段代码
      ExerciseRecord record = new ExerciseRecord();
      record.setAccuracy(BigDecimal.ZERO);
      record.setCompletionRate(BigDecimal.ZERO);
@@ -2948,20 +2948,20 @@
      this.save(record);
      // 3.操作最近一次做题记录
      // 3.操作最近一次做题记录
      doOperExerciseRecentRecord(record);*/
   }
   @Override
   public Result updateExerciseRecordObj(ExerciseRecord record) {
      // TraceUtils.setUpdateTrace(record); ---不更新时间
      // TraceUtils.setUpdateTrace(record); ---不更新时间
      this.save(record);
      return new Result(true);
   }
   /**
    *
    * 保存app端请求保存的数据
    * 保存app端请求保存的数据
    * @return
    */
   @Override
@@ -2977,7 +2977,6 @@
      log.setUpdator(ClientUtils.getUserName());
      log.setStatus(status);
      log.setUrl(url);
      this.save(log);
@@ -3002,25 +3001,25 @@
   /**
    * 操作练习答案数据同步
    * 操作练习答案数据同步
    */
   public Map<String,Object> doOperExerciseAnswerData(ExerciseSubmitAnswerData clientAnswerData) {
      // 0.重新整理答题数据
      // 0.重新整理答题数据
      ExerciseSubmitAnswerData answerData = this.getExerciseSubmitAnswerDataNew(clientAnswerData);
      //  1.当前练习组 判断 是否新纪录   提交的为同一个组  ExerciseRecord
      //  1.当前练习组 判断 是否新纪录   提交的为同一个组  ExerciseRecord
      Map<String,Object> resultMap = doOperExerciseRecordNew(answerData);
      //  2.提交练习答案
      //  2.提交练习答案
      Result result = doSubmitExerciseAnswerDataNew(answerData, String.valueOf(resultMap.get("exerciseRecordId")));
      //如果是是阅卷,发布消息
      //如果是是阅卷,发布消息
      if(answerData.getStatus().equals(String.valueOf(ExerciseRecord.STATUS_CHECK))){
         this.doCheckMsg(answerData);
      }
      // 该套题总做题个数、正确个数
      // 该套题总做题个数、正确个数
      resultMap.put("doCount", result.getData("doCount"));
      resultMap.put("correctCount", result.getData("correctCount"));
@@ -3031,29 +3030,29 @@
      String msg = null;
      Map<String,String> attrs = null;
      //答题记录
      //答题记录
      ExerciseRecord record= this.read(ExerciseRecord.class, answerData.getExerciseRecordId());
      //考试
      //考试
      if(StringUtils.isNotEmpty(record.getExamBatchId())){
         ExamBatchInfo batchInfo = this.read(ExamBatchInfo.class,record.getExamBatchId());
         attrs = CollectionUtils.newStringMap("examBatchId",record.getExamBatchId(),"examName",batchInfo.getExamInfo().getExamName(),
                   "subjectId",batchInfo.getExamInfo().getSubjectId(),
                  "subjectName",batchInfo.getExamInfo().getSubject().getName());
         msg = "老师批改了考试";
         msg = "老师批改了考试";
      }else{
         ExerciseInfo exerciseInfo = this.read(ExerciseInfo.class,answerData.getExerciseInfoId());
         attrs = CollectionUtils.newStringMap("exerciseInfoId",exerciseInfo.getExerciseInfoId(),"exerciseName",exerciseInfo.getName(),
               "subjectId",exerciseInfo.getSubjectId(),
               "subjectName",exerciseInfo.getSubject().getName(),"creator",exerciseInfo.getCreator(),"exerciseType",String.valueOf(exerciseInfo.getType()));
         msg = "老师批改了答题作业";
         msg = "老师批改了答题作业";
      }
      msgInfoService.doSendTextMsgToUsers(new String[]{record.getUserId()}, MsgInfo.TYPE_CHECK, msg, attrs);
   }
   /**
    * 操作练习记录
    * 操作练习记录
    * @param answerData
    * @return
    */
@@ -3062,8 +3061,8 @@
      ExerciseRecord record = this.read(ExerciseRecord.class, recordId);
      //如果是作业需要处理
      if(record == null){// 第一次做题
      //如果是作业需要处理
      if(record == null){// 第一次做题
         record = new ExerciseRecord();
         record.setStatus(answerData.getStatus());
         record = this.insertExerciseRecordMutiNew(record,
@@ -3071,7 +3070,7 @@
         doOperExerciseRecentRecord(record);
      }else{
         // 更新做题记录
         // 更新做题记录
         record = this.updateExerciseRecordNew(record, answerData);
      }
@@ -3085,7 +3084,7 @@
   /**
    * 操作练习记录
    * 操作练习记录
    * @param answerData
    * @return
    */
@@ -3098,24 +3097,24 @@
         record = this.read(ExerciseRecord.class, recordId);
      }
      // 2.操作做题记录
      // 2.操作做题记录
      if(record != null){
         // 更新做题记录
         // 更新做题记录
         record = this.updateExerciseRecordNew(record, answerData);
      }else{
         record = new ExerciseRecord();
         record.setStatus(answerData.getStatus());
         record.setTitleMaxNumber(answerData.getCurrTitleNum());
         // 新增做题记录
         // 新增做题记录
         record = this.insertExerciseRecordMutiNew(record, exerciseGroupId,
               answerData.getSubjectId(),answerData.getSubmitTime());
         recordId =record.getRecordId();
      }
      // 3.操作最近一次做题记录
      // 3.操作最近一次做题记录
      doOperExerciseRecentRecord(record);
      // 4.返回结果
      // 4.返回结果
      Map<String,Object> resultMap = new HashMap<String, Object>(4);
      resultMap.put("exerciseRecordId", record.getRecordId());
@@ -3145,13 +3144,13 @@
//   public static void main(String [] args){
//      ExerciseVerService s = new ExerciseVerService();
//      s.checkSimilarity("1981年", "1981");
//      s.checkSimilarity("教与学系统", "教与学的系统");
//      s.checkSimilarity("教与学的系统", "教与学系统");
//      System.out.println(HanLP.extractKeyword("中国人", 100));
//      System.out.println(HanLP.extractKeyword("中国  人  def", 100));
//      System.out.println(HanLP.segment("中国人"));
//      s.checkSimilarity("中国人", "中国");
//      s.checkSimilarity("1981年", "1981");
//      s.checkSimilarity("教与学系统", "教与学的系统");
//      s.checkSimilarity("教与学的系统", "教与学系统");
//      System.out.println(HanLP.extractKeyword("中国人", 100));
//      System.out.println(HanLP.extractKeyword("中国  人  def", 100));
//      System.out.println(HanLP.segment("中国人"));
//      s.checkSimilarity("中国人", "中国");
//   }