package com.ibeetl.jlw.service; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.jlw.util.EnumUtil; import cn.jlw.util.ToolUtils; import cn.jlw.validate.ValidateConfig; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ibeetl.admin.core.entity.CoreUser; import com.ibeetl.admin.core.service.CoreBaseService; import com.ibeetl.admin.core.util.PlatformException; import com.ibeetl.admin.core.util.TimeTool; import com.ibeetl.admin.core.web.JsonResult; import com.ibeetl.admin.core.web.JsonReturnCode; import com.ibeetl.jlw.dao.GeneralQuestionLogDao; import com.ibeetl.jlw.dao.GeneralQuestionSettingDao; import com.ibeetl.jlw.dao.GeneralResourcesQuestionSnapshotDao; import com.ibeetl.jlw.entity.*; import com.ibeetl.jlw.entity.dto.QuestionSettingDTO; import com.ibeetl.jlw.enums.GlobalPushStatusEnum; import com.ibeetl.jlw.enums.QuestionBussinessTypeEnum; import com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum; import com.ibeetl.jlw.enums.ResourcesQuestionTypeEnum; import com.ibeetl.jlw.web.query.GeneralQuestionSettingQuery; import com.ibeetl.jlw.web.query.GeneralResourcesQuestionSnapshotQuery; import com.ibeetl.jlw.web.query.ResourcesQuestionQuery; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.beetl.sql.core.SqlId; import org.beetl.sql.core.engine.PageQuery; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.io.*; import java.util.*; import static cn.hutool.core.util.ObjectUtil.defaultIfNull; import static cn.jlw.util.CacheUserUtil.getStudent; import static cn.jlw.util.QuestionUtil.shuffleQuestion; import static com.ibeetl.admin.core.util.ExcelUtil.getCellFormatValue; import static com.ibeetl.jlw.enums.BusinessCourseInfoEnum.SYSTEM_QUESTION; import static com.ibeetl.jlw.enums.QuestionLogAddTypeEnum.FINALLY_SUBMIT; import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.CHAPTER_EXERCISE; import static com.ibeetl.jlw.enums.ResourcesQuestionSnapshotFromTypeEnum.HOMEWORK_FILE; /** * 通用题目配置 Service * 当分布式ID开启后请勿使用insert(*,true) */ @Service @Transactional @Validated public class GeneralQuestionSettingService extends CoreBaseService{ @Autowired private GeneralQuestionSettingDao generalQuestionSettingDao; @Autowired private GeneralResourcesQuestionSnapshotDao generalResourcesQuestionSnapshotDao; @Autowired private GeneralQuestionLogDao generalQuestionLogDao; @Autowired private GeneralQuestionLogService generalQuestionLogService; @Autowired private GeneralResourcesQuestionSnapshotService generalResourcesQuestionSnapshotService; @Autowired private ResourcesQuestionService resourcesQuestionService; public PageQueryqueryByCondition(PageQuery query){ PageQuery ret = generalQuestionSettingDao.queryByCondition(query); queryListAfter(ret.getList()); return ret; } public PageQueryqueryByConditionQuery(PageQuery query){ PageQuery ret = generalQuestionSettingDao.queryByConditionQuery(query); queryListAfter(ret.getList()); return ret; } public void deleteByList(List list){ String ids = ""; ToolUtils.deleteNullList(list); for(int i=0;null != list && i generalQuestionSettingList = new ArrayList<>(); try { generalQuestionSettingList = JSON.parseArray(generalQuestionSettingQuery.getGeneralQuestionSettingJsonStr(), GeneralQuestionSetting.class); } catch (Exception e) { try { generalQuestionSettingList.add(JSONObject.parseObject(generalQuestionSettingQuery.getGeneralQuestionSettingJsonStr(), GeneralQuestionSetting.class)); } catch (Exception e1) {} } ToolUtils.deleteNullList(generalQuestionSettingList); if(null != generalQuestionSettingList && generalQuestionSettingList.size()>0){ for(int i=0;i 0; if(!flag){ msg = "更新指定参数失败"; } }else{ msg = "指定参数为空"; } return msg; } public List getValues (Object paras){ return sqlManager.select(SqlId.of("jlw.generalQuestionSetting.getGeneralQuestionSettingValues"), GeneralQuestionSetting.class, paras); } public List getValuesByQuery (GeneralQuestionSettingQuery generalQuestionSettingQuery){ return generalQuestionSettingDao.getValuesByQuery(generalQuestionSettingQuery); } public List getValuesByQueryNotWithPermission (GeneralQuestionSettingQuery generalQuestionSettingQuery){ return generalQuestionSettingDao.getValuesByQueryNotWithPermission(generalQuestionSettingQuery); } public GeneralQuestionSetting getInfo (Long generalQuestionSettingId){ GeneralQuestionSettingQuery generalQuestionSettingQuery = new GeneralQuestionSettingQuery(); generalQuestionSettingQuery.setGeneralQuestionSettingId(generalQuestionSettingId); generalQuestionSettingQuery.setGeneralQuestionSettingStatusPlural("1");//需要根据实际情况来 List list = generalQuestionSettingDao.getValuesByQuery(generalQuestionSettingQuery); if(null != list && list.size()>0){ return list.get(0); }else{ return null; } } public GeneralQuestionSetting getInfo (GeneralQuestionSettingQuery generalQuestionSettingQuery){ List list = generalQuestionSettingDao.getValuesByQuery(generalQuestionSettingQuery); if(null != list && list.size()>0){ return list.get(0); }else{ return null; } } public JsonResult importTemplate(List fileEntityList,Listlist,CoreUser coreUser){ ListerrMsg = new ArrayList<>(); String msg =""; int count = 0; Date date = new Date(); for(int item=0;null != fileEntityList && item map = new HashMap<>();//获取需要的表头的列 //从第一列找到需要的表头 for (int i=0; i0?JsonReturnCode.SUCCESS.getCode():JsonReturnCode.FAIL.getCode()); jsonResult.setData(errMsg); jsonResult.setMsg((count>0?"导入成功,共导入"+count+"条":"导入失败")+(StringUtils.isNotBlank(msg)?"
"+msg:"")); return jsonResult; } public List> getExcelValues (GeneralQuestionSettingQuery generalQuestionSettingQuery){ return generalQuestionSettingDao.getExcelValues(generalQuestionSettingQuery); } public void editPushStatus(@NotEmpty(message = "题目配置ID不能为空!") String ids, @NotNull(message = "发布状态不能为空!") GlobalPushStatusEnum pushStatus) { for (String settingId : ids.split(",")) { GeneralQuestionSetting model = new GeneralQuestionSetting(); model.setGeneralQuestionSettingId(Long.valueOf(settingId)); model.setGeneralQuestionSettingPushStatus(pushStatus); updateTemplate(model); } } /** * 根据题目配置ID查询当前时间,是否可以参加进行题目测试 * @param questionSettingId * @return */ public boolean verifyQuestionStartAndEndTimeWithNowTime(Long questionSettingId) { if (ObjectUtil.isNotEmpty(questionSettingId)) { GeneralQuestionSetting info = getInfo(questionSettingId); return DateUtil.isIn(DateUtil.date(), info.getGeneralQuestionStartTime(), info.getGeneralQuestionEndTime()); } return false; } /** * 根据题目配置ID查询当前时间,是否可以参加进行题目测试 * 抛出异常 * @param questionSettingId * @return */ public void verifyQuestionStartAndEndTimeWithNowTimeThrow(Long questionSettingId) { Assert.isTrue(verifyQuestionStartAndEndTimeWithNowTime(questionSettingId), "当前时间不在题目操作的时间段!"); } /** * 获取作业 * * @param generalQuestionSettingId 开课作业ID * @param fromTypeEnum * @return */ public List questionDetail(@NotNull(message = "题目配置ID不能为空!") final Long generalQuestionSettingId, @NotNull(message = "类型不能为空!") ResourcesQuestionSnapshotFromTypeEnum fromTypeEnum) { // 获取学生ID final Student student = getStudent(); Assert.notNull(student, "非学生身份,无法获取题目!"); Assert.isTrue(!fromTypeEnum.equals(HOMEWORK_FILE), "作业-附件类型 不需要获取题目快照!"); // 学生ID final Long studentId = student.getStudentId(); // 常量 True的Integer表现 final Integer TRUE_CONST = 1; List resourcesQuestionSnapshots; GeneralQuestionSetting hwSetting = getInfo(generalQuestionSettingId); Assert.notNull(hwSetting, "未查询到来源ID对应的题目!"); // 章节练习,则跳过次数验证; // 其他类型,都需要验证作答次数 if (!EnumUtil.contains(fromTypeEnum, CHAPTER_EXERCISE)) { // 作答次数 Integer generalQuestionSettingSettingDoCount = hwSetting.getGeneralQuestionSettingDoCount(); Assert.isTrue(generalQuestionSettingSettingDoCount > 0, "作答次数设置有误,请联系管理员!"); // 数据库查询该学生已经做过的次数, 这个试卷如果已经交卷的话,就提示用户 GeneralQuestionLog generalQuestionLog = new GeneralQuestionLog(); generalQuestionLog.setStudentId(studentId); generalQuestionLog.setQuestionLogAddType(FINALLY_SUBMIT); generalQuestionLog.setGeneralQuestionSettingId(generalQuestionSettingId); long doCount = generalQuestionLogDao.templateCount(generalQuestionLog); // 断言判断最大作答次数 Assert.isTrue(doCount < generalQuestionSettingSettingDoCount, "已超过最大作答次数!"); } GeneralResourcesQuestionSnapshotQuery questionSnapshotQuery = new GeneralResourcesQuestionSnapshotQuery(); questionSnapshotQuery.setGeneralQuestionSettingId(generalQuestionSettingId); // 答卷后显示答案解析 if (TRUE_CONST.equals(hwSetting.getGeneralQuestionSettingEndShowQa())) { /** 实现 {@link GeneralQuestionLogService#questionAnalysis} */ } // 答卷后显示答案对错 if (TRUE_CONST.equals(hwSetting.getGeneralQuestionSettingEndShowTrueFalse())) { /** 实现 {@link GeneralQuestionLogService#questionAnalysis} */ } // 题目乱序(同一大题内) if (TRUE_CONST.equals(hwSetting.getGeneralQuestionSettingQuestionNoOrder())) { questionSnapshotQuery.setRand(true); } // 题目查询 resourcesQuestionSnapshots = generalResourcesQuestionSnapshotService.getValuesByQueryNotWithPermission(questionSnapshotQuery); // resourcesQuestionSnapshots = defaultIfNull(resourcesQuestionSnapshots, new ArrayList<>()); // 选项乱序(限单选、多选) if (TRUE_CONST.equals(hwSetting.getGeneralQuestionSettingOptionNoOrder())) { // 单题选项排序处理 resourcesQuestionSnapshots.forEach(value -> { shuffleQuestion(value, "questionStem","questionOption", "questionAnswer", "questionType"); }); } // 学生身份屏蔽答案,且记录在做题日志表中,这里不为空的判断有点多余 { // 判断章节练习是否需要重发试卷的题目 boolean selectIsReSend = generalQuestionLogService. verifyLogAddTypeIsReSend(generalQuestionSettingId, studentId, fromTypeEnum, FINALLY_SUBMIT); // 做题日志关联学生, 初步提交做题日志信息,不包含学生提交的答案和得分情况 generalQuestionLogService.preSubmitStudentQuestionLog(studentId, hwSetting, resourcesQuestionSnapshots, selectIsReSend); // 学生身份,需要屏蔽答案,再丢给前端 resourcesQuestionSnapshots.forEach(GeneralResourcesQuestionSnapshot::hideAnswer); } return resourcesQuestionSnapshots; } public void deleteSettingAndSnapByIds(@NotEmpty String settingIds) { generalQuestionSettingDao.deleteByIds(settingIds); generalResourcesQuestionSnapshotService.deleteGeneralResourcesQuestionSnapshot(settingIds); } /** * 增加题目类型的数据 * 从系统题库中拉取 *

* 任务一;添加题目配置主表 * 任务二:添加题目快照表 * * @param settingQuery 题目配置信息 * @param courseInfoIdPair 新旧课程ID片段 * @return */ public void addSettingBySystemCourse(@Validated(ValidateConfig.ADD.class) GeneralQuestionSettingQuery settingQuery, Map courseInfoIdPair ) { // 添加到作业主表中 add(settingQuery); // 插入快照 final Long teacherOpenCourseQuestionSettingId = settingQuery.getGeneralQuestionSettingId(); // 传入的开课题目IDS String resourcesQuestionIdPlural = settingQuery.getResourcesQuestionIdPlural(); // 题目类型区分 Collection settingDTOList = settingQuery.getQuestionSettingOptions(); // 如果指定的题目IDs不为空的话,则需要对这些题目进行题目类型分组。 if(ObjectUtil.isNotEmpty(resourcesQuestionIdPlural)) { ResourcesQuestionQuery questionQuery = new ResourcesQuestionQuery(); questionQuery.setQuestionStatus(1); questionQuery.setResourcesQuestionIds(resourcesQuestionIdPlural); List questionList = resourcesQuestionService.getValuesByQueryNotWithPermission(questionQuery); // 无差别题目IDS转换成类型区分的集合 Map map = resourcesQuestionService.buildSettingDtoListByNoDiffQuestionList(questionList); // 设置分值 settingQuery.getQuestionSettingOptions().forEach(item -> { QuestionSettingDTO settingDTO = map.get(item.getQuestionType()); if(ObjectUtil.isAllNotEmpty(settingDTO, item.getSingleScore())) { settingDTO.setSingleScore(item.getSingleScore()); } }); if (ObjectUtil.isNotEmpty(map)) { settingDTOList = map.values(); } } List list = generalResourcesQuestionSnapshotService.getQuestionBySettingOptionDTOList(settingDTOList, Collections.emptyMap()); if (ObjectUtil.isNotEmpty(list)) { list.forEach(item -> { item.setGeneralQuestionSettingId(teacherOpenCourseQuestionSettingId); item.setBusinessCourseInfoId(settingQuery.getBusinessId()); item.setBusinessCourseInfoType(SYSTEM_QUESTION); }); // 更新ID setNewCourseInfoId(list, courseInfoIdPair); generalResourcesQuestionSnapshotDao.insertBatch(list); } else { throw new PlatformException("题目配置信息有误,未获取到的题目!"); } } /** * 根据课程新旧ID片段集合,设置新的课程ID * * @param insertList * @param courseInfoIdPair */ public void setNewCourseInfoId(@NotNull Collection insertList, @NotNull Map courseInfoIdPair) { if (ObjectUtil.isAllNotEmpty(insertList, courseInfoIdPair)) { insertList.forEach(item -> { Long businessCourseInfoId = item.getBusinessCourseInfoId(); item.setBusinessCourseInfoId(courseInfoIdPair.getOrDefault(businessCourseInfoId, businessCourseInfoId)); }); } } }