From 1f1c4f1340ea6769f9f137cd6f252b5eb483b0b2 Mon Sep 17 00:00:00 2001 From: "hhb@hotmail.com" Date: Tue, 6 May 2025 18:33:47 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E6=9B=B4=E6=96=B0=E7=8F=AD=E7=BA=A7?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/IndexController.java | 5 +- .../admin/service/AdminAppraiseService.java | 3 +- .../impl/AdminAppraiseServiceImpl.java | 47 +- .../impl/MoralEducationServiceImpl.java | 438 +++++++++++------- 4 files changed, 319 insertions(+), 174 deletions(-) diff --git a/src/main/java/cn/teammodel/controller/admin/controller/IndexController.java b/src/main/java/cn/teammodel/controller/admin/controller/IndexController.java index fb9e9a9..be23cfb 100644 --- a/src/main/java/cn/teammodel/controller/admin/controller/IndexController.java +++ b/src/main/java/cn/teammodel/controller/admin/controller/IndexController.java @@ -10,6 +10,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import java.util.List; @@ -35,8 +36,8 @@ public class IndexController { @PostMapping("latestRecord") @ApiOperation("查询时间范围最近评价(无参则当前周的所有记录)") - public R> latestRecord(@Valid @RequestBody TimeRangeDto timeRangeDto) { - List res = adminAppraiseService.conditionLatestRecord(timeRangeDto); + public R> latestRecord(@Valid @RequestBody TimeRangeDto timeRangeDto, HttpServletRequest request) { + List res = adminAppraiseService.conditionLatestRecord(timeRangeDto,request); return R.success(res); } diff --git a/src/main/java/cn/teammodel/controller/admin/service/AdminAppraiseService.java b/src/main/java/cn/teammodel/controller/admin/service/AdminAppraiseService.java index 20492c7..c8c002e 100644 --- a/src/main/java/cn/teammodel/controller/admin/service/AdminAppraiseService.java +++ b/src/main/java/cn/teammodel/controller/admin/service/AdminAppraiseService.java @@ -6,6 +6,7 @@ import cn.teammodel.model.entity.appraise.AchievementRule; import cn.teammodel.model.vo.admin.*; import cn.teammodel.model.vo.appraise.RecordVo; +import javax.servlet.http.HttpServletRequest; import java.util.List; /** @@ -18,7 +19,7 @@ public interface AdminAppraiseService { /** * 按时期分页获取最新的评价数据 */ - List conditionLatestRecord(TimeRangeDto timeRangeDto); + List conditionLatestRecord(TimeRangeDto timeRangeDto, HttpServletRequest request); List classRank(TimeRangeDto timeRangeDto); diff --git a/src/main/java/cn/teammodel/controller/admin/service/impl/AdminAppraiseServiceImpl.java b/src/main/java/cn/teammodel/controller/admin/service/impl/AdminAppraiseServiceImpl.java index d20bc53..330963b 100644 --- a/src/main/java/cn/teammodel/controller/admin/service/impl/AdminAppraiseServiceImpl.java +++ b/src/main/java/cn/teammodel/controller/admin/service/impl/AdminAppraiseServiceImpl.java @@ -4,6 +4,9 @@ import cn.teammodel.common.ErrorCode; import cn.teammodel.common.PK; import cn.teammodel.config.exception.ServiceException; import cn.teammodel.controller.admin.service.AdminAppraiseService; +import cn.teammodel.model.dto.admin.common.GroupDto; +import cn.teammodel.model.dto.admin.common.RGroupList; +import cn.teammodel.model.dto.admin.common.RMember; import cn.teammodel.repository.*; import cn.teammodel.model.dto.admin.appraise.TimeRangeDto; import cn.teammodel.model.dto.admin.appraise.UpdateAchievementRuleDto; @@ -18,18 +21,25 @@ import cn.teammodel.model.entity.school.Teacher; import cn.teammodel.model.vo.admin.*; import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.security.utils.SecurityUtil; +import cn.teammodel.utils.GroupUtil; import cn.teammodel.utils.RepositoryUtil; import cn.teammodel.utils.SchoolDateUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; import com.azure.cosmos.models.CosmosPatchOperations; import com.azure.cosmos.models.PartitionKey; import com.azure.spring.data.cosmos.core.query.CosmosPageRequest; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; +import javax.annotation.PostConstruct; import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; import java.time.*; import java.time.temporal.TemporalAdjusters; import java.util.*; @@ -56,6 +66,15 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService { @Resource private AppraiseRecordRepository appraiseRecordRepository; + @Autowired + private Environment env; // 非静态字段 + + private static Environment environment; // 静态字段 + @PostConstruct + public void init() { + AdminAppraiseServiceImpl.environment = env; // 在初始化时将非静态字段赋值给静态字段 + } + @Override public AppraiseIndexData getIndexData(TimeRangeDto timeRangeDto) { final int SLICE_SIZE = 100; @@ -137,7 +156,7 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService { } @Override - public List conditionLatestRecord(TimeRangeDto timeRangeDto) { + public List conditionLatestRecord(TimeRangeDto timeRangeDto, HttpServletRequest request) { Long startTime = timeRangeDto.getStartTime(); Long endTime = timeRangeDto.getEndTime(); String academicYearId = timeRangeDto.getAcademicYearId(); @@ -178,8 +197,34 @@ public class AdminAppraiseServiceImpl implements AdminAppraiseService { classIds ); + GroupDto groupDto = new GroupDto(); + groupDto.setIds(classIds); + groupDto.setSchoolId(schoolId); + String url = environment.getProperty("ies.server-url-group"); + Map groupId = GroupUtil.getGroupId(groupDto, new GroupUtil(environment), request, url); + List rGroupList = new ArrayList<>(); + for (Map.Entry entry : groupId.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (key.equals("groups")) { + String jsonGroups = JSON.toJSONString(value); + rGroupList = JSON.parseObject(jsonGroups, new TypeReference>() {}); + } + } + + if (res != null) { res = res.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).collect(Collectors.toList()); + for (RecordVo recordVo : res) { + List finalRGroupList = rGroupList; + String className = Optional.ofNullable(recordVo.getClassName()) + .orElseGet(() -> finalRGroupList.stream() + .filter(group -> group.getId().equals(recordVo.getClassId())) + .map(RGroupList::getName) + .findFirst() + .orElse("未知班级")); + recordVo.setClassName(className); + } } return res; diff --git a/src/main/java/cn/teammodel/controller/admin/service/impl/MoralEducationServiceImpl.java b/src/main/java/cn/teammodel/controller/admin/service/impl/MoralEducationServiceImpl.java index bd11338..2312f8c 100644 --- a/src/main/java/cn/teammodel/controller/admin/service/impl/MoralEducationServiceImpl.java +++ b/src/main/java/cn/teammodel/controller/admin/service/impl/MoralEducationServiceImpl.java @@ -4,7 +4,7 @@ import cn.teammodel.common.ErrorCode; import cn.teammodel.common.PK; import cn.teammodel.config.exception.ServiceException; import cn.teammodel.controller.admin.service.CommonService; -import cn.teammodel.controller.admin.service.MoralEducationService; +import cn.teammodel.controller.admin.service.LaborEducationService; import cn.teammodel.model.dto.admin.common.GCDto; import cn.teammodel.model.dto.admin.common.GroupDto; import cn.teammodel.model.dto.admin.common.RGroupList; @@ -32,6 +32,7 @@ import lombok.AllArgsConstructor; import lombok.Data; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; @@ -48,9 +49,10 @@ import java.time.ZoneId; import java.util.*; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import java.util.stream.IntStream; @Service -public class MoralEducationServiceImpl implements MoralEducationService { +public class MoralEducationServiceImpl implements LaborEducationService { @Resource private LessonRecordRepository lessonRecordRepository; @@ -90,7 +92,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { Long startTime = laborDto.getStartTime(); Long endTime = laborDto.getEndTime(); String subjectId = laborDto.getSubjectId(); - String tmdId = laborDto.getTmdId(); + //String tmdId = laborDto.getTmdId(); String grade = laborDto.getGrade(); String periodId = laborDto.getPeriodId(); String academicYearId = laborDto.getAcademicYearId(); @@ -209,13 +211,13 @@ public class MoralEducationServiceImpl implements MoralEducationService { classScoreRate = calculateKnowledgeScoreRateForClass(laborDto.getClassId(), examResults, knowledgeMap, appraise, point,res,request); } if (laborDto.getGrade() != null) { - gradeScoreRate = calculateKnowledgeScoreForGrade(laborDto.getGrade(), examResults, knowledgeMap,appraise, point,res,gradeAndClassVos); + gradeScoreRate = calculateKnowledgeScoreForGrade(laborDto.getGrade(), examResults, knowledgeMap,appraise, point,res,gradeAndClassVos,request); } - Map schoolScoreRate = calculateKnowledgeScoreForSchool(examResults, knowledgeMap,appraise, point,res,period,gradeAndClassVos); + Map schoolScoreRate = calculateKnowledgeScoreForSchool(examResults, knowledgeMap,appraise, point,res,period,gradeAndClassVos,request); resMap.put("gradeScoreRate", gradeScoreRate); resMap.put("classScoreRate", classScoreRate); resMap.put("schoolScoreRate", schoolScoreRate); - List> scores = calculateScoresWithDetails(res, appraise); + List> scores = calculateScoresWithDetails(res, appraise, request); List> students = combineScoresWithExamResults(scores,examResults,knowledgeMap,point,knowledgeBlockToPointsMap); resMap.put("scores", students); } @@ -239,6 +241,79 @@ public class MoralEducationServiceImpl implements MoralEducationService { } return resMap; } + @Override + public Map getExamDetails(LaborDto laborDto, HttpServletRequest request) { + Map resMap = new HashMap<>(); + try { + List examResults = new ArrayList<>(); + if (!laborDto.getExamId().isEmpty()) { + Map>> knowledgeMap = new HashMap<>(); + Map> points = new HashMap<>(); + + // 1. 查询考试信息 + Exam exam = examRepository.findExamById(String.format(PK.EXAM, laborDto.getTmdId()), laborDto.getExamId()).get(0); + if (exam.getPapers() != null && !exam.getPapers().isEmpty()) { + knowledgeMap.put(exam.getId(), exam.getPapers().get(0).getKnowledge()); + points.put(exam.getId(), exam.getPapers().get(0).getPoint()); + } + + // 2. 查询考试结果 + examResults = examClassResultRepository.findById( + String.format(PK.CLASS_RESULT, laborDto.getCode()), + laborDto.getClassId(), + laborDto.getExamId() + ); + + // 3. 查询知识块-知识点映射关系 + Appraise appraise = appraiseRepository.findAppraiseBySchoolIdAndPeriodIdAndCode( + laborDto.getCode(), + laborDto.getPeriodId(), + PK.PK_APPRAISE + ); + appraise = evaluationService.buildTree(appraise); + Map> knowledgeBlockToPointsMap = getKnowledgeBlockToPointsMap(appraise); + + // 4. 计算每个知识点的得分(调用 calculateStudentScoreRates) + Map knowledgeTotalScore = new HashMap<>(); + if (!examResults.isEmpty()) { + // 假设计算所有学生的平均分(或指定某个学生) + String studentId = laborDto.getStudentId(); // 如果传入了学生ID + calculateStudentScoreRates(studentId, examResults, knowledgeMap, points, knowledgeTotalScore); + } else { + // 如果没有考试数据,默认所有知识点60分 + knowledgeMap.values().stream() + .flatMap(List::stream) + .flatMap(List::stream) + .forEach(knowledge -> knowledgeTotalScore.put(knowledge, 60.0)); + } + + // 5. 按知识块分组,计算每个知识块下知识点的得分 + List> knowledgeBlockScores = new ArrayList<>(); + for (Map.Entry> entry : knowledgeBlockToPointsMap.entrySet()) { + String blockName = entry.getKey(); + List knowledgePoints = entry.getValue(); + + List> pointScores = new ArrayList<>(); + for (String point : knowledgePoints) { + double score = knowledgeTotalScore.getOrDefault(point, 60.0); // 默认60分 + pointScores.add(new HashMap() {{ + put("name", point); + put("score", score); + }}); + } + knowledgeBlockScores.add(new HashMap() {{ + put("name", blockName); + put("children", pointScores); + }}); + } + + resMap.put("data", knowledgeBlockScores); + } + } catch (Exception e) { + throw new ServiceException(ErrorCode.SYSTEM_ERROR.getCode(), "数据查询异常"); + } + return resMap; + } public List> combineScoresWithExamResults( List> scores, @@ -380,7 +455,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { } - public static List> calculateScoresWithDetails(List res, Appraise appraise) { + public static List> calculateScoresWithDetails(List res, Appraise appraise,HttpServletRequest request) { // 1. 构建知识点到知识块的映射 (一个知识块对应多个知识点) Map> knowledgeBlockToPointsMap = getKnowledgeBlockToPointsMap(appraise); @@ -407,10 +482,47 @@ public class MoralEducationServiceImpl implements MoralEducationService { Map> studentScores = new HashMap<>(); Map>> studentAppraises = new HashMap<>(); // 存储每个学生的评价记录 + // 将 classId 转换为 List + //获取res中的classId集合 + List classIds = res.stream() + .map(RecordVo::getClassId) + .distinct() + .collect(Collectors.toList()); + //List classIds = Collections.singletonList(classId); + GroupDto groupDto = new GroupDto(); + groupDto.setIds(classIds); + groupDto.setSchoolId(appraise.getSchoolId()); + String url = environment.getProperty("ies.server-url-group"); + Map groupId = GroupUtil.getGroupId(groupDto, new GroupUtil(environment), request, url); + List rGroupList = new ArrayList<>(); + List rMembers = new ArrayList<>(); + for (Map.Entry entry : groupId.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (key.equals("groups")) { + String jsonGroups = JSON.toJSONString(value); + rGroupList = JSON.parseObject(jsonGroups, new TypeReference>() {}); + } + if (key.equals("members")) { + String jsonGroups = JSON.toJSONString(value); + rMembers = JSON.parseObject(jsonGroups, new TypeReference>() {}); + } + } + for (RecordVo record : res) { String studentId = record.getTargetId(); // 学生 ID String studentName = record.getTargetName(); // 学生名称 - String className = record.getClassName(); // 班级名称 + String className = ""; + if (record.getClassName() == null) { + className = rGroupList.stream() + .filter(rGroupList1 -> rGroupList1.getId().equals(record.getClassId())) + .findFirst() + .map(RGroupList::getName) + .orElse("未知班级"); // 如果未找到则返回默认值 "未知班级" + }else { + className = record.getClassName(); + } + String appraiseName = record.getAppraiseName(); // 评价内容 boolean isPraise = record.isPraise(); // 是否为优点 @@ -536,22 +648,43 @@ public class MoralEducationServiceImpl implements MoralEducationService { Map parentNodeScoreCount = new HashMap<>(); // 记录每个父节点的知识点数量 for (MoralEducationServiceImpl.KnowledgeScoreRate scoreRate : studentScoreRates) { - AppraiseTreeNode node = findKnowledgeNode(appraise.getNodes(), scoreRate.getKnowledge()); + String knowledge = scoreRate.getKnowledge(); + AppraiseTreeNode node = findKnowledgeNode(appraise.getNodes(), knowledge); + + // 1. 查找知识点所属的知识块(假设通过knowledgeMap映射) + String block = findKnowledgeBlock(knowledgeMap, knowledge); // 自定义方法:从knowledgeMap中获取知识点所属的知识块 + + // 2. 查找知识块对应的父节点 + AppraiseTreeNode parentNode = null; + if (block != null) { + parentNode = findParentNodeByBlockName(appraise.getNodes(), block); // 自定义方法:按知识块名称查找父节点 + } + + // 3. 处理匹配到节点的情况 if (node != null) { - AppraiseTreeNode parentNode = findParentNode(appraise.getNodes(), node.getId()); - if (parentNode != null) { - // 累加父节点的得分 - double currentScore = parentNodeScoreRates.getOrDefault(parentNode.getName(), 0.0); - parentNodeScoreRates.put(parentNode.getName(), currentScore + scoreRate.getScoreRate()); - - // 累加父节点的知识点数量 - int currentCount = parentNodeScoreCount.getOrDefault(parentNode.getName(), 0); - parentNodeScoreCount.put(parentNode.getName(), currentCount + 1); + parentNode = findParentNode(appraise.getNodes(), node.getId()); + } else { + // 未匹配知识点:默认60分,归入其所属知识块的父节点 + double defaultScore = 60.0; + if (parentNode == null) { + // 若知识块无对应父节点,归入全局默认块 + parentNodeScoreRates.merge("默认块", defaultScore, Double::sum); + parentNodeScoreCount.merge("默认块", 1, Integer::sum); } else { - // 如果没有找到父节点,直接使用当前知识点的得分 - parentNodeScoreRates.put(node.getName(), scoreRate.getScoreRate()); - parentNodeScoreCount.put(node.getName(), 1); + // 归入知识块对应的父节点 + parentNodeScoreRates.merge(parentNode.getName(), defaultScore, Double::sum); + parentNodeScoreCount.merge(parentNode.getName(), 1, Integer::sum); } + continue; // 跳过后续匹配逻辑 + } + + // 4. 累加得分到父节点(原有逻辑) + if (parentNode != null) { + parentNodeScoreRates.merge(parentNode.getName(), scoreRate.getScoreRate(), Double::sum); + parentNodeScoreCount.merge(parentNode.getName(), 1, Integer::sum); + } else { + parentNodeScoreRates.put(node.getName(), scoreRate.getScoreRate()); + parentNodeScoreCount.put(node.getName(), 1); } } @@ -583,6 +716,30 @@ public class MoralEducationServiceImpl implements MoralEducationService { return parentNodeScoreRates; } + // 从knowledgeMap中查找知识点所属的知识块 + private static String findKnowledgeBlock(Map>> knowledgeMap, String knowledge) { + for (Map.Entry>> entry : knowledgeMap.entrySet()) { + for (List subList : entry.getValue()) { + if (subList.contains(knowledge)) { + return entry.getKey(); + } + } + } + return null; + } + + // 按知识块名称查找父节点 + private static AppraiseTreeNode findParentNodeByBlockName(List nodes, String blockName) { + for (AppraiseTreeNode node : nodes) { + if (node.getName().equals(blockName)) { + return node; + } + AppraiseTreeNode found = findParentNodeByBlockName(node.getChildren(), blockName); + if (found != null) return found; + } + return null; + } + /** * 计算班级每个学生知识点得分率,并返回每个学生所属节点的父节点得分率 @@ -655,29 +812,44 @@ public class MoralEducationServiceImpl implements MoralEducationService { if (examResults != null && !examResults.isEmpty()) { // 遍历班级中的每个学生 for (ExamClassResult examResult : examResults) { - if (!examResult.getInfo().getId().equals(classId)) continue; - List statuses = examResult.getStatus(); - for (int i = 0; i < examResult.getStudentIds().size(); i++) { - String studentId = examResult.getStudentIds().get(i); - String name = rMembers.stream() - .filter(member -> member.getId().equals(studentId)) - .findFirst() - .map(RMember::getName) - .orElse("未知"); - int status = statuses.get(i); - if (status == 1) continue; - - // 正确获取已转换的客观分数(无需二次截断) - Map scoreRates = calculateKnowledgeScoreRateForStudent( - studentId, examResults, knowledgeMap, appraise, points - ); - studentScoreRates.put(name, scoreRates); - - // 累加班级整体得分率 - for (Map.Entry entry : scoreRates.entrySet()) { - classScoreRates.put(entry.getKey(), classScoreRates.getOrDefault(entry.getKey(), 0.0) + entry.getValue()); + if (!examResult.getInfo().getId().equals(classId)){ + // 无考试数据时,初始化所有学生的默认分数为60 + if (groupList != null) { + for (RMember member : groupList.members) { + String studentId = member.getId(); + String studentName = studentIdToName.getOrDefault(studentId, "未知学生"); + Map defaultScores = new HashMap<>(); + for (String block : knowledgeBlocks) { + defaultScores.put(block, 84.0); // 初始化为60分 + } + studentScoreRates.put(studentName, defaultScores); + } + } + }else{ + List statuses = examResult.getStatus(); + for (int i = 0; i < examResult.getStudentIds().size(); i++) { + String studentId = examResult.getStudentIds().get(i); + String name = rMembers.stream() + .filter(member -> member.getId().equals(studentId)) + .findFirst() + .map(RMember::getName) + .orElse("未知"); + int status = statuses.get(i); + if (status == 1) continue; + + // 正确获取已转换的客观分数(无需二次截断) + Map scoreRates = calculateKnowledgeScoreRateForStudent( + studentId, examResults, knowledgeMap, appraise, points + ); + studentScoreRates.put(name, scoreRates); + + // 累加班级整体得分率 + for (Map.Entry entry : scoreRates.entrySet()) { + classScoreRates.put(entry.getKey(), classScoreRates.getOrDefault(entry.getKey(), 0.0) + entry.getValue()); + } } } + } }else { // 无考试数据时,初始化所有学生的默认分数为60 @@ -687,7 +859,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { String studentName = studentIdToName.getOrDefault(studentId, "未知学生"); Map defaultScores = new HashMap<>(); for (String block : knowledgeBlocks) { - defaultScores.put(block, 60.0); // 初始化为60分 + defaultScores.put(block, 84.0); // 初始化为60分 } studentScoreRates.put(studentName, defaultScores); } @@ -695,7 +867,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { } // 2. 获取班级所有学生的主观分数(次数) - List> subjectiveScoresList = calculateScoresWithDetails(res, appraise); + List> subjectiveScoresList = calculateScoresWithDetails(res, appraise,request); // 3. 将主观次数转换为0-100分数 Map> subjectiveScores = new HashMap<>(); @@ -833,7 +1005,6 @@ public class MoralEducationServiceImpl implements MoralEducationService { Map>> knowledgeMap, Map> points, Map knowledgeTotalScore) { - Map knowledgeTotalAverage = new HashMap<>(); Map knowledgeExamCount = new HashMap<>(); @@ -961,7 +1132,8 @@ public class MoralEducationServiceImpl implements MoralEducationService { Appraise appraise, Map> points, List res, - List gradeAndClassVos) { + List gradeAndClassVos, + HttpServletRequest request) { // 1. 获取年级所有班级的客观分数 Map> classScores = new HashMap<>(); @@ -984,7 +1156,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { .collect(Collectors.toList()); // 2. 获取年级所有学生的主观分数(次数) - List> subjectiveScoresList = calculateScoresWithDetails(res, appraise); + List> subjectiveScoresList = calculateScoresWithDetails(res, appraise,request); // 3. 将主观次数转换为0-100分数,并收集学生班级信息 Map> subjectiveScores = new HashMap<>(); @@ -1174,7 +1346,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { Map> points, List res, List period, - List gradeAndClassVos) { + List gradeAndClassVos,HttpServletRequest request) { // 1. 初始化数据结构 Map> gradeScores = new HashMap<>(); @@ -1188,7 +1360,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { int index = 0; for (String gradeId : gradeIds) { Map gradeResult = calculateKnowledgeScoreForGrade( - String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos + String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos,request ); // 2.1 提取年级平均分 @@ -1328,6 +1500,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { return null; // 未找到父节点 } + //获取每月各个知识库综合得分以及整体得分内容 public Map>> getStudentMonthlyScores(LaborDto laborDto,HttpServletRequest request) { // 1. 获取基础信息 @@ -1385,7 +1558,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { laborDto.getAcademicYearId(), laborDto.getClassId(), laborDto.getStudentId(), - "德育" + "劳育" ); //表扬的次数 rightCount = (int) res.stream().filter(RecordVo::isPraise).count(); @@ -1402,7 +1575,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { List targetStudents = laborDto.getClassId() != null ? classStudentIds : Collections.singletonList(studentId); - Map> monthlyResults = getMonthlyExamResults( + Map> monthlyResults = getMonthlyExamResults( schoolId, laborDto.getClassId(), exams, records, examKnowledgeMap, points, targetStudents // 传入目标学生列表 ); @@ -1465,81 +1638,6 @@ public class MoralEducationServiceImpl implements MoralEducationService { ); } - @Override - public Map getExamDetails(LaborDto laborDto, HttpServletRequest request) { - - Map resMap = new HashMap<>(); - try { - List examResults = new ArrayList<>(); - if (!laborDto.getExamId().isEmpty()) { - Map>> knowledgeMap = new HashMap<>(); - Map> points = new HashMap<>(); - - // 1. 查询考试信息 - Exam exam = examRepository.findExamById(String.format(PK.EXAM, laborDto.getTmdId()), laborDto.getExamId()).get(0); - if (exam.getPapers() != null && !exam.getPapers().isEmpty()) { - knowledgeMap.put(exam.getId(), exam.getPapers().get(0).getKnowledge()); - points.put(exam.getId(), exam.getPapers().get(0).getPoint()); - } - - // 2. 查询考试结果 - examResults = examClassResultRepository.findById( - String.format(PK.CLASS_RESULT, laborDto.getCode()), - laborDto.getClassId(), - laborDto.getExamId() - ); - - // 3. 查询知识块-知识点映射关系 - Appraise appraise = appraiseRepository.findAppraiseBySchoolIdAndPeriodIdAndCode( - laborDto.getCode(), - laborDto.getPeriodId(), - PK.PK_APPRAISE - ); - appraise = evaluationService.buildTree(appraise); - Map> knowledgeBlockToPointsMap = getKnowledgeBlockToPointsMap(appraise); - - // 4. 计算每个知识点的得分(调用 calculateStudentScoreRates) - Map knowledgeTotalScore = new HashMap<>(); - if (!examResults.isEmpty()) { - // 假设计算所有学生的平均分(或指定某个学生) - String studentId = laborDto.getStudentId(); // 如果传入了学生ID - calculateStudentScoreRates(studentId, examResults, knowledgeMap, points, knowledgeTotalScore); - } else { - // 如果没有考试数据,默认所有知识点60分 - knowledgeMap.values().stream() - .flatMap(List::stream) - .flatMap(List::stream) - .forEach(knowledge -> knowledgeTotalScore.put(knowledge, 60.0)); - } - - // 5. 按知识块分组,计算每个知识块下知识点的得分 - List> knowledgeBlockScores = new ArrayList<>(); - for (Map.Entry> entry : knowledgeBlockToPointsMap.entrySet()) { - String blockName = entry.getKey(); - List knowledgePoints = entry.getValue(); - - List> pointScores = new ArrayList<>(); - for (String point : knowledgePoints) { - double score = knowledgeTotalScore.getOrDefault(point, 60.0); // 默认60分 - pointScores.add(new HashMap() {{ - put("name", point); - put("score", score); - }}); - } - knowledgeBlockScores.add(new HashMap() {{ - put("name", blockName); - put("children", pointScores); - }}); - } - - resMap.put("data", knowledgeBlockScores); - } - } catch (Exception e) { - throw new ServiceException(ErrorCode.SYSTEM_ERROR.getCode(), "数据查询异常"); - } - return resMap; - } - // 新增方法:添加综合得分 private List> addOverallScore( @@ -1614,12 +1712,12 @@ public class MoralEducationServiceImpl implements MoralEducationService { .collect(Collectors.toList()); } - private Map> getMonthlyExamResults( + private Map> getMonthlyExamResults( String schoolId, String classId, List exams, List records, Map>> examKnowledgeMap, Map> points, List studentIds) { // 新增studentIds参数 - Map> monthlyResults = new HashMap<>(); + Map> monthlyResults = new HashMap<>(); if (classId == null) { exams.forEach(exam -> { @@ -1641,7 +1739,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { .filter(studentIds::contains) // 仅处理班级学生 .forEach(studentId -> { monthlyResults.computeIfAbsent(month, k -> new ArrayList<>()) - .add(new MoralEducationServiceImpl.ExamResultWrapper( + .add(new ExamResultWrapper( exam.getId(), result, knowledge, @@ -1672,7 +1770,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { .filter(studentIds::contains) // 仅处理班级学生 .forEach(studentId -> { monthlyResults.computeIfAbsent(month, k -> new ArrayList<>()) - .add(new MoralEducationServiceImpl.ExamResultWrapper( + .add(new ExamResultWrapper( exam.getId(), result, knowledge, @@ -1692,7 +1790,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { private Map>> processMonthlyData( List records,List res,int rightCount,int wrongCount, List targetStudentIds, - Map> monthlyResults, + Map> monthlyResults, Map> knowledgeBlockMap, Set months, Map> blockMonthlyCounts) { @@ -1712,11 +1810,11 @@ public class MoralEducationServiceImpl implements MoralEducationService { List> scoreList = new ArrayList<>(); // 按学生分组考试结果 - Map> studentResults = monthlyResults + Map> studentResults = monthlyResults .getOrDefault(month, Collections.emptyList()) .stream() .filter(wrapper -> targetStudentIds.contains(wrapper.getStudentId())) - .collect(Collectors.groupingBy(MoralEducationServiceImpl.ExamResultWrapper::getStudentId)); + .collect(Collectors.groupingBy(ExamResultWrapper::getStudentId)); // 初始化知识块总分计数器 Map blockTotalScores = new HashMap<>(); @@ -1724,9 +1822,9 @@ public class MoralEducationServiceImpl implements MoralEducationService { // 遍历所有目标学生 targetStudentIds.forEach(studentId -> { - List wrappers = studentResults.getOrDefault(studentId, Collections.emptyList()); + List wrappers = studentResults.getOrDefault(studentId, Collections.emptyList()); List examResults = wrappers.stream() - .map(MoralEducationServiceImpl.ExamResultWrapper::getResult) + .map(ExamResultWrapper::getResult) .collect(Collectors.toList()); // 1. 计算知识点得分(保留原始逻辑) @@ -1734,11 +1832,11 @@ public class MoralEducationServiceImpl implements MoralEducationService { studentId, examResults, wrappers.stream().collect(Collectors.toMap( - MoralEducationServiceImpl.ExamResultWrapper::getExamId, - MoralEducationServiceImpl.ExamResultWrapper::getKnowledge)), + ExamResultWrapper::getExamId, + ExamResultWrapper::getKnowledge)), wrappers.stream().collect(Collectors.toMap( - MoralEducationServiceImpl.ExamResultWrapper::getExamId, - MoralEducationServiceImpl.ExamResultWrapper::getPoints)) + ExamResultWrapper::getExamId, + ExamResultWrapper::getPoints)) ); // 2. 计算每个知识块的客观得分(新增关键逻辑) @@ -1971,14 +2069,14 @@ public class MoralEducationServiceImpl implements MoralEducationService { public Map getStudentSemesterScores(LaborDto laborDto,HttpServletRequest request) { // 1. 获取学期配置 List semesters = schoolRepository.findSemestersById(laborDto.getCode(), laborDto.getPeriodId()); - List configs = new ArrayList<>(); + List configs = new ArrayList<>(); for (School.Semester semester : semesters) { - configs.add(new MoralEducationServiceImpl.SemesterConfig(semester.getName(), semester.getStart(), semester.getMonth(), semester.getDay(), semester.getId())); + configs.add(new SemesterConfig(semester.getName(), semester.getStart(), semester.getMonth(), semester.getDay(), semester.getId())); } // 2. 计算学期时间范围 - Map periods = calculateSemesters(configs); - MoralEducationServiceImpl.SemesterPeriod current = periods.get("current"); - MoralEducationServiceImpl.SemesterPeriod last = periods.get("last"); + Map periods = calculateSemesters(configs); + SemesterPeriod current = periods.get("current"); + SemesterPeriod last = periods.get("last"); // 学生数据处理 Map studentResult = Collections.emptyMap(); @@ -2012,8 +2110,8 @@ public class MoralEducationServiceImpl implements MoralEducationService { } private Map processIndividual(LaborDto dto, - MoralEducationServiceImpl.SemesterPeriod current, - MoralEducationServiceImpl.SemesterPeriod last, + SemesterPeriod current, + SemesterPeriod last, HttpServletRequest request) { // 原有学生处理逻辑 Map currentData = processSemesterData(dto, current, request, true, false); @@ -2022,8 +2120,8 @@ public class MoralEducationServiceImpl implements MoralEducationService { } private Map processClass(LaborDto dto, - MoralEducationServiceImpl.SemesterPeriod current, - MoralEducationServiceImpl.SemesterPeriod last, + SemesterPeriod current, + SemesterPeriod last, HttpServletRequest request) { // 克隆DTO并清除学生ID LaborDto classDto = new LaborDto(); @@ -2123,12 +2221,12 @@ public class MoralEducationServiceImpl implements MoralEducationService { } // 核心学期计算逻辑 - private Map calculateSemesters(List semesters) { + private Map calculateSemesters(List semesters) { LocalDate now = LocalDate.now(); int currentYear = now.getYear(); // 1. 确定学年起始学期 - MoralEducationServiceImpl.SemesterConfig startSemester = semesters.stream() + SemesterConfig startSemester = semesters.stream() .filter(s -> s.start == 1) .findFirst() .orElseThrow(() -> new IllegalArgumentException("未配置起始学期")); @@ -2138,51 +2236,51 @@ public class MoralEducationServiceImpl implements MoralEducationService { int academicYear = calculateAcademicYear(startSemester, LocalDate.now()); // 3. 生成当前学年学期 - List currentYearSemesters = generateYearSemesters( + List currentYearSemesters = generateYearSemesters( semesters, academicYear, startSemester); // 4. 确定当前学期 - MoralEducationServiceImpl.SemesterPeriod current = currentYearSemesters.stream() + SemesterPeriod current = currentYearSemesters.stream() .filter(sp -> !now.isBefore(sp.startDate) && !now.isAfter(sp.endDate)) .findFirst() .orElse(null); // 5. 确定上学期 - MoralEducationServiceImpl.SemesterPeriod last = findLastSemester(current, semesters, academicYear, startSemester); + SemesterPeriod last = findLastSemester(current, semesters, academicYear, startSemester); - return new HashMap() {{ + return new HashMap() {{ put("current", current); put("last", last); }}; } // 增强学术年度计算方法 - private int calculateAcademicYear(MoralEducationServiceImpl.SemesterConfig startSemester, LocalDate currentDate) { + private int calculateAcademicYear(SemesterConfig startSemester, LocalDate currentDate) { int currentYear = currentDate.getYear(); int currentMonth = currentDate.getMonthValue(); return (currentMonth < startSemester.month) ? currentYear -1 : currentYear; } // 生成学年学期时间范围 - private List generateYearSemesters(List semesters, - int academicYear, - MoralEducationServiceImpl.SemesterConfig startSemester) { - List periods = new ArrayList<>(); + private List generateYearSemesters(List semesters, + int academicYear, + SemesterConfig startSemester) { + List periods = new ArrayList<>(); // 1. 生成各学期开始日期 - for (MoralEducationServiceImpl.SemesterConfig sc : semesters) { + for (SemesterConfig sc : semesters) { int year = academicYear; if (sc.month < startSemester.month) { year += 1; // 跨年学期(如 2024 学年下学期是 2025 年 2 月) } LocalDate startDate = LocalDate.of(year, sc.month, sc.day); - periods.add(new MoralEducationServiceImpl.SemesterPeriod(sc.name, startDate, null)); + periods.add(new SemesterPeriod(sc.name, startDate, null)); } - periods.sort(Comparator.comparing(MoralEducationServiceImpl.SemesterPeriod::getStartDate)); + periods.sort(Comparator.comparing(SemesterPeriod::getStartDate)); // 2. 计算结束日期 for (int i = 0; i < periods.size(); i++) { - MoralEducationServiceImpl.SemesterPeriod curr = periods.get(i); + SemesterPeriod curr = periods.get(i); if (i < periods.size() - 1) { // 非最后学期:下一学期开始前 1 天 @@ -2205,13 +2303,13 @@ public class MoralEducationServiceImpl implements MoralEducationService { } // 查找上学期(含跨学年处理) - private MoralEducationServiceImpl.SemesterPeriod findLastSemester(MoralEducationServiceImpl.SemesterPeriod current, - List semesters, - int academicYear, - MoralEducationServiceImpl.SemesterConfig startSemester) { + private SemesterPeriod findLastSemester(SemesterPeriod current, + List semesters, + int academicYear, + SemesterConfig startSemester) { if (current == null) return null; - List currentYearSemesters = generateYearSemesters( + List currentYearSemesters = generateYearSemesters( semesters, academicYear, startSemester); int index = currentYearSemesters.indexOf(current); @@ -2219,7 +2317,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { return currentYearSemesters.get(index-1); } else { // 获取去年最后一个学期 - List lastYear = generateYearSemesters( + List lastYear = generateYearSemesters( semesters, academicYear-1, startSemester); return lastYear.isEmpty() ? null : lastYear.get(lastYear.size()-1); } @@ -2227,7 +2325,7 @@ public class MoralEducationServiceImpl implements MoralEducationService { // 处理学期数据 private Map processSemesterData(LaborDto laborDto, - MoralEducationServiceImpl.SemesterPeriod semester, + SemesterPeriod semester, HttpServletRequest request, boolean isCurrent, boolean isClassMod) {