update 报告相关算法更新

develop
hhb@hotmail.com 2 months ago
parent a1ad6463b6
commit cb74969301

@ -47,7 +47,7 @@ public class LaborEducationController {
@PostMapping("getStudentMonthlyScores")
@ApiOperation("按月比对分析")
public R<List<Map<String, Object>>> getStudentMonthlyScores(@Valid @RequestBody LaborDto laborDto, HttpServletRequest request) {
List<Map<String, Object>> res = laborEducationService.getStudentMonthlyScores(laborDto);
List<Map<String, Object>> res = laborEducationService.getStudentMonthlyScores(laborDto,request);
return R.success(res);
}
}

@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
@RestController
@ -34,4 +35,17 @@ public class MoralEducationController {
Map<String, Object> res = moralEducationService.getDetails(findDto,request);
return R.success(res);
}
@PostMapping("getStudentSemesterScores")
@ApiOperation("分学期比对分析")
public R<Map<String, Object>> getStudentSemesterScores(@Valid @RequestBody LaborDto laborDto, HttpServletRequest request) {
Map<String, Object> res = moralEducationService.getStudentSemesterScores(laborDto,request);
return R.success(res);
}
@PostMapping("getStudentMonthlyScores")
@ApiOperation("按月比对分析")
public R<List<Map<String, Object>>> getStudentMonthlyScores(@Valid @RequestBody LaborDto laborDto, HttpServletRequest request) {
List<Map<String, Object>> res = moralEducationService.getStudentMonthlyScores(laborDto,request);
return R.success(res);
}
}

@ -13,5 +13,5 @@ public interface LaborEducationService {
Map<String,Object> getAnalysis(LaborDto laborDto, HttpServletRequest request);
Map<String,Object> getDetails(FindDto findDto, HttpServletRequest request);
Map<String,Object> getStudentSemesterScores(LaborDto laborDto, HttpServletRequest request);
List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto);
List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto,HttpServletRequest request);
}

@ -4,9 +4,12 @@ import cn.teammodel.model.dto.admin.labor.FindDto;
import cn.teammodel.model.dto.admin.labor.LaborDto;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
public interface MoralEducationService {
Map<String,Object> getAnalysis(LaborDto laborDto, HttpServletRequest request);
Map<String,Object> getDetails(FindDto findDto, HttpServletRequest request);
Map<String,Object> getStudentSemesterScores(LaborDto laborDto, HttpServletRequest request);
List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto,HttpServletRequest request);
}

@ -30,7 +30,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
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;
@ -38,6 +40,8 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -45,6 +49,7 @@ 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 LaborEducationServiceImpl implements LaborEducationService {
@ -1371,23 +1376,59 @@ public class LaborEducationServiceImpl implements LaborEducationService {
//获取每月各个知识库综合得分以及整体得分内容
public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto,HttpServletRequest request) {
// 1. 获取基础信息
String schoolId = SecurityUtil.getLoginUser().getSchoolId();
String studentId = laborDto.getStudentId();
List<String> classStudentIds = Collections.emptyList();
// 2. 获取相关开课记录
List<LessonRecord> records = getLessonRecords(laborDto, schoolId);
//List<String> classIds = Collections.singletonList(laborDto.getClassId());
List<RecordVo> res = appraiseRecordRepository.getStudentRecords(
List<RecordVo> res;
if (laborDto.getClassId() == null) {
res = appraiseRecordRepository.getStudentRecords(
String.format(PK.PK_APPRAISE_RECORD, schoolId),
laborDto.getStudentId(),
laborDto.getStartTime(),
laborDto.getEndTime(),
"德育"
);
}else {
//当班级ID 存在时 获取该班级下所有名单即学生Id
List<String> classIds = Collections.singletonList(laborDto.getClassId());
GroupDto groupDto = new GroupDto();
groupDto.setIds(classIds);
groupDto.setSchoolId(laborDto.getCode());
String url = environment.getProperty("ies.server-url-group");
Map<String, Object> groupId = GroupUtil.getGroupId(groupDto, new GroupUtil(environment), request, url);
List<RGroupList> rGroupList = new ArrayList<>();
List<RMember> rMembers = new ArrayList<>();
for (Map.Entry<String, Object> 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<List<RGroupList>>() {});
}
}
rMembers = rGroupList.stream()
.flatMap(rGroupList1 -> rGroupList1.getMembers().stream())
.filter(rMember -> rMember.getClassId().equals(laborDto.getClassId()))
.collect(Collectors.toList());
classStudentIds = rMembers.stream().map(RMember::getId).collect(Collectors.toList());
/*String className = rGroupList.stream()
.filter(rGroupList1 -> rGroupList1.getId().equals(classId))
.findFirst()
.map(RGroupList::getName)
.orElse("未知班级"); // 如果未找到则返回默认值 "未知班级"*/
res = appraiseRecordRepository.latestRecords(
String.format(PK.PK_APPRAISE_RECORD, schoolId),
laborDto.getAcademicYearId(),
laborDto.getStartTime(),
laborDto.getEndTime(),
"德育",
classIds
);
}
// 3. 获取考试及知识点映射
Map<String, List<List<String>>> examKnowledgeMap = new HashMap<>();
@ -1395,8 +1436,12 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
List<ExamVo> exams = getExamsWithKnowledge(laborDto, records, examKnowledgeMap, points);
// 4. 获取考试结果并按月份分组
List<String> targetStudents = laborDto.getClassId() != null ?
classStudentIds : Collections.singletonList(studentId);
Map<Integer, List<ExamResultWrapper>> monthlyResults = getMonthlyExamResults(
schoolId, laborDto.getClassId(), exams, records, examKnowledgeMap, points, res
schoolId, laborDto.getClassId(), exams, records,
examKnowledgeMap, points, targetStudents // 传入目标学生列表
);
// 5. 获取知识块配置
@ -1417,7 +1462,9 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
Map<String, Map<Integer, Integer>> finalBlockMonthlyCounts = blockMonthlyCounts;
res.stream()
.filter(vo -> studentId.equals(vo.getTargetId()))
.filter(vo -> laborDto.getClassId() != null ?
targetStudents.contains(vo.getTargetId()) :
studentId.equals(vo.getTargetId()))
.forEach(vo -> {
// 获取知识点对应的知识块
String originalPoint = vo.getAppraiseName();
@ -1445,11 +1492,14 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
)));
// 6. 处理每月数据,传入主观评价统计结果
List<Map<String, Object>> monthlyData = processMonthlyData(studentId, monthlyResults, knowledgeBlockMap,
getMonthsBetween(laborDto.getStartTime(), laborDto.getEndTime()), blockMonthlyCounts);
// 7. 计算综合得分并添加到结果
return addOverallScore(monthlyData, knowledgeBlockMap.keySet());
return processMonthlyData(
targetStudents,
monthlyResults,
knowledgeBlockMap,
getMonthsBetween(laborDto.getStartTime(), laborDto.getEndTime()),
blockMonthlyCounts
);
}
@ -1526,13 +1576,45 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
.collect(Collectors.toList());
}
private Map<Integer, List<ExamResultWrapper>> getMonthlyExamResults(String schoolId, String classId,
List<ExamVo> exams, List<LessonRecord> records,
Map<String, List<List<String>>> examKnowledgeMap,
Map<String, List<Double> > points,
List<RecordVo> res) {
private Map<Integer, List<ExamResultWrapper>> getMonthlyExamResults(
String schoolId, String classId, List<ExamVo> exams,
List<LessonRecord> records, Map<String, List<List<String>>> examKnowledgeMap,
Map<String, List<Double>> points, List<String> studentIds) { // 新增studentIds参数
Map<Integer, List<ExamResultWrapper>> monthlyResults = new HashMap<>();
if (classId == null) {
exams.forEach(exam -> {
List<ExamClassResult> results = examClassResultRepository.findByStudentId(
String.format(PK.CLASS_RESULT, schoolId), studentIds.get(0), exam.getId()
);
results.forEach(result -> {
records.stream()
.filter(r -> r.getId().equals(exam.getLessonRecordId()))
.findFirst()
.ifPresent(record -> {
int month = getMonthFromTimestamp(record.getStartTime());
List<List<String>> knowledge = examKnowledgeMap.get(exam.getId());
List<Double> point = points.get(exam.getId());
// 处理所有相关学生
result.getStudentIds().stream()
.filter(studentIds::contains) // 仅处理班级学生
.forEach(studentId -> {
monthlyResults.computeIfAbsent(month, k -> new ArrayList<>())
.add(new ExamResultWrapper(
exam.getId(),
result,
knowledge,
point,
studentId // 新增学生ID字段
));
});
});
});
});
}else {
exams.forEach(exam -> {
List<ExamClassResult> results = examClassResultRepository.findById(
String.format(PK.CLASS_RESULT, schoolId), classId, exam.getId()
@ -1547,50 +1629,80 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
List<List<String>> knowledge = examKnowledgeMap.get(exam.getId());
List<Double> point = points.get(exam.getId());
// 处理所有相关学生
result.getStudentIds().stream()
.filter(studentIds::contains) // 仅处理班级学生
.forEach(studentId -> {
monthlyResults.computeIfAbsent(month, k -> new ArrayList<>())
.add(new ExamResultWrapper(exam.getId(),result, knowledge,point));
.add(new ExamResultWrapper(
exam.getId(),
result,
knowledge,
point,
studentId // 新增学生ID字段
));
});
});
});
});
}
return monthlyResults;
}
private List<Map<String, Object>> processMonthlyData(String studentId,
private List<Map<String, Object>> processMonthlyData(
List<String> targetStudentIds,
Map<Integer, List<ExamResultWrapper>> monthlyResults,
Map<String, List<String>> knowledgeBlockMap,
Set<Integer> months,
Map<String, Map<Integer, Integer>> blockMonthlyCounts) {
return months.stream().map(month -> {
Map<String, Object> monthData = new LinkedHashMap<>();
monthData.put("month", month);
List<ExamResultWrapper> wrappers = monthlyResults.getOrDefault(month, Collections.emptyList());
Map<String, Object> monthEntry = new LinkedHashMap<>();
monthEntry.put("month", month);
List<Map<String, Object>> scoreList = new ArrayList<>();
// 按学生分组考试结果
Map<String, List<ExamResultWrapper>> studentResults = monthlyResults
.getOrDefault(month, Collections.emptyList())
.stream()
.filter(wrapper -> targetStudentIds.contains(wrapper.getStudentId()))
.collect(Collectors.groupingBy(ExamResultWrapper::getStudentId));
// 初始化知识块总分计数器
Map<String, Double> blockTotalScores = new HashMap<>();
knowledgeBlockMap.keySet().forEach(block -> blockTotalScores.put(block, 0.0));
// 遍历所有目标学生
targetStudentIds.forEach(studentId -> {
List<ExamResultWrapper> wrappers = studentResults.getOrDefault(studentId, Collections.emptyList());
List<ExamClassResult> examResults = wrappers.stream()
.map(ExamResultWrapper::getResult)
.collect(Collectors.toList());
Map<String, List<List<String>>> monthlyKnowledgeMap = new HashMap<>();
Map<String, List<Double>> monthlyPoints = new HashMap<>();
wrappers.forEach(wrapper -> {
String examId = wrapper.getExamId();
monthlyKnowledgeMap.put(examId, wrapper.getKnowledge());
monthlyPoints.put(examId, wrapper.getPoints());
});
// 1. 计算知识点得分(保留原始逻辑)
Map<String, Double> knowledgeScores = calculateMonthlyKnowledgeScores(
studentId, examResults, monthlyKnowledgeMap, monthlyPoints
studentId,
examResults,
wrappers.stream().collect(Collectors.toMap(
ExamResultWrapper::getExamId,
ExamResultWrapper::getKnowledge)),
wrappers.stream().collect(Collectors.toMap(
ExamResultWrapper::getExamId,
ExamResultWrapper::getPoints))
);
Set<String> monthlyTestedKnowledges = knowledgeScores.keySet();
// 2. 计算每个知识块的客观得分(新增关键逻辑)
Map<String, Double> objectiveScores = new HashMap<>();
knowledgeBlockMap.forEach((block, knowledges) -> {
// 获取该学生当前月份被测试的知识点
Set<String> monthlyTestedKnowledges = knowledgeScores.keySet();
List<String> testedKnowledges = knowledges.stream()
.filter(monthlyTestedKnowledges::contains)
.collect(Collectors.toList());
// 计算客观得分(原始逻辑)
double finalScore;
if (testedKnowledges.isEmpty()) {
finalScore = 60.0;
@ -1603,33 +1715,70 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
finalScore = Math.min(finalScore, 100.0);
}
finalScore = Double.parseDouble(String.format("%.2f", finalScore));
objectiveScores.put(block, finalScore);
});
// 处理主观评分(根据知识块获取对应次数)
Map<Integer, Integer> monthlyCounts = blockMonthlyCounts.getOrDefault(block, new HashMap<>());
int praiseCount = monthlyCounts.getOrDefault(month, 0);
// 3. 处理主观评价得分
Map<String, Double> subjectiveScores = calculateSubjectiveScores(
knowledgeBlockMap,
blockMonthlyCounts,
month,
studentId
);
// 步骤1计算次数转换分数0-40分
final double K = 50.0; // 调整系数控制分数增长速度
double convertedScore = (praiseCount * 40.0) / (praiseCount + K);
convertedScore = Math.min(convertedScore, 40.0);
convertedScore = Double.parseDouble(String.format("%.2f", convertedScore));
// 4. 合并主客观得分(调整权重)
knowledgeBlockMap.keySet().forEach(block -> {
double objectiveScore = objectiveScores.getOrDefault(block, 60.0);
double subjectiveScore = subjectiveScores.getOrDefault(block, 60.0);
double combinedScore = (subjectiveScore * 0.6) + (objectiveScore * 0.4);
blockTotalScores.merge(block, combinedScore, Double::sum);
});
});
// 步骤2计算主观总分60分基础 + 转换分)
double subjectiveTotal = 60.0 + convertedScore;
subjectiveTotal = Math.min(subjectiveTotal, 100.0);
subjectiveTotal = Double.parseDouble(String.format("%.2f", subjectiveTotal));
// 计算班级平均分
int studentCount = targetStudentIds.size();
knowledgeBlockMap.keySet().forEach(block -> {
double avg = studentCount > 0 ?
blockTotalScores.get(block) / studentCount : 0.0;
Map<String, Object> scoreEntry = new LinkedHashMap<>();
scoreEntry.put("name", block);
scoreEntry.put("score", Double.parseDouble(String.format("%.2f", avg)));
scoreList.add(scoreEntry);
});
// 步骤3主客观合并主观60% + 客观40%
double combinedScore = (subjectiveTotal * 0.6) + (finalScore * 0.4);
combinedScore = Double.parseDouble(String.format("%.2f", combinedScore));
// 按知识块名称排序(可选)
scoreList.sort(Comparator.comparing(m -> (String) m.get("name")));
monthData.put(block, combinedScore);
monthEntry.put("types", scoreList);
return monthEntry;
}).sorted(Comparator.comparingInt(m -> (Integer) m.get("month")))
.collect(Collectors.toList());
}
// 新增方法:计算主观评分转换后的得分
private Map<String, Double> calculateSubjectiveScores(
Map<String, List<String>> knowledgeBlockMap,
Map<String, Map<Integer, Integer>> blockMonthlyCounts,
int month,
String studentId) {
Map<String, Double> subjectiveScores = new HashMap<>();
knowledgeBlockMap.keySet().forEach(block -> {
// 获取该学生本月的评价次数
int praiseCount = blockMonthlyCounts.getOrDefault(block, new HashMap<>())
.getOrDefault(month, 0);
// 次数转分数公式
final double K = 50.0;
double convertedScore = (praiseCount * 40.0) / (praiseCount + K);
convertedScore = Math.min(convertedScore, 40.0);
// 主观总分 = 基础60 + 转换分
double totalScore = 60.0 + convertedScore;
subjectiveScores.put(block, Double.parseDouble(String.format("%.2f", totalScore)));
});
return monthData;
})
.sorted(Comparator.comparingInt(m -> (Integer) m.get("month")))
.collect(Collectors.toList());
return subjectiveScores;
}
private Map<String, Double> calculateMonthlyKnowledgeScores(String studentId,
@ -1715,6 +1864,7 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
private ExamClassResult result;
private List<List<String>> knowledge; // 每个题目对应的知识点列表
private List<Double> points;
private String studentId; // 新增字段
}
// 时间处理工具方法
@ -1780,17 +1930,145 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
SemesterPeriod current = periods.get("current");
SemesterPeriod last = periods.get("last");
// 3. 查询并处理数据
Map<String, Object> currentData = current != null ?
processSemesterData(laborDto, current, request,true) :
Collections.emptyMap();
// 学生数据处理
Map<String, Object> studentResult = Collections.emptyMap();
if (StringUtils.isNotBlank(laborDto.getStudentId())) {
studentResult = processIndividual(laborDto, current, last, request);
}
// 班级数据处理
Map<String, Object> classResult = Collections.emptyMap();
if (StringUtils.isNotBlank(laborDto.getClassId())) {
classResult = processClass(laborDto, current, last, request);
}
// 组合最终结果
return combineAllResults(laborDto, studentResult, classResult);
}
private Map<String, Object> combineAllResults(LaborDto dto,
Map<String, Object> studentResult,
Map<String, Object> classResult) {
Map<String, Object> finalResult = new LinkedHashMap<>();
// 学生维度数据
finalResult.put("student", studentResult);
// 班级维度数据
if (!classResult.isEmpty()) {
finalResult.put("class", classResult);
}
return finalResult;
}
private Map<String, Object> processIndividual(LaborDto dto,
SemesterPeriod current,
SemesterPeriod last,
HttpServletRequest request) {
// 原有学生处理逻辑
Map<String, Object> currentData = processSemesterData(dto, current, request, true, false);
Map<String, Object> lastData = processSemesterData(dto, last, request, false,false);
return combineResults(dto, currentData, lastData);
}
private Map<String, Object> processClass(LaborDto dto,
SemesterPeriod current,
SemesterPeriod last,
HttpServletRequest request) {
// 克隆DTO并清除学生ID
LaborDto classDto = new LaborDto();
classDto.setCode(dto.getCode());
classDto.setPeriodId(dto.getPeriodId());
classDto.setClassId(dto.getClassId());
classDto.setSubjectId(dto.getSubjectId());
classDto.setSemesterId(dto.getSemesterId());
classDto.setStartTime(dto.getStartTime());
classDto.setEndTime(dto.getEndTime());
classDto.setAcademicYearId(dto.getAcademicYearId());
classDto.setTargetType(dto.getTargetType());
classDto.setYear(dto.getYear());
classDto.setGrade(dto.getGrade());
classDto.setGradeName(dto.getGradeName());
classDto.setSource(dto.getSource());
classDto.setTmdId(dto.getTmdId());
classDto.setStudentId(null);
Map<String, Object> currentData = processSemesterData(classDto, current, request, true,true);
Map<String, Object> lastData = processSemesterData(classDto, last, request, false,true);
return combineClassResults(classDto, currentData, lastData);
}
private Map<String, Object> combineClassResults(LaborDto dto,
Map<String, Object> current,
Map<String, Object> last) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("classId", dto.getClassId());
// 构建班级数据结构(类似学生结构)
List<Map<String, Object>> scores = buildClassScoreBlocks(dto, current, last);
result.put("scores", scores);
return result;
}
private List<Map<String, Object>> buildClassScoreBlocks(LaborDto dto,
Map<String, Object> current,
Map<String, Object> last) {
Map<String, Object> result = new LinkedHashMap<>();
result.put("classId", dto.getClassId());
Map<String, Object> lastData = last != null ?
processSemesterData(laborDto, last, request,true) :
Collections.emptyMap();
Appraise appraise = appraiseRepository.findAppraiseBySchoolIdAndPeriodIdAndCode(dto.getCode(), dto.getPeriodId(), PK.PK_APPRAISE);
// 获取知识块配置
appraise = evaluationService.buildTree(appraise);
Set<String> knowledgeBlocks = loadKnowledgeBlocks(appraise);
// 4. 组合最终结果
return combineResults(laborDto, currentData, lastData);
// 类似学生数据结构,但含班级统计信息
Appraise finalAppraise = appraise;
return knowledgeBlocks.stream().map(block -> {
Map<String, Object> blockData = new LinkedHashMap<>();
blockData.put("name", block);
// 处理当前学期班级平均分(空值安全+格式化)
double currentScore = Optional.ofNullable(current)
.map(c -> (Map<String, Double>) c.get("blockScores"))
.map(scores -> scores.getOrDefault(block, 0.0))
.orElse(0.0);
currentScore = new BigDecimal(currentScore).setScale(2, RoundingMode.HALF_UP).doubleValue();
blockData.put("classCurrentScore", currentScore);
// 处理上学期班级平均分(空值安全+格式化)
double lastScore = Optional.ofNullable(last)
.map(l -> (Map<String, Double>) l.get("blockScores"))
.map(scores -> scores.getOrDefault(block, 0.0))
.orElse(0.0);
lastScore = new BigDecimal(lastScore).setScale(2, RoundingMode.HALF_UP).doubleValue();
blockData.put("classLastScore", lastScore);
// 知识点出现总次数
((Map<String, Integer>)current.get("knowledgeCounts")).entrySet().stream()
.filter(e -> isBelongToBlock(e.getKey(), block, finalAppraise))
.forEach(e -> blockData.put(e.getKey(), e.getValue()));
// 处理知识点次数
List<Map<String, Object>> knowledgePoints = new ArrayList<>();
if (current.containsKey("knowledgeCounts")) {
Map<String, Integer> counts = (Map<String, Integer>) current.get("knowledgeCounts");
counts.entrySet().stream()
.filter(e -> isBelongToBlock(e.getKey(), block, finalAppraise))
.forEach(e -> {
Map<String, Object> point = new HashMap<>();
point.put("name", e.getKey());
point.put("count", e.getValue() != null ? e.getValue() : 0);
knowledgePoints.add(point);
});
}
blockData.put("knowledgePoints", knowledgePoints);
return blockData;
}).collect(Collectors.toList());
}
// 核心学期计算逻辑
@ -1900,7 +2178,8 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
private Map<String, Object> processSemesterData(LaborDto laborDto,
SemesterPeriod semester,
HttpServletRequest request,
boolean isCurrent) {
boolean isCurrent,
boolean isClassMod) {
Map<String, Object> result = new HashMap<>();
// 1. 设置时间范围查询条件
@ -1910,6 +2189,22 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
// 2. 获取原始分析数据
Map<String, Object> analysisData = getAnalysis(laborDto, request);
if (isClassMod) {
// 班级知识点统计
List<Map<String, Object>> scores = (List<Map<String, Object>>) analysisData.get("scores");
Map<String, Integer> knowledgeCounts = scores.stream()
.map(s -> (List<Map<String, Object>>) s.get("appraises"))
.flatMap(List::stream)
.collect(Collectors.toMap(
a -> (String) a.get("appraiseName"),
a -> 1,
Integer::sum
));
result.put("knowledgeCounts", knowledgeCounts);
// 班级版块平均分
Map<String, Double> classBlockAverages = calculateClassAverages(analysisData);
result.put("blockScores", classBlockAverages);
} else {
// 3. 提取知识点次数(仅当前学期)
if (isCurrent) {
List<Map<String, Object>> scores = (List<Map<String, Object>>) analysisData.get("scores");
@ -1944,10 +2239,20 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
)))
.orElse(new HashMap<>());
result.put("classAverage", classAverages);
}
return result;
}
private Map<String, Double> calculateClassAverages(Map<String, Object> analysisData) {
return ((List<Map<String, Object>>) analysisData.get("scores")).stream()
.map(s -> (Map<String, Map<String, Object>>) s.get("scores"))
.flatMap(m -> m.entrySet().stream())
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.averagingDouble(e -> (Double)e.getValue().get("compositeScore"))
));
}
private Map<String, Double> extractBlockScores(Map<String, Object> data, String studentId) {
return ((List<Map<String, Object>>) data.get("scores")).stream()
.filter(s -> studentId.equals(s.get("studentId")))
@ -2001,14 +2306,22 @@ public List<Map<String, Object>> getStudentMonthlyScores(LaborDto laborDto) {
Map<String, Double> classAvg = (Map<String, Double>) currentData.get("classAverage");
blockData.put("classScore", classAvg.getOrDefault(block, 0.0));
// 知识点次数
// 处理知识点次数
List<Map<String, Object>> knowledgePoints = new ArrayList<>();
if (currentData.containsKey("knowledgeCounts")) {
Map<String, Integer> counts = (Map<String, Integer>) currentData.get("knowledgeCounts");
Appraise finalAppraise = appraise;
counts.entrySet().stream()
.filter(e -> isBelongToBlock(e.getKey(), block, finalAppraise))
.forEach(e -> blockData.put(e.getKey(), e.getValue()));
.forEach(e -> {
Map<String, Object> point = new HashMap<>();
point.put("name", e.getKey());
point.put("count", e.getValue() != null ? e.getValue() : 0);
knowledgePoints.add(point);
});
}
blockData.put("knowledgePoints", knowledgePoints);
scores.add(blockData);
}

@ -1,10 +1,9 @@
package cn.teammodel.model.dto.admin.labor;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
public class LaborDto {
@ApiModelProperty("学校编码")
@ -26,4 +25,5 @@ public class LaborDto {
private String classId;
private String source = "1";
private String studentId;
private String targetType; // "student" 或 "class"
}

@ -13,4 +13,7 @@ public interface ExamClassResultRepository extends CosmosRepository<ExamClassRes
List<ExamClassResult> findAll(String code, Collection<String> ids);
@Query("select * from ExamClassResult as s where s.code = @code and s.info.id = @id and s.examId = @examId")
List<ExamClassResult> findById(String code, String id,String examId);
@Query("select * from ExamClassResult as s where s.code = @code and array_contains(s.studentIds ,@studentId) and s.examId = @examId")
List<ExamClassResult> findByStudentId(String code, String studentId,String examId);
}

Loading…
Cancel
Save