update 新增批量评价内容获取

develop
hhb@hotmail.com 4 months ago
parent cf3f5d300b
commit 4aaa07f8e4

@ -10,7 +10,8 @@ public enum ErrorCode {
FORBIDDEN_ERROR(40300, "禁止访问"), FORBIDDEN_ERROR(40300, "禁止访问"),
SYSTEM_ERROR(50000, "系统内部异常"), SYSTEM_ERROR(50000, "系统内部异常"),
OPERATION_ERROR(50001, "操作失败"), OPERATION_ERROR(50001, "操作失败"),
DATA_FORMAT_ERROR(40001, "数据格式错误"); DATA_FORMAT_ERROR(40001, "数据格式错误"),
PARAM_ERROR(40002, "数据为空");
/** /**
* *

@ -9,3 +9,4 @@ public interface BlobService {
Map<String,Object> getBlobSas(BlobSasDto blobSasDto, HttpServletRequest request); Map<String,Object> getBlobSas(BlobSasDto blobSasDto, HttpServletRequest request);
Map<String,Object> getSasR99(BlobSasDto blobSasDto, HttpServletRequest request); Map<String,Object> getSasR99(BlobSasDto blobSasDto, HttpServletRequest request);
} }

@ -86,9 +86,17 @@ public class AppraiseController {
return R.success(res); return R.success(res);
} }
@PostMapping("Reports")
@ApiOperation(value = "查看多个学生当前的学期的实时评价报告")
public R<List<StudentReportVo>> Reports(@Valid @RequestBody ReportDto reportDto) {
List<StudentReportVo> res = evaluationService.Reports(reportDto);
return R.success(res);
}
@PostMapping("studentReportPDF") @PostMapping("studentReportPDF")
@ApiOperation(value = "导出学生当前的学期的实时评价报告 PDF") @ApiOperation(value = "导出学生当前的学期的实时评价报告 PDF")
public void exportStuReportPdf(@Valid @RequestBody IdRequest idRequest, HttpServletResponse response) throws DocumentException, IOException { public void exportStuReportPdf(@Valid @RequestBody IdRequest idRequest, HttpServletResponse response) throws DocumentException, IOException {
evaluationService.exportStuReportPdf(idRequest, response); evaluationService.exportStuReportPdf(idRequest, response);
} }
} }

@ -0,0 +1,13 @@
package cn.teammodel.model.dto.Appraise;
import lombok.Data;
import javax.validation.constraints.Size;
import java.util.List;
@Data
public class ReportDto {
@Size(min = 1, message = "ids cannot be empty")
public List<String> ids;
}

@ -34,6 +34,9 @@ public interface AppraiseRecordRepository extends CosmosRepository<AppraiseRecor
@Query("select c.id, c.praiseCount, c.score from Student as c where c.targetId = @targetId and c.academicYearId = @academicYearId and c.code = @code") @Query("select c.id, c.praiseCount, c.score from Student as c where c.targetId = @targetId and c.academicYearId = @academicYearId and c.code = @code")
List<AppraiseRecord> findScoreAndPraise(String targetId,String academicYearId,String code); List<AppraiseRecord> findScoreAndPraise(String targetId,String academicYearId,String code);
@Query("select * from Student as c where c.targetId in (@targetId) and c.classId =@classId and c.academicYearId = @academicYearId and c.code = @code")
List<AppraiseRecord> findAllRecord(List<String> targetId,String classId,String academicYearId,String code);
/** /**
* *
*/ */

@ -18,7 +18,7 @@ public interface StudentRepository extends CosmosRepository<Student, String> {
@Query("select c.pk, c.code, c.id, c.name, c.gender, c.schoolId, c.periodId, c.year, c.createTime, c.picture, c.mail, c.mobile, c.country, c.classId, c.no, c.groupId, c.groupName, c.guardians, c.irs, c.salt from Student as c where c.id = @id and c.code = @code") @Query("select c.pk, c.code, c.id, c.name, c.gender, c.schoolId, c.periodId, c.year, c.createTime, c.picture, c.mail, c.mobile, c.country, c.classId, c.no, c.groupId, c.groupName, c.guardians, c.irs, c.salt from Student as c where c.id = @id and c.code = @code")
List<Student> findByIdAndCode(String id, String code); List<Student> findByIdAndCode(String id, String code);
@Query("select c.id, c.name, c.classId, c.picture from Student as c where c.code = @code and c.id in (@ids)") @Query("select c.id, c.name, c.classId, c.picture, c.periodId from Student as c where c.code = @code and c.id in (@ids)")
List<Student> findAllByCodeAndIdIn(String code, Set<String> ids); List<Student> findAllByCodeAndIdIn(String code, Set<String> ids);
int countByClassIdAndCode(String classId, String code); int countByClassIdAndCode(String classId, String code);

@ -62,6 +62,7 @@ public interface EvaluationService {
* *
*/ */
StudentReportVo studentReport(IdRequest idRequest); StudentReportVo studentReport(IdRequest idRequest);
List<StudentReportVo> Reports(ReportDto reportDto);
void exportStuReportPdf(IdRequest idRequest, HttpServletResponse response) throws IOException, DocumentException; void exportStuReportPdf(IdRequest idRequest, HttpServletResponse response) throws IOException, DocumentException;
} }

@ -36,6 +36,7 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
@ -46,6 +47,9 @@ import java.io.InputStream;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -476,6 +480,190 @@ public class EvaluationServiceImpl implements EvaluationService {
appraiseRecordRepository.save(appraiseRecord); appraiseRecordRepository.save(appraiseRecord);
} }
public List<StudentReportVo> Reports(ReportDto reportDto) {
// 获取当前登录用户和学校信息
//User user = SecurityUtil.getLoginUser();
String schoolId = "hbcn";
// 获取学生 ID 列表
List<String> studentIds = reportDto.getIds();
if (CollectionUtils.isEmpty(studentIds)) {
throw new ServiceException(ErrorCode.PARAM_ERROR.getCode(), "学生 ID 列表不能为空");
}
Set<String> studentIdSet = new HashSet<>(studentIds);
// 批量查询学生信息
List<Student> students = studentRepository.findAllByCodeAndIdIn(String.format(PK.STUDENT, schoolId),studentIdSet);
if (CollectionUtils.isEmpty(students)) {
throw new ServiceException(ErrorCode.OPERATION_ERROR.getCode(), "未找到对应的学生信息");
}
// 获取学段 ID 和班级 ID
String periodId = students.get(0).getPeriodId(); // 假设所有学生属于同一个学段
List<String> classIds = students.stream().map(Student::getClassId).collect(Collectors.toList());
// 查询学期信息
List<School.Semester> semesters = schoolRepository.findSemestersById(schoolId, periodId);
String academicYearId = SchoolDateUtil.calculateAcademicYearId(semesters, LocalDate.now());
// 批量查询评价记录
List<AppraiseRecord> appraiseRecords = appraiseRecordRepository.findAllRecord(
studentIds, classIds.get(0), academicYearId, String.format(PK.PK_APPRAISE_RECORD, schoolId)
);
if (CollectionUtils.isEmpty(appraiseRecords)) {
throw new ServiceException(ErrorCode.OPERATION_ERROR.getCode(), "未找到对应的评价记录");
}
// 查询班级内学生总数
Map<String, Integer> classStudentCountMap = new HashMap<>();
for (String classId : classIds) {
int count = studentRepository.countByClassIdAndCode(classId, String.format(PK.STUDENT, schoolId));
classStudentCountMap.put(classId, count);
}
// 查询成就规则
Appraise appraise = RepositoryUtil.findOne(appraiseRepository.findRulesById(schoolId, periodId), "当前成就规则还未创建");
List<AchievementRule> rules = appraise.getAchievementRules();
if (CollectionUtils.isEmpty(rules)) {
throw new ServiceException(ErrorCode.OPERATION_ERROR.getCode(), "当前成就规则为空");
}
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
List<CompletableFuture<StudentReportVo>> futures = new ArrayList<>();
// 并行处理每个学生的报告生成任务
for (Student student : students) {
CompletableFuture<StudentReportVo> future = CompletableFuture.supplyAsync(() -> {
try {
return generateStudentReport(student, appraiseRecords, classStudentCountMap, rules, academicYearId, schoolId);
} catch (Exception e) {
System.out.println("生成报告失败:" + e.getMessage());
return null;
}
}, executor);
futures.add(future);
}
// 等待所有任务完成并收集结果
List<StudentReportVo> reportVos = futures.stream()
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList());
// 关闭线程池
executor.shutdown();
return reportVos;
}
private StudentReportVo generateStudentReport(Student student, List<AppraiseRecord> appraiseRecords,
Map<String, Integer> classStudentCountMap, List<AchievementRule> rules,
String academicYearId, String schoolId) {
String studentId = student.getId();
String classId = student.getClassId();
// 查找当前学生的评价记录
Optional<AppraiseRecord> appraiseRecordOpt = appraiseRecords.stream()
.filter(record -> record.getTargetId().equals(studentId))
.findFirst();
// 初始化默认值
Map<String, Integer> praiseDistribution = StudentReportVo.ofFiveEducation();
Map<String, Integer> criticalDistribution = StudentReportVo.ofFiveEducation();
List<AppraiseRecordItem> records = Collections.emptyList();
int praiseCount = 0;
float beyondPercent = 0.0f;
AchievementRule curAchievement = rules.get(rules.size() - 1); // 默认使用最低成就规则
int n = 1;
// 如果有评价记录,则填充数据
if (appraiseRecordOpt.isPresent()) {
AppraiseRecord appraiseRecord = appraiseRecordOpt.get();
// 处理评价记录
if (appraiseRecord.getNodes() != null) {
// 计算雷达图数据
for (AppraiseRecordItem record : appraiseRecord.getNodes()) {
AppraiseTreeNode appraiseNode = record.getAppraiseNode();
String[] path = appraiseNode.getPath();
if (path == null || path.length == 0) {
continue;
}
String root = path[0];
String key = FiveEducations.getCodeByName(root);
if (key != null) {
if (appraiseNode.isPraise()) {
praiseDistribution.put(key, praiseDistribution.getOrDefault(key, 0) + 1);
} else {
criticalDistribution.put(key, criticalDistribution.getOrDefault(key, 0) + 1);
}
}
}
// 计算学生排名
praiseCount = appraiseRecord.getPraiseCount();
int greaterCount = appraiseRecordRepository.findClassRecord(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, classId, praiseCount);
int stuInClassCount = classStudentCountMap.get(classId);
beyondPercent = (float) (stuInClassCount - greaterCount) / stuInClassCount;
// 计算成就项 (排序 120(20x3) 60(10x4) 25(5x5) 121
rules = rules.stream().sorted(Comparator.comparing(AchievementRule::getLevel).reversed()).collect(Collectors.toList());
int ruleSize = rules.size();
curAchievement = rules.get(rules.size() - 1);
for (int i = 0; i <= rules.size() - 1; i++) {
AchievementRule curRule = rules.get(i);
int flag = praiseCount / curRule.getPromotionCount();
if (ruleSize == 1) {
n = praiseCount / curRule.getLevelCount() + 1;
break;
}
if (flag >= 1) {
if (i == 0) {
curAchievement = curRule;
AchievementRule lastRule = rules.get(i + 1);
n = (praiseCount - lastRule.getPromotionCount()) / curRule.getLevelCount() + 1;
} else {
AchievementRule nextRule = rules.get(i - 1);
curAchievement = nextRule;
n = (praiseCount - curRule.getPromotionCount()) / nextRule.getLevelCount() + 1;
}
break;
}
if (i == rules.size() - 1) {
n = praiseCount / curRule.getLevelCount() + 1;
}
}
// 获取记录
records = appraiseRecord.getNodes().stream()
.sorted(Comparator.comparing(AppraiseRecordItem::getCreateTime).reversed())
.collect(Collectors.toList());
}
}
// 构建报告
return StudentReportVo.builder()
.name(student.getName())
.studentId(studentId)
.className(student.getClassId()) // 假设班级名可以从学生信息中获取
.praiseCount(praiseCount)
.score(appraiseRecordOpt.isPresent() ? appraiseRecordOpt.get().getScore() : 0) // 默认分数为 0
.beyondPercent(beyondPercent)
.topPraiseTeacher(new StudentReportVo.Teacher(null, null)) // 默认值为 null
.topCriticalTeacher(new StudentReportVo.Teacher(null, null)) // 默认值为 null
.topPraiseNode(null) // 默认值为 null
.topCriticalNode(null) // 默认值为 null
.praiseDistribution(praiseDistribution)
.criticalDistribution(criticalDistribution)
.curAchievement(curAchievement)
.achievementN(n)
.records(records)
.build();
}
@Override @Override
public StudentReportVo studentReport(IdRequest idRequest) { public StudentReportVo studentReport(IdRequest idRequest) {
String studentId = idRequest.getId(); String studentId = idRequest.getId();

Loading…
Cancel
Save