|
@@ -0,0 +1,204 @@
|
|
|
|
|
+package cn.iocoder.byzs.module.web.service.reportprogress;
|
|
|
|
|
+
|
|
|
|
|
+import cn.iocoder.byzs.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
|
|
+import cn.iocoder.byzs.module.bjdx.controller.admin.coursetype.vo.CourseTypeListReqVO;
|
|
|
|
|
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.coursetype.CourseTypeDO;
|
|
|
|
|
+import cn.iocoder.byzs.module.bjdx.dal.dataobject.reportmanage.ReportManageDO;
|
|
|
|
|
+import cn.iocoder.byzs.module.bjdx.dal.mysql.coursetype.CourseTypeMapper;
|
|
|
|
|
+import cn.iocoder.byzs.module.bjdx.dal.mysql.reportmanage.ReportManageMapper;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.controller.admin.course.vo.WebCourseVO;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.controller.admin.reportprogress.vo.WebReportProgressDO;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.controller.admin.reportprogress.vo.WebReportProgressDTO;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.controller.admin.reportprogress.vo.WebReportProgressVO;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.dal.mysql.reportprogress.WebReportProgressMapper;
|
|
|
|
|
+import cn.iocoder.byzs.module.web.service.course.WebCourseServiceImpl;
|
|
|
|
|
+import jakarta.annotation.Resource;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+import org.springframework.validation.annotation.Validated;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.math.RoundingMode;
|
|
|
|
|
+import java.util.*;
|
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 评估报告-课程开课率 Service 实现类
|
|
|
|
|
+ *
|
|
|
|
|
+ * @author lyb
|
|
|
|
|
+ */
|
|
|
|
|
+@Service
|
|
|
|
|
+@Validated
|
|
|
|
|
+public class WebReportProgressServiceImpl {
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private WebReportProgressMapper progressMapper;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private ReportManageMapper reportManageMapper;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private CourseTypeMapper courseTypeMapper;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private WebCourseServiceImpl webCourseService;
|
|
|
|
|
+
|
|
|
|
|
+ public void saveReportProgress(WebReportProgressDO progress) {
|
|
|
|
|
+
|
|
|
|
|
+ LambdaQueryWrapperX<WebReportProgressDO> progressLambdaQueryWrapperX = new LambdaQueryWrapperX<WebReportProgressDO>()
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpUserId, progress.getBrpUserId())
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpType, progress.getBrpType())
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpNjId, progress.getBrpNjId());
|
|
|
|
|
+
|
|
|
|
|
+ switch (progress.getBrpType()) {
|
|
|
|
|
+ case "course":// 课程开课率
|
|
|
|
|
+ progressLambdaQueryWrapperX
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpCtId, progress.getBrpCtId())
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpCourseId, progress.getBrpCourseId());
|
|
|
|
|
+ WebReportProgressDO courseProgressDo = progressMapper.selectOne(progressLambdaQueryWrapperX);
|
|
|
|
|
+ if (courseProgressDo == null) {
|
|
|
|
|
+ progressMapper.insert(progress);
|
|
|
|
|
+ }else if (progress.getBrpProgress() > courseProgressDo.getBrpProgress()) {
|
|
|
|
|
+ courseProgressDo.setBrpProgress(progress.getBrpProgress());
|
|
|
|
|
+ progressMapper.updateById(courseProgressDo);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "courseQuest":// 课程互动率
|
|
|
|
|
+ progressLambdaQueryWrapperX
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpCtId, progress.getBrpCtId())
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpCourseId, progress.getBrpCourseId())
|
|
|
|
|
+ .eqIfPresent(WebReportProgressDO::getBrpCourseConfigId, progress.getBrpCourseConfigId());
|
|
|
|
|
+ WebReportProgressDO courseConfigProgressDo = progressMapper.selectOne(progressLambdaQueryWrapperX);
|
|
|
|
|
+
|
|
|
|
|
+ if (courseConfigProgressDo == null) {
|
|
|
|
|
+ progressMapper.insert(progress);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "aiCount":// ai问答次数
|
|
|
|
|
+ WebReportProgressDO aiCountProgressDo = progressMapper.selectOne(progressLambdaQueryWrapperX);
|
|
|
|
|
+
|
|
|
|
|
+ if (aiCountProgressDo == null) {
|
|
|
|
|
+ progressMapper.insert(progress);
|
|
|
|
|
+ }else {
|
|
|
|
|
+ aiCountProgressDo.setBrpProgress(aiCountProgressDo.getBrpProgress()+1);
|
|
|
|
|
+ progressMapper.updateById(aiCountProgressDo);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public WebReportProgressVO getReportProgress(WebReportProgressDO progress) {
|
|
|
|
|
+ //前端数据封装
|
|
|
|
|
+ WebReportProgressVO webReportProgressVO = new WebReportProgressVO();
|
|
|
|
|
+ List<WebReportProgressVO.ReportProgressVo> courseProgressVoList = new ArrayList<>();
|
|
|
|
|
+ List<WebReportProgressVO.ReportProgressVo> courseConfigProgressVoList = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ //年级下的课程列表
|
|
|
|
|
+ Map<String, List<Map<String, Integer>>> courseAllMap = new HashMap<>();
|
|
|
|
|
+ List<CourseTypeDO> courseTypeDOS = courseTypeMapper.selectList(new CourseTypeListReqVO().setCtParentId(Math.toIntExact(progress.getBrpNjId())).setCtTypeNode("1"));
|
|
|
|
|
+ courseTypeDOS.forEach(courseTypeDO -> {
|
|
|
|
|
+ List<WebCourseVO> courseVoList = webCourseService.getCourseVoByTypeId(courseTypeDO.getId());
|
|
|
|
|
+ List<Map<String, Integer>> courseCountMapList = new ArrayList<>();
|
|
|
|
|
+ courseVoList.forEach(webCourseVO -> {
|
|
|
|
|
+ Map<String, Integer> courseCountMap = new HashMap<>();
|
|
|
|
|
+ courseCountMap.put(webCourseVO.getCourseName(), webCourseVO.getCourseConfigList().size());
|
|
|
|
|
+ courseCountMapList.add(courseCountMap);
|
|
|
|
|
+ });
|
|
|
|
|
+ String sort = courseTypeDO.getCtTypeSort() > 9 ? "" : "0";
|
|
|
|
|
+ courseAllMap.put(sort + courseTypeDO.getCtTypeSort() + " " + courseTypeDO.getCtType(), courseCountMapList);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ //取进度
|
|
|
|
|
+ List<WebReportProgressDTO> webReportProgressDOList = progressMapper.selectProgres(progress);
|
|
|
|
|
+ Map<String, List<WebReportProgressDTO>> progressTypeMap = webReportProgressDOList.stream().collect(Collectors.groupingBy(WebReportProgressDTO::getProgressType));
|
|
|
|
|
+
|
|
|
|
|
+ courseAllMap.forEach((kcflName, courseMap)->{
|
|
|
|
|
+
|
|
|
|
|
+ //解析数据进度
|
|
|
|
|
+ progressTypeMap.keySet().forEach(progressType -> {
|
|
|
|
|
+ List<WebReportProgressDTO> progressDOList = progressTypeMap.get(progressType);
|
|
|
|
|
+ Map<String, List<WebReportProgressDTO>> progressKcflMap = progressDOList.stream().collect(Collectors.groupingBy(WebReportProgressDTO::getKcflName));
|
|
|
|
|
+ switch (progressType) {
|
|
|
|
|
+ case "course":
|
|
|
|
|
+
|
|
|
|
|
+ //计算课程大纲进度
|
|
|
|
|
+ progressKcflMap.forEach((kcflNameData, progressDTOList) -> {
|
|
|
|
|
+ //课程开课率
|
|
|
|
|
+ WebReportProgressVO.ReportProgressVo courseProgressVo = new WebReportProgressVO.ReportProgressVo();
|
|
|
|
|
+ courseProgressVo.setKcflName(kcflName);
|
|
|
|
|
+ double sum = progressDTOList.stream().collect(Collectors.summarizingDouble(WebReportProgressDTO::getProgress)).getSum();
|
|
|
|
|
+ courseProgressVo.setProgress(delTwo(sum / courseAllMap.get(kcflName).size()));
|
|
|
|
|
+ courseProgressVoList.add(courseProgressVo);
|
|
|
|
|
+ });
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "courseQuest":
|
|
|
|
|
+
|
|
|
|
|
+ //计算课程大纲进度
|
|
|
|
|
+ progressKcflMap.forEach((kcflNameData, progressDTOList) -> {
|
|
|
|
|
+ //课程互动率
|
|
|
|
|
+ WebReportProgressVO.ReportProgressVo courseConfigProgressVoConfig = new WebReportProgressVO.ReportProgressVo();
|
|
|
|
|
+ courseConfigProgressVoConfig.setKcflName(kcflName);
|
|
|
|
|
+
|
|
|
|
|
+ // 新增:计算courseMap所有value的总和(每个Map的value是课程配置数量)
|
|
|
|
|
+ int totalConfigCount = courseMap.stream()
|
|
|
|
|
+ .flatMap(map -> map.values().stream()) // 展开所有Map的value值
|
|
|
|
|
+ .mapToInt(Integer::intValue) // 转换为int流
|
|
|
|
|
+ .sum(); // 求和
|
|
|
|
|
+
|
|
|
|
|
+ double sum = progressDTOList.size();
|
|
|
|
|
+ // 注意:这里可能需要根据实际业务调整分母(示例保持原逻辑)
|
|
|
|
|
+ courseConfigProgressVoConfig.setProgress(delTwo(sum / totalConfigCount * 100)); // 调整为使用总和计算进度
|
|
|
|
|
+ courseConfigProgressVoList.add(courseConfigProgressVoConfig); // 修正集合添加对象
|
|
|
|
|
+ });
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
|
|
+ case "aiCount":
|
|
|
|
|
+ if (!progressDOList.isEmpty()) {
|
|
|
|
|
+ Double sum = progressDOList.stream().collect(Collectors.summarizingDouble(WebReportProgressDTO::getProgress)).getSum();
|
|
|
|
|
+ webReportProgressVO.setAiCount(sum.intValue());
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 原有总和计算逻辑(位置不变)
|
|
|
|
|
+ double courseProgressSum = courseProgressVoList.stream().collect(Collectors.summarizingDouble(WebReportProgressVO.ReportProgressVo::getProgress)).getSum();
|
|
|
|
|
+ double courseConfigProgressSum = courseConfigProgressVoList.stream().collect(Collectors.summarizingDouble(WebReportProgressVO.ReportProgressVo::getProgress)).getSum();
|
|
|
|
|
+ webReportProgressVO.setNjCourseProgress(delTwo(courseProgressSum / courseProgressVoList.size()));
|
|
|
|
|
+ webReportProgressVO.setNjCourseConfigProgress(delTwo(courseConfigProgressSum / courseConfigProgressVoList.size()));
|
|
|
|
|
+
|
|
|
|
|
+ // 按kcflName字段排序(自然顺序)
|
|
|
|
|
+ courseProgressVoList.sort(Comparator.comparing(WebReportProgressVO.ReportProgressVo::getKcflName));
|
|
|
|
|
+ courseConfigProgressVoList.sort(Comparator.comparing(WebReportProgressVO.ReportProgressVo::getKcflName));
|
|
|
|
|
+ webReportProgressVO.setReportCourseProgressList(courseProgressVoList);
|
|
|
|
|
+ webReportProgressVO.setReportCourseConfigProgressList(courseConfigProgressVoList);
|
|
|
|
|
+
|
|
|
|
|
+ //
|
|
|
|
|
+ Double njCourseProgress = webReportProgressVO.getNjCourseProgress();
|
|
|
|
|
+ Double njCourseConfigProgress = webReportProgressVO.getNjCourseConfigProgress();
|
|
|
|
|
+ Integer aiCount = webReportProgressVO.getAiCount();
|
|
|
|
|
+ List<ReportManageDO> reportManageDOList = reportManageMapper.selectList();
|
|
|
|
|
+ StringBuffer comment = new StringBuffer();
|
|
|
|
|
+ reportManageDOList.forEach(reportManageDO -> {
|
|
|
|
|
+ if (reportManageDO.getBrcReportAiCountMin() <= njCourseProgress && reportManageDO.getBrcReportAiCountMax() >= njCourseProgress){
|
|
|
|
|
+ comment.append(reportManageDO.getBrcReportComment());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (reportManageDO.getBrcReportQuestMin() <= njCourseConfigProgress && reportManageDO.getBrcReportQuestMax() >= njCourseConfigProgress){
|
|
|
|
|
+ comment.append(reportManageDO.getBrcReportComment());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (reportManageDO.getBrcReportAiCountMin() <= aiCount && reportManageDO.getBrcReportAiCountMax() >= aiCount){
|
|
|
|
|
+ comment.append(reportManageDO.getBrcReportComment());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ webReportProgressVO.setComment(comment.toString());
|
|
|
|
|
+ return webReportProgressVO;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public double delTwo(Double num){
|
|
|
|
|
+ if (Double.isInfinite(num))return 0;
|
|
|
|
|
+ BigDecimal two = new BigDecimal(num);
|
|
|
|
|
+ double newNum = two.setScale(0, RoundingMode.HALF_UP).doubleValue();
|
|
|
|
|
+ newNum = newNum > 100 ? 100 : newNum;
|
|
|
|
|
+ return newNum;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|