update 调整算法和返回内容

develop
hhb@hotmail.com 1 month ago
parent dfadaf37bc
commit e47903b31d

@ -18,6 +18,7 @@ import cn.teammodel.model.entity.common.ExamClassResult;
import cn.teammodel.model.entity.school.ClassInfo; import cn.teammodel.model.entity.school.ClassInfo;
import cn.teammodel.model.entity.school.LessonRecord; import cn.teammodel.model.entity.school.LessonRecord;
import cn.teammodel.model.entity.school.School; import cn.teammodel.model.entity.school.School;
import cn.teammodel.model.vo.Common.ExamVo;
import cn.teammodel.model.vo.admin.GradeAndClassVo; import cn.teammodel.model.vo.admin.GradeAndClassVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import cn.teammodel.repository.*; import cn.teammodel.repository.*;
@ -146,7 +147,7 @@ public class LaborEducationServiceImpl implements LaborEducationService {
} }
//examIds.add("c26e5766-597f-45b3-91ad-19e76426323b"); //examIds.add("c26e5766-597f-45b3-91ad-19e76426323b");
//获取所有课程下的课中活动 //获取所有课程下的课中活动
List<Exam> exams = new ArrayList<>(); List<ExamVo> exams = new ArrayList<>();
if (!recordIds.isEmpty()) { if (!recordIds.isEmpty()) {
exams = examRepository.findExamsByIds(laborDto.getSource(),recordIds); exams = examRepository.findExamsByIds(laborDto.getSource(),recordIds);
exams = exams.stream() exams = exams.stream()
@ -155,7 +156,17 @@ public class LaborEducationServiceImpl implements LaborEducationService {
} }
Map<String, List<List<String>>> knowledgeMap = new HashMap<>(); Map<String, List<List<String>>> knowledgeMap = new HashMap<>();
Map<String, List<Double>> point = new HashMap<>(); Map<String, List<Double>> point = new HashMap<>();
for (Exam exam : exams) { List<String> examIds = new ArrayList<>();
for (ExamVo exam : exams) {
examIds.add(exam.getId());
String lessonRecordId = exam.getLessonRecordId(); // 获取 lessonRecordId
Optional<LessonRecord> recordOptional = records.stream()
.filter(record -> record.getId().equals(lessonRecordId))
.findFirst();
if (recordOptional.isPresent()) {
LessonRecord record = recordOptional.get();
exam.setRecordName(record.getName()); // 设置 recordName
}
if (exam.getPapers() != null) { if (exam.getPapers() != null) {
if (exam.getPapers().get(0).getKnowledge() != null) if (exam.getPapers().get(0).getKnowledge() != null)
{ {
@ -164,10 +175,6 @@ public class LaborEducationServiceImpl implements LaborEducationService {
} }
} }
} }
List<String> examIds = new ArrayList<>();
for (Exam exam : exams) {
examIds.add(exam.getId());
}
List<ExamClassResult> examResults = new ArrayList<>(); List<ExamClassResult> examResults = new ArrayList<>();
if (!examIds.isEmpty()) { if (!examIds.isEmpty()) {
examResults = examClassResultRepository.findAll(String.format(PK.CLASS_RESULT, laborDto.getCode()),examIds); examResults = examClassResultRepository.findAll(String.format(PK.CLASS_RESULT, laborDto.getCode()),examIds);
@ -272,21 +279,16 @@ public class LaborEducationServiceImpl implements LaborEducationService {
int count = entry.getValue(); // 次数 int count = entry.getValue(); // 次数
// 确保 count 不小于0 // 确保 count 不小于0
if (count < 0) { if (count < 0) {
count = 0; //次数永远不能为负数 count = 0;
} }
double maxCount = 50.0; // 最大次数(可根据实际情况调整) double maxCount = 50.0; // 调整此参数控制分数增长速率
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 // 使用反比例函数计算加分
double convertedScore; double additionalScore = 40.0 * ((double) count / (count + maxCount));
if (count > maxCount) { double convertedScore = 60.0 + additionalScore;
convertedScore = 100.0; // 超过最大次数,直接满分
} else { // 保留两位小数
// 计算额外加分占总40分的比例 convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
}
subjectiveTotal += convertedScore; subjectiveTotal += convertedScore;
// 获取对应知识块的客观成绩并转换为基于60分加分的分数 // 获取对应知识块的客观成绩并转换为基于60分加分的分数
@ -544,11 +546,18 @@ public class LaborEducationServiceImpl implements LaborEducationService {
} }
} }
// 计算父节点的平均得分 // 计算父节点的平均得分原始正确率转换为基于60分的加分制
parentNodeScoreRates.replaceAll((parentNodeName, totalScore) -> { parentNodeScoreRates.replaceAll((parentNodeName, totalScore) -> {
int count = parentNodeScoreCount.getOrDefault(parentNodeName, 1); int count = parentNodeScoreCount.getOrDefault(parentNodeName, 1);
double averageScore = totalScore / count; double averageScore = totalScore / count; // 原始正确率0-100的百分比
return Math.min(100.0, Math.max(60.0, averageScore)); // 确保得分在60-100之间
// 将原始正确率转换为以60分为基础的加分制正确率 × 40%
double correctRate = averageScore / 100.0; // 转为0-1的小数
double convertedScore = 60.0 + (correctRate * 40.0); // 最低60分最高100分
// 确保不超过100分并保留两位小数
convertedScore = Math.min(100.0, convertedScore);
return Double.parseDouble(String.format("%.2f", convertedScore));
}); });
// 初始化所有同层的父节点 // 初始化所有同层的父节点
@ -693,18 +702,18 @@ public class LaborEducationServiceImpl implements LaborEducationService {
for (Map.Entry<String, Integer> entry : scores.entrySet()) { for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey(); String block = entry.getKey();
int count = entry.getValue(); int count = entry.getValue();
double maxCount = 50.0; // 确保 count 不小于0
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 if (count < 0) {
double convertedScore; count = 0;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
} }
double maxCount = 50.0; // 调整此参数控制分数增长速率
// 使用反比例函数计算加分
double additionalScore = 40.0 * ((double) count / (count + maxCount));
double convertedScore = 60.0 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
convertedScores.put(block, convertedScore); convertedScores.put(block, convertedScore);
} }
@ -987,18 +996,18 @@ public class LaborEducationServiceImpl implements LaborEducationService {
for (Map.Entry<String, Integer> entry : scores.entrySet()) { for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey(); String block = entry.getKey();
int count = entry.getValue(); int count = entry.getValue();
double maxCount = 50.0; // 确保 count 不小于0
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 if (count < 0) {
double convertedScore; count = 0;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
} }
double maxCount = 50.0; // 调整此参数控制分数增长速率
// 使用反比例函数计算加分
double additionalScore = 40.0 * ((double) count / (count + maxCount));
double convertedScore = 60.0 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
convertedScores.put(block, convertedScore); convertedScores.put(block, convertedScore);
} }
subjectiveScores.put(studentId, convertedScores); subjectiveScores.put(studentId, convertedScores);
@ -1161,106 +1170,66 @@ public class LaborEducationServiceImpl implements LaborEducationService {
List<School.Period> period, List<School.Period> period,
List<GradeAndClassVo> gradeAndClassVos) { List<GradeAndClassVo> gradeAndClassVos) {
// 1. 获取全校所有年级的客观分数 // 1. 初始化数据结构
Map<String, Map<String, Double>> gradeScores = new HashMap<>(); Map<String, Map<String, Double>> gradeScores = new HashMap<>();
Map<String, Double> schoolScores = new HashMap<>(); Map<String, Double> schoolScores = new HashMap<>();
// 获取所有年级的 ID
List<String> gradeIds = period.stream() List<String> gradeIds = period.stream()
.flatMap(period1 -> period1.getGrades().stream()) .flatMap(period1 -> period1.getGrades().stream())
.collect(Collectors.toList()); .collect(Collectors.toList());
int totalClassCount = 0; // 新增:全校总班级数统计
// 2. 获取全校所有学生的主观分数(次数) // 2. 遍历所有年级
List<Map<String, Object>> subjectiveScoresList = calculateScoresWithDetails(res, appraise);
// 3. 将主观次数转换为0-100分数
//Map<String, Map<String, Double>> subjectiveScores = new HashMap<>();
for (Map<String, Object> studentScore : subjectiveScoresList) {
String studentId = (String) studentScore.get("studentId");
@SuppressWarnings("unchecked")
Map<String, Integer> scores = (Map<String, Integer>) studentScore.get("scores");
Map<String, Double> convertedScores = new HashMap<>();
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey();
int count = entry.getValue();
double maxCount = 50.0;
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分
double convertedScore;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
}
convertedScores.put(block, convertedScore);
}
//subjectiveScores.put(studentId, convertedScores);
}
// 4. 遍历所有年级
int index = 0; int index = 0;
for (String gradeId : gradeIds) { for (String gradeId : gradeIds) {
// 调用改造后的方法,返回的 gradeResult 包含列表结构的 gradeScores 和 classScores
Map<String, Object> gradeResult = calculateKnowledgeScoreForGrade( Map<String, Object> gradeResult = calculateKnowledgeScoreForGrade(
String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos
); );
// 1. 提取年级平均gradeScores // 2.1 提取年级平均分
List<Map<String, Object>> adjustedGradeScores = (List<Map<String, Object>>) gradeResult.get("gradeScores"); List<Map<String, Object>> adjustedGradeScores = (List<Map<String, Object>>) gradeResult.get("gradeScores");
Map<String, Double> gradeScoresInner = new HashMap<>(); Map<String, Double> gradeScoresInner = new HashMap<>();
// 遍历年级得分列表(通常只有一个元素)
for (Map<String, Object> gradeScoreEntry : adjustedGradeScores) { for (Map<String, Object> gradeScoreEntry : adjustedGradeScores) {
String gradeName = (String) gradeScoreEntry.get("gradeName");
List<Map<String, Object>> blocks = (List<Map<String, Object>>) gradeScoreEntry.get("blocks"); List<Map<String, Object>> blocks = (List<Map<String, Object>>) gradeScoreEntry.get("blocks");
// 将 blocks 转换为 Map<String, Double>
for (Map<String, Object> block : blocks) { for (Map<String, Object> block : blocks) {
String nodeName = (String) block.get("name"); String nodeName = (String) block.get("name");
Double score = (Double) block.get("score"); Double score = (Double) block.get("score");
gradeScoresInner.put(nodeName, score); gradeScoresInner.put(nodeName, score);
} }
} }
// 保存年级得分
gradeScores.put(gradeId, gradeScoresInner); gradeScores.put(gradeId, gradeScoresInner);
// 2. 累加全校得分总和(从 classScores 中提取) // 2.2 累加全校总分并统计班级数
List<Map<String, Object>> adjustedClassScores = (List<Map<String, Object>>) gradeResult.get("classScores"); List<Map<String, Object>> adjustedClassScores = (List<Map<String, Object>>) gradeResult.get("classScores");
totalClassCount += adjustedClassScores.size(); // 累加班级数
for (Map<String, Object> classScoreEntry : adjustedClassScores) { for (Map<String, Object> classScoreEntry : adjustedClassScores) {
List<Map<String, Object>> classBlocks = (List<Map<String, Object>>) classScoreEntry.get("blocks"); List<Map<String, Object>> classBlocks = (List<Map<String, Object>>) classScoreEntry.get("blocks");
// 遍历班级的每个评分项
for (Map<String, Object> block : classBlocks) { for (Map<String, Object> block : classBlocks) {
String nodeName = (String) block.get("name"); String nodeName = (String) block.get("name");
Double score = (Double) block.get("score"); Double score = (Double) block.get("score");
schoolScores.put(nodeName, schoolScores.getOrDefault(nodeName, 0.0) + score); schoolScores.put(nodeName, schoolScores.getOrDefault(nodeName, 0.0) + score);
} }
} }
index++; index++;
} }
// 5. 计算全校的平均得 // 3. 计算全校平均
if (gradeIds.size() == 1) { if (gradeIds.size() == 1) {
schoolScores.putAll(gradeScores.get(gradeIds.iterator().next())); schoolScores.putAll(gradeScores.get(gradeIds.iterator().next()));
} else { } else {
// 计算全校的平均得分
for (Map.Entry<String, Double> entry : schoolScores.entrySet()) { for (Map.Entry<String, Double> entry : schoolScores.entrySet()) {
String nodeName = entry.getKey(); String nodeName = entry.getKey();
double totalScore = entry.getValue(); double totalScore = entry.getValue();
int totalCount = schoolScores.size(); // 每个年级视为一个单位 if (totalClassCount == 0) {
schoolScores.put(nodeName, Double.parseDouble(String.format("%.2f", totalScore / totalCount))); // 保留小数点后两位 schoolScores.put(nodeName, 0.0);
} else {
double average = totalScore / totalClassCount;
average = Double.parseDouble(String.format("%.2f", average));
schoolScores.put(nodeName, average);
}
} }
} }
// 6. 初始化所有同层的父节点 // 4. 初始化未参与计算的父节点保持默认0分
for (AppraiseTreeNode node : appraise.getNodes()) { for (AppraiseTreeNode node : appraise.getNodes()) {
if (node.getName().equals("德育")) { if (node.getName().equals("德育")) {
for (AppraiseTreeNode child : node.getChildren()) { for (AppraiseTreeNode child : node.getChildren()) {
@ -1271,7 +1240,7 @@ public class LaborEducationServiceImpl implements LaborEducationService {
} }
} }
// 7. 转换 gradeScores 为新的数据结构 // 5. 转换数据结构并返回
return getResult(gradeScores, schoolScores); return getResult(gradeScores, schoolScores);
} }

@ -18,6 +18,7 @@ import cn.teammodel.model.entity.common.ExamClassResult;
import cn.teammodel.model.entity.school.ClassInfo; import cn.teammodel.model.entity.school.ClassInfo;
import cn.teammodel.model.entity.school.LessonRecord; import cn.teammodel.model.entity.school.LessonRecord;
import cn.teammodel.model.entity.school.School; import cn.teammodel.model.entity.school.School;
import cn.teammodel.model.vo.Common.ExamVo;
import cn.teammodel.model.vo.admin.GradeAndClassVo; import cn.teammodel.model.vo.admin.GradeAndClassVo;
import cn.teammodel.model.vo.appraise.RecordVo; import cn.teammodel.model.vo.appraise.RecordVo;
import cn.teammodel.repository.*; import cn.teammodel.repository.*;
@ -146,7 +147,7 @@ public class MoralEducationServiceImpl implements MoralEducationService {
} }
//examIds.add("c26e5766-597f-45b3-91ad-19e76426323b"); //examIds.add("c26e5766-597f-45b3-91ad-19e76426323b");
//获取所有课程下的课中活动 //获取所有课程下的课中活动
List<Exam> exams = new ArrayList<>(); List<ExamVo> exams = new ArrayList<>();
if (!recordIds.isEmpty()) { if (!recordIds.isEmpty()) {
exams = examRepository.findExamsByIds(laborDto.getSource(),recordIds); exams = examRepository.findExamsByIds(laborDto.getSource(),recordIds);
exams = exams.stream() exams = exams.stream()
@ -155,7 +156,17 @@ public class MoralEducationServiceImpl implements MoralEducationService {
} }
Map<String, List<List<String>>> knowledgeMap = new HashMap<>(); Map<String, List<List<String>>> knowledgeMap = new HashMap<>();
Map<String, List<Double>> point = new HashMap<>(); Map<String, List<Double>> point = new HashMap<>();
for (Exam exam : exams) { List<String> examIds = new ArrayList<>();
for (ExamVo exam : exams) {
examIds.add(exam.getId());
String lessonRecordId = exam.getLessonRecordId(); // 获取 lessonRecordId
Optional<LessonRecord> recordOptional = records.stream()
.filter(record -> record.getId().equals(lessonRecordId))
.findFirst();
if (recordOptional.isPresent()) {
LessonRecord record = recordOptional.get();
exam.setRecordName(record.getName()); // 设置 recordName
}
if (exam.getPapers() != null) { if (exam.getPapers() != null) {
if (exam.getPapers().get(0).getKnowledge() != null) if (exam.getPapers().get(0).getKnowledge() != null)
{ {
@ -164,10 +175,6 @@ public class MoralEducationServiceImpl implements MoralEducationService {
} }
} }
} }
List<String> examIds = new ArrayList<>();
for (Exam exam : exams) {
examIds.add(exam.getId());
}
List<ExamClassResult> examResults = new ArrayList<>(); List<ExamClassResult> examResults = new ArrayList<>();
if (!examIds.isEmpty()) { if (!examIds.isEmpty()) {
examResults = examClassResultRepository.findAll(String.format(PK.CLASS_RESULT, laborDto.getCode()),examIds); examResults = examClassResultRepository.findAll(String.format(PK.CLASS_RESULT, laborDto.getCode()),examIds);
@ -272,26 +279,27 @@ public class MoralEducationServiceImpl implements MoralEducationService {
int count = entry.getValue(); // 次数 int count = entry.getValue(); // 次数
// 确保 count 不小于0 // 确保 count 不小于0
if (count < 0) { if (count < 0) {
count = 0; //次数永远不能为负数 count = 0;
} }
double maxCount = 50.0; // 最大次数(可根据实际情况调整) double maxCount = 50.0; // 调整此参数控制分数增长速率
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 // 使用反比例函数计算加分
double convertedScore; double additionalScore = 40.0 * ((double) count / (count + maxCount));
if (count > maxCount) { double convertedScore = 60.0 + additionalScore;
convertedScore = 100.0; // 超过最大次数,直接满分
} else { // 保留两位小数
// 计算额外加分占总40分的比例 convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
}
subjectiveTotal += convertedScore; subjectiveTotal += convertedScore;
// 获取对应知识块的客观成绩,并确保在60-100之间 // 获取对应知识块的客观成绩并转换为基于60分加分的分数
double objectiveScore = knowledgeBlockScores.get(knowledgeBlock); double objectiveScore = knowledgeBlockScores.get(knowledgeBlock);
objectiveScore = Math.max(60.0, Math.min(100.0, objectiveScore)); // 确保60-100分 // 转换为正确率的小数形式(假设原始分是百分比)
double correctRate = objectiveScore / 100.0;
objectiveScore = 60.0 + correctRate * 40.0;
// 确保不超过100分
objectiveScore = Math.min(100.0, objectiveScore);
// 保留两位小数
objectiveScore = Double.parseDouble(String.format("%.2f", objectiveScore));
objectiveTotal += objectiveScore; objectiveTotal += objectiveScore;
// 计算综合得分主观占60%客观占40% // 计算综合得分主观占60%客观占40%
@ -538,11 +546,18 @@ public class MoralEducationServiceImpl implements MoralEducationService {
} }
} }
// 计算父节点的平均得分 // 计算父节点的平均得分原始正确率转换为基于60分的加分制
parentNodeScoreRates.replaceAll((parentNodeName, totalScore) -> { parentNodeScoreRates.replaceAll((parentNodeName, totalScore) -> {
int count = parentNodeScoreCount.getOrDefault(parentNodeName, 1); int count = parentNodeScoreCount.getOrDefault(parentNodeName, 1);
double averageScore = totalScore / count; double averageScore = totalScore / count; // 原始正确率0-100的百分比
return Math.min(100.0, Math.max(60.0, averageScore)); // 确保得分在60-100之间
// 将原始正确率转换为以60分为基础的加分制正确率 × 40%
double correctRate = averageScore / 100.0; // 转为0-1的小数
double convertedScore = 60.0 + (correctRate * 40.0); // 最低60分最高100分
// 确保不超过100分并保留两位小数
convertedScore = Math.min(100.0, convertedScore);
return Double.parseDouble(String.format("%.2f", convertedScore));
}); });
// 初始化所有同层的父节点 // 初始化所有同层的父节点
@ -687,18 +702,18 @@ public class MoralEducationServiceImpl implements MoralEducationService {
for (Map.Entry<String, Integer> entry : scores.entrySet()) { for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey(); String block = entry.getKey();
int count = entry.getValue(); int count = entry.getValue();
double maxCount = 50.0; // 确保 count 不小于0
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 if (count < 0) {
double convertedScore; count = 0;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
} }
double maxCount = 50.0; // 调整此参数控制分数增长速率
// 使用反比例函数计算加分
double additionalScore = 40.0 * ((double) count / (count + maxCount));
double convertedScore = 60.0 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
convertedScores.put(block, convertedScore); convertedScores.put(block, convertedScore);
} }
@ -981,18 +996,18 @@ public class MoralEducationServiceImpl implements MoralEducationService {
for (Map.Entry<String, Integer> entry : scores.entrySet()) { for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey(); String block = entry.getKey();
int count = entry.getValue(); int count = entry.getValue();
double maxCount = 50.0; // 确保 count 不小于0
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分 if (count < 0) {
double convertedScore; count = 0;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
} }
double maxCount = 50.0; // 调整此参数控制分数增长速率
// 使用反比例函数计算加分
double additionalScore = 40.0 * ((double) count / (count + maxCount));
double convertedScore = 60.0 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
convertedScores.put(block, convertedScore); convertedScores.put(block, convertedScore);
} }
subjectiveScores.put(studentId, convertedScores); subjectiveScores.put(studentId, convertedScores);
@ -1155,106 +1170,66 @@ public class MoralEducationServiceImpl implements MoralEducationService {
List<School.Period> period, List<School.Period> period,
List<GradeAndClassVo> gradeAndClassVos) { List<GradeAndClassVo> gradeAndClassVos) {
// 1. 获取全校所有年级的客观分数 // 1. 初始化数据结构
Map<String, Map<String, Double>> gradeScores = new HashMap<>(); Map<String, Map<String, Double>> gradeScores = new HashMap<>();
Map<String, Double> schoolScores = new HashMap<>(); Map<String, Double> schoolScores = new HashMap<>();
// 获取所有年级的 ID
List<String> gradeIds = period.stream() List<String> gradeIds = period.stream()
.flatMap(period1 -> period1.getGrades().stream()) .flatMap(period1 -> period1.getGrades().stream())
.collect(Collectors.toList()); .collect(Collectors.toList());
int totalClassCount = 0; // 新增:全校总班级数统计
// 2. 获取全校所有学生的主观分数(次数) // 2. 遍历所有年级
List<Map<String, Object>> subjectiveScoresList = calculateScoresWithDetails(res, appraise);
// 3. 将主观次数转换为0-100分数
//Map<String, Map<String, Double>> subjectiveScores = new HashMap<>();
for (Map<String, Object> studentScore : subjectiveScoresList) {
String studentId = (String) studentScore.get("studentId");
@SuppressWarnings("unchecked")
Map<String, Integer> scores = (Map<String, Integer>) studentScore.get("scores");
Map<String, Double> convertedScores = new HashMap<>();
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
String block = entry.getKey();
int count = entry.getValue();
double maxCount = 50.0;
// 将次数转换为 60-100 的分数60分基础额外加分不超过40分
double convertedScore;
if (count > maxCount) {
convertedScore = 100.0; // 超过最大次数,直接满分
} else {
// 计算额外加分占总40分的比例
double additionalScore = (count / maxCount) * 40;
convertedScore = 60 + additionalScore;
// 保留两位小数
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
}
convertedScores.put(block, convertedScore);
}
//subjectiveScores.put(studentId, convertedScores);
}
// 4. 遍历所有年级
int index = 0; int index = 0;
for (String gradeId : gradeIds) { for (String gradeId : gradeIds) {
// 调用改造后的方法,返回的 gradeResult 包含列表结构的 gradeScores 和 classScores
Map<String, Object> gradeResult = calculateKnowledgeScoreForGrade( Map<String, Object> gradeResult = calculateKnowledgeScoreForGrade(
String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos String.valueOf(index), examResults, knowledgeMap, appraise, points, res, gradeAndClassVos
); );
// 1. 提取年级平均gradeScores // 2.1 提取年级平均分
List<Map<String, Object>> adjustedGradeScores = (List<Map<String, Object>>) gradeResult.get("gradeScores"); List<Map<String, Object>> adjustedGradeScores = (List<Map<String, Object>>) gradeResult.get("gradeScores");
Map<String, Double> gradeScoresInner = new HashMap<>(); Map<String, Double> gradeScoresInner = new HashMap<>();
// 遍历年级得分列表(通常只有一个元素)
for (Map<String, Object> gradeScoreEntry : adjustedGradeScores) { for (Map<String, Object> gradeScoreEntry : adjustedGradeScores) {
String gradeName = (String) gradeScoreEntry.get("gradeName");
List<Map<String, Object>> blocks = (List<Map<String, Object>>) gradeScoreEntry.get("blocks"); List<Map<String, Object>> blocks = (List<Map<String, Object>>) gradeScoreEntry.get("blocks");
// 将 blocks 转换为 Map<String, Double>
for (Map<String, Object> block : blocks) { for (Map<String, Object> block : blocks) {
String nodeName = (String) block.get("name"); String nodeName = (String) block.get("name");
Double score = (Double) block.get("score"); Double score = (Double) block.get("score");
gradeScoresInner.put(nodeName, score); gradeScoresInner.put(nodeName, score);
} }
} }
// 保存年级得分
gradeScores.put(gradeId, gradeScoresInner); gradeScores.put(gradeId, gradeScoresInner);
// 2. 累加全校得分总和(从 classScores 中提取) // 2.2 累加全校总分并统计班级数
List<Map<String, Object>> adjustedClassScores = (List<Map<String, Object>>) gradeResult.get("classScores"); List<Map<String, Object>> adjustedClassScores = (List<Map<String, Object>>) gradeResult.get("classScores");
totalClassCount += adjustedClassScores.size(); // 累加班级数
for (Map<String, Object> classScoreEntry : adjustedClassScores) { for (Map<String, Object> classScoreEntry : adjustedClassScores) {
List<Map<String, Object>> classBlocks = (List<Map<String, Object>>) classScoreEntry.get("blocks"); List<Map<String, Object>> classBlocks = (List<Map<String, Object>>) classScoreEntry.get("blocks");
// 遍历班级的每个评分项
for (Map<String, Object> block : classBlocks) { for (Map<String, Object> block : classBlocks) {
String nodeName = (String) block.get("name"); String nodeName = (String) block.get("name");
Double score = (Double) block.get("score"); Double score = (Double) block.get("score");
schoolScores.put(nodeName, schoolScores.getOrDefault(nodeName, 0.0) + score); schoolScores.put(nodeName, schoolScores.getOrDefault(nodeName, 0.0) + score);
} }
} }
index++; index++;
} }
// 5. 计算全校的平均得 // 3. 计算全校平均
if (gradeIds.size() == 1) { if (gradeIds.size() == 1) {
schoolScores.putAll(gradeScores.get(gradeIds.iterator().next())); schoolScores.putAll(gradeScores.get(gradeIds.iterator().next()));
} else { } else {
// 计算全校的平均得分
for (Map.Entry<String, Double> entry : schoolScores.entrySet()) { for (Map.Entry<String, Double> entry : schoolScores.entrySet()) {
String nodeName = entry.getKey(); String nodeName = entry.getKey();
double totalScore = entry.getValue(); double totalScore = entry.getValue();
int totalCount = schoolScores.size(); // 每个年级视为一个单位 if (totalClassCount == 0) {
schoolScores.put(nodeName, Double.parseDouble(String.format("%.2f", totalScore / totalCount))); // 保留小数点后两位 schoolScores.put(nodeName, 0.0);
} else {
double average = totalScore / totalClassCount;
average = Double.parseDouble(String.format("%.2f", average));
schoolScores.put(nodeName, average);
}
} }
} }
// 6. 初始化所有同层的父节点 // 4. 初始化未参与计算的父节点保持默认0分
for (AppraiseTreeNode node : appraise.getNodes()) { for (AppraiseTreeNode node : appraise.getNodes()) {
if (node.getName().equals("劳育")) { if (node.getName().equals("劳育")) {
for (AppraiseTreeNode child : node.getChildren()) { for (AppraiseTreeNode child : node.getChildren()) {
@ -1265,7 +1240,7 @@ public class MoralEducationServiceImpl implements MoralEducationService {
} }
} }
// 7. 转换 gradeScores 为新的数据结构 // 5. 转换数据结构并返回
return getResult(gradeScores, schoolScores); return getResult(gradeScores, schoolScores);
} }

@ -0,0 +1,20 @@
package cn.teammodel.model.vo.Common;
import cn.teammodel.model.entity.common.Exam;
import lombok.Data;
import java.util.List;
@Data
public class ExamVo {
private String id;
private String name;
private String school;
public int stuCount;
public double average;
public List<String> classes;
public long createTime;
public String recordName;
public List<Exam.PaperSimple> papers;
public String lessonRecordId;
}

@ -1,6 +1,7 @@
package cn.teammodel.repository; package cn.teammodel.repository;
import cn.teammodel.model.entity.common.Exam; import cn.teammodel.model.entity.common.Exam;
import cn.teammodel.model.vo.Common.ExamVo;
import com.azure.spring.data.cosmos.repository.CosmosRepository; import com.azure.spring.data.cosmos.repository.CosmosRepository;
import com.azure.spring.data.cosmos.repository.Query; import com.azure.spring.data.cosmos.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
@ -16,6 +17,6 @@ public interface ExamRepository extends CosmosRepository<Exam, String> {
List<Exam> findExamByClassId(String code,String classId,String periodId,String subjectId); List<Exam> findExamByClassId(String code,String classId,String periodId,String subjectId);
@Query("select * from Exam as s where s.code = @code and s.id = @id") @Query("select * from Exam as s where s.code = @code and s.id = @id")
List<Exam> findExamById(@Param("code")String code, @Param("id")String id); List<Exam> findExamById(@Param("code")String code, @Param("id")String id);
@Query("select s.id,s.name,s.average,s.classes,s.stuCount,s.createTime,s.papers from Exam as s where s.source = @source and s.lessonRecordId in (@ids)") @Query("select s.id,s.name,s.average,s.classes,s.stuCount,s.createTime,s.lessonRecordId,s.papers from Exam as s where s.source = @source and s.lessonRecordId in (@ids)")
List<Exam> findExamsByIds(String source, Collection<String> ids); List<ExamVo> findExamsByIds(String source, Collection<String> ids);
} }

@ -12,7 +12,7 @@ import java.util.List;
@Repository @Repository
public interface LessonRecordRepository extends CosmosRepository<LessonRecord, String> { public interface LessonRecordRepository extends CosmosRepository<LessonRecord, String> {
@Query("select c.id,c.tmdid,c.groupIds,c.startTime,c.clientInteractionCount,c.clientInteractionAverge from LessonRecord as c where " + @Query("select c.id,c.tmdid,c.name,c.groupIds,c.startTime,c.clientInteractionCount,c.clientInteractionAverge from LessonRecord as c where " +
"c.code = @code and " + "c.code = @code and " +
"(IS_NULL(@startTime) OR c.startTime >= @startTime) and " + "(IS_NULL(@startTime) OR c.startTime >= @startTime) and " +
"(IS_NULL(@endTime) OR c.startTime <= @endTime) and "+ "(IS_NULL(@endTime) OR c.startTime <= @endTime) and "+

Loading…
Cancel
Save