diff --git a/src/main/java/cn/teammodel/controller/admin/controller/TeacherController.java b/src/main/java/cn/teammodel/controller/admin/controller/TeacherController.java index 825a6c0..5b80c65 100644 --- a/src/main/java/cn/teammodel/controller/admin/controller/TeacherController.java +++ b/src/main/java/cn/teammodel/controller/admin/controller/TeacherController.java @@ -142,4 +142,16 @@ public class TeacherController { teacherService.dataSync(gpTeacherDtos,request); return R.success("同步成功"); } + @PostMapping("getPtTeacher") + @ApiOperation("获取教师基础信息加上五大能力得分") + public R>> getPtTeacher(@Valid @RequestBody TeacherDto teacherDto, HttpServletRequest request) { + List> res = teacherService.getPtTeacher(teacherDto,request); + return R.success(res); + } + @PostMapping("saveFiveScores") + @ApiOperation("保存教师 五大能力得分--暂时用不上") + public R saveFiveScores(@Valid @RequestBody TeacherDto teacherDto, HttpServletRequest request) { + teacherService.saveFiveScores(teacherDto,request); + return R.success("保存成功"); + } } diff --git a/src/main/java/cn/teammodel/controller/admin/service/TeacherService.java b/src/main/java/cn/teammodel/controller/admin/service/TeacherService.java index f80791f..d1ce266 100644 --- a/src/main/java/cn/teammodel/controller/admin/service/TeacherService.java +++ b/src/main/java/cn/teammodel/controller/admin/service/TeacherService.java @@ -32,4 +32,6 @@ public interface TeacherService { List> findTeachers(CoreUser dto, HttpServletRequest request); List saveOrUpdate(GpTeacherRequest gpTeacherRequest, HttpServletRequest request); void dataSync(GpTeacherRequest gpTeacherRequest, HttpServletRequest request); + List > getPtTeacher(TeacherDto teacherDto, HttpServletRequest request); + void saveFiveScores(TeacherDto teacherDto, HttpServletRequest request); } diff --git a/src/main/java/cn/teammodel/controller/admin/service/impl/TeacherServiceImpl.java b/src/main/java/cn/teammodel/controller/admin/service/impl/TeacherServiceImpl.java index b585672..5fe09a3 100644 --- a/src/main/java/cn/teammodel/controller/admin/service/impl/TeacherServiceImpl.java +++ b/src/main/java/cn/teammodel/controller/admin/service/impl/TeacherServiceImpl.java @@ -49,6 +49,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import static cn.teammodel.utils.SchoolDateUtil.calculateWeekNum; +import static java.lang.Double.parseDouble; @Service public class TeacherServiceImpl implements TeacherService { @@ -80,6 +81,11 @@ public class TeacherServiceImpl implements TeacherService { @Autowired private Environment env; private static final double K = 0.08; // 衰减系数常量 + private static final double T_DATA_COEFFICIENT = 25.0; + private static final double T_GREEN_COEFFICIENT = 50.0; + private static final double LESSON_COEFFICIENT = 15.0; + private static final double PAPER_COEFFICIENT = 10.0; + private static final double BASE_SCORE = 60.0; // 添加日志对象 private static final Logger logger = LoggerFactory.getLogger(TeacherServiceImpl.class); @@ -1983,6 +1989,349 @@ public class TeacherServiceImpl implements TeacherService { } } + @Override + public List> getPtTeacher(TeacherDto teacherDto, HttpServletRequest request) { + String code = String.format(PK.PTTEACHER, teacherDto.getCode()); + String LessonCode = String.format(PK.PK_LESSON_RECORD, teacherDto.getCode()); + List> ptTeachers = new ArrayList<>(); + try { + List ptTeacherInfos = ptTeacherRepository.findAllTeacher(teacherDto.getCode(), code); + //获取ptTeacherInfos中所有的老师ID + List teacherIds = ptTeacherInfos.stream().map(PtTeacherInfo::getId).collect(Collectors.toList()); + //整合教研 教学数据 + List> list = extracted(teacherDto, request, LessonCode, teacherIds); + Map teachingScore = new HashMap<>(); + Map researchScore = new HashMap<>(); + for (Map map : list) { + String teacherId = (String) map.get("teacherId"); + double tGreen = ((Number) map.get("t_green")).doubleValue(); + double totalTeachingScore; + double totalResearchScore; + + // 先处理特殊规则 + if (tGreen == 1.0) { + totalTeachingScore = BASE_SCORE; + } else { + // 延迟获取其他字段值(当tGreen>1时才需要计算) + double tData = ((Number) map.get("t_data")).doubleValue(); + double paperCount = ((Number) map.get("paperCount")).doubleValue(); + double lessonRecordCount = ((Number) map.get("lessonRecordCount")).doubleValue(); + + // 计算各维度分数 + double tDataScore = calculateScore(T_DATA_COEFFICIENT, tData); + double tGreenScore = calculateScore(T_GREEN_COEFFICIENT, tGreen); + double lessonsScore = calculateScore(LESSON_COEFFICIENT, lessonRecordCount); + double paperScore = calculateScore(PAPER_COEFFICIENT, paperCount); + + totalTeachingScore = tDataScore + tGreenScore + lessonsScore + paperScore; + + // 处理tGreen >1 的情况 + if (tGreen > 1.0) { + totalTeachingScore = BASE_SCORE + totalTeachingScore * 0.4; + } + } + // 统一格式化结果(仅保留两位小数) + totalTeachingScore = Math.round(totalTeachingScore * 100.0) / 100.0; + + // 后续处理 + teachingScore.put(teacherId, totalTeachingScore); + //处理教研得分 + double DoubleGreenCount = ((Number) map.get("double_green_count")).doubleValue(); + double LessonCount = ((Number) map.get("lesson_count")).doubleValue(); + double ObserveLessons = ((Number) map.get("ObserveLessons")).doubleValue(); + double PublicCount = ((Number) map.get("PublicCount")).doubleValue(); + + // 基础分计算 + double baseScore = calculateScore(40,DoubleGreenCount); + double lessonScore = calculateScore(20,LessonCount); + double materialScore = calculateScore(30,ObserveLessons); + double publicScore = calculateScore(10,PublicCount); + totalResearchScore = baseScore + lessonScore + materialScore + publicScore; + totalResearchScore = Math.round(totalResearchScore * 100.0) / 100.0; + researchScore.put(teacherId, totalResearchScore); + + } + + GpTeacherDto gpTeacherDto = new GpTeacherDto(); + gpTeacherDto.setOwnerIds(teacherIds); + gpTeacherDto.setIds(teacherIds); + gpTeacherDto.setSchoolId(teacherDto.getCode()); + //获取所有老师对应的荣誉数量 + Map honorScore = getHonorScore(gpTeacherDto, request, teacherIds); + //处理研修数据 + Map trainingScore = extracted(request, gpTeacherDto, teacherIds); + + if (!ptTeacherInfos.isEmpty()) { + for (PtTeacherInfo ptTeacherInfo : ptTeacherInfos) { + Map ptTeacher = new HashMap<>(); + ptTeacher.put("id", ptTeacherInfo.getId()); + ptTeacher.put("name", ptTeacherInfo.getName()); + ptTeacher.put("gradeName", ptTeacherInfo.getGradeName()); + ptTeacher.put("subjectName", ptTeacherInfo.getSubjectNames()); + ptTeacher.put("teachingAge", ptTeacherInfo.getTeachingAge()); + ptTeacher.put("teachingScore", teachingScore.get(ptTeacherInfo.getId())); + ptTeacher.put("researchScore", researchScore.get(ptTeacherInfo.getId())); + ptTeacher.put("honorScore", honorScore.get(ptTeacherInfo.getId())); + ptTeacher.put("trainingScore", trainingScore.get(ptTeacherInfo.getId())); + ptTeacher.put("scientificScore", 60); +// ptTeacher.put("teachingScore", ptTeacherInfo.getTeachingScore()); +// ptTeacher.put("researchScore", ptTeacherInfo.getResearchScore()); +// ptTeacher.put("honorScore", ptTeacherInfo.getHonorScore()); +// ptTeacher.put("trainingScore", ptTeacherInfo.getTrainingScore()); +// ptTeacher.put("scientificScore", ptTeacherInfo.getScientificScore()); + ptTeachers.add(ptTeacher); + } + } + return ptTeachers; + } catch (Exception e) { + throw new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "获取数据异常"); + } + } + + // 指数衰减计算函数封装 + private static double calculateScore(double coefficient, double value) { + return coefficient * (1 - Math.exp(-K * value)); + } + + private List> extracted(TeacherDto teacherDto, HttpServletRequest request, String LessonCode, List teacherIds) { + List sugVos = getSugVos(teacherDto, request); + //根据SugVo中habook分类聚合 每个老师的其他数据求和 + List> sug = extracted(sugVos); + //获取当前条件下所有的课程记录 + List lessonRecords = lessonRecordRepository.findAllIds(LessonCode, teacherDto.getPeriodId(), teacherDto.getStartTime(), teacherDto.getEndTime(), teacherDto.getSubjectId()); + //筛选出每个tmdid的总数量 + Map lessonRecordCount = new HashMap<>(); + for (LessonRecord lessonRecord : lessonRecords) { + lessonRecordCount.put(lessonRecord.getTmdid(), lessonRecordCount.getOrDefault(lessonRecord.getTmdid(), 0) + 1); + } + //获取该学校该学段所有的试卷数量 + Map paperCount = new HashMap<>(); + List paperTeachers = paperTeacherRepository.getAllPaperCode(); + for (PaperTeacher paperTeacher : paperTeachers) { + for (String teacherId : teacherIds) { + if (paperTeacher.getCode().contains(teacherId)) { + paperCount.put(teacherId, paperCount.getOrDefault(teacherId, 0) + 1); + } + } + } + //将sug lessonRecordCount paperCount 数据整合 并返回 List> 以sug 为准 + List> integratedList = new ArrayList<>(); + for (String teacherId : teacherIds) { + // 1. 初始化默认值 + int t_data = 0; + int t_green = 0; + int PublicCount = 0; + int double_green_count = 0; + int lesson_count = 0; + int ObserveLessons = 0; + + // 2. 从 sug 中提取该教师的数据(如果存在) + Optional> sugItemOptional = sug.stream() + .filter(item -> teacherId.equals(item.get("habook"))) + .findFirst(); + + if (sugItemOptional.isPresent()) { + Map sugItem = sugItemOptional.get(); + t_data = (int) sugItem.getOrDefault("t_data", 0); + t_green = (int) sugItem.getOrDefault("t_green", 0); + PublicCount = (int) sugItem.getOrDefault("PublicCount", 0); + double_green_count = (int) sugItem.getOrDefault("double_green_count", 0); + lesson_count = (int) sugItem.getOrDefault("lesson_count", 0); + ObserveLessons = (int) sugItem.getOrDefault("ObserveLessons", 0); + } + + // 3. 从 lessonRecordCount 中获取课程记录数量 + int lessonRecordCountVal = lessonRecordCount.getOrDefault(teacherId, 0); + + // 4. 从 paperCount 中获取试卷数量 + int paperCountVal = paperCount.getOrDefault(teacherId, 0); + + // 5. 构造结果项 + Map integratedItem = new HashMap<>(); + integratedItem.put("teacherId", teacherId); // 明确标识教师 ID + integratedItem.put("t_data", t_data); + integratedItem.put("t_green", t_green); + integratedItem.put("PublicCount", PublicCount); + integratedItem.put("double_green_count", double_green_count); + integratedItem.put("lesson_count", lesson_count); + integratedItem.put("ObserveLessons", ObserveLessons); + integratedItem.put("lessonRecordCount", lessonRecordCountVal); + integratedItem.put("paperCount", paperCountVal); + + integratedList.add(integratedItem); + } + return integratedList; + } + + private @NotNull Map getHonorScore(GpTeacherDto gpTeacherDto, HttpServletRequest request, List teacherIds) { + Map honorCount = new HashMap<>(); + Map honorScoreMap = new HashMap<>(); + Map honor = getTeacherHonors(gpTeacherDto, request); + List honors = new ArrayList<>(); + Object honorsObj = honor.get("honors"); + if (honorsObj instanceof List) { + List rawHonors = (List) honorsObj; + + for (Object item : rawHonors) { + if (item instanceof Map) { + Map map = (Map) item; + HonorInfo info = new HonorInfo(); + + // 手动设置属性,假设 HonorInfo 有对应的 setter 方法 + info.setScore((Integer) map.get("score")); // 根据字段名称匹配 + info.setOwnerId((String) map.get("ownerId")); + // 设置其他字段 + // info.setHonorName((String) map.get("honorName")); + honors.add(info); + } else if (item instanceof HonorInfo) { + honors.add((HonorInfo) item); + } + } + } + //根据返回honors 相同的ownerId 对应的score相加 + for (HonorInfo honorInfo : honors) { + String ownerId = honorInfo.ownerId; + if (ownerId == null) { + continue; // 忽略 ownerId 为 null 的项 + } + Integer score = honorInfo.score; + int currentScore = (score != null) ? score : 0; // 处理 score 为 null 的情况 + honorCount.merge(ownerId, currentScore, Integer::sum); // 累加分数 + } + //换算每个老师的荣誉得分 + for (String id : teacherIds) { + double honorScore = 0; + for (Map.Entry entry : honorCount.entrySet()) { + String ownerId = entry.getKey(); + if (id.equals(ownerId)) { + Integer score = entry.getValue(); + honorScore = score > 0 ? Math.round(100.0 - (165.0 / (score + 4.5))) : 60; + honorScoreMap.put(ownerId, honorScore); + } + } + honorScoreMap.put(id, honorScore); + } + return honorScoreMap; + } + + private Map extracted(HttpServletRequest request, GpTeacherDto gpTeacherDto, List teacherIds) { + + Map trainingMapOfTeacher = new HashMap<>(); + Map training = getTeacherTraining(gpTeacherDto, request); + List> trainings = (List>) training.get("persons"); + for (String id : teacherIds) { + double TrainingScore = 0; + if (!trainings.isEmpty()) { + for (Map trainingMap : trainings) { + if (id.equals(trainingMap.get("id"))) { + Object scoreObj = trainingMap.get("studyHour"); + Object isJoin = trainingMap.get("isJoin"); + if(isJoin instanceof Boolean) { + if ((boolean) isJoin) { + double score = 60; + double hourScore = 0; + if (scoreObj instanceof Integer) { + int hour = (int) scoreObj; + if (hour > 0) { + hourScore = 40 * (1 - Math.exp(-K * hour)); + } + } + TrainingScore += (score + hourScore); + } else { + TrainingScore += 0; + } + } + } + } + } + if (TrainingScore > 0) { + //保留两位小数 + TrainingScore = Double.parseDouble(String.format("%.2f", TrainingScore)); + } + trainingMapOfTeacher.put(id, TrainingScore); + } + return trainingMapOfTeacher; + } + + private static List> extracted(List sugVos) { + Map> sugVosMap = sugVos.stream().collect(Collectors.groupingBy(SugVo::getHabook)); + // 构造结果列表 + List> result = new ArrayList<>(); + sugVosMap.forEach((habook, vos) -> { + // 初始化各字段的累加器 + int t_data = 0; + int t_green = 0; + int PublicCount = 0; + int double_green_count = 0; + int lesson_count = 0; + int ObserveLessons = 0; + + // 遍历当前分组的所有 SugVo 对象进行累加 + for (SugVo vo : vos) { + t_data += (vo.getT_data() != null) ? vo.getT_data() : 0; + t_green += (vo.getT_green() != null) ? vo.getT_green() : 0; + //教研数据 + PublicCount += (vo.getPublic_count() != null) ? vo.getPublic_count() : 0; + double_green_count += (vo.getDouble_green_count() != null) ? vo.getDouble_green_count() : 0; + lesson_count += (vo.getLesson_count() != null) ? vo.getLesson_count() : 0; + if (vo.getObserve_lessons() != null) { + Set observeLessons = new HashSet<>((List) vo.getObserve_lessons()); + // 如果后续需要使用 observeLessons,可以在此处添加逻辑 + ObserveLessons += observeLessons.size(); + } + } + + // 构造单个结果项(平铺结构) + Map item = new HashMap<>(); + item.put("habook", habook); + item.put("t_data", t_data); + item.put("t_green", t_green); + item.put("PublicCount", PublicCount); + item.put("double_green_count", double_green_count); + item.put("lesson_count", lesson_count); + item.put("ObserveLessons", ObserveLessons); + + result.add(item); + }); + return result; + } + + public void saveFiveScores(TeacherDto teacherDto, HttpServletRequest request) { + String code = String.format(PK.PTTEACHER, teacherDto.getCode()); + try { + List ptTeacherInfos = ptTeacherRepository.findAllTeacher(teacherDto.getCode(), code); + if (!ptTeacherInfos.isEmpty()) { + List teachers = ptTeacherInfos.stream() + .peek(ptTeacherInfo -> { + Map scores = getTeacherOfCapabilityAssessment(teacherDto, request); + ptTeacherInfo.setTeachingScore(parseScore(scores.get("teachingScore"), 0.0)); + ptTeacherInfo.setResearchScore(parseScore(scores.get("researchScore"), 0.0)); + ptTeacherInfo.setHonorScore(parseScore(scores.get("honorScore"), 0.0)); + ptTeacherInfo.setTrainingScore(parseScore(scores.get("trainingScore"), 0.0)); + ptTeacherInfo.setScientificScore(parseScore(scores.get("scientificScore"), 0.0)); + + }) + .collect(Collectors.toList()); + + ptTeacherRepository.saveAll(teachers); + } + + } catch (Exception e) { + throw new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "获取数据异常"); + } + } + + private Double parseScore(Object obj, double defaultValue) { + if (obj instanceof Number) { + return ((Number) obj).doubleValue(); + } else if (obj instanceof String) { + try { + return Double.parseDouble((String) obj); + } catch (NumberFormatException ignored) {} + } + return defaultValue; + } + // 手机号正则表达式(中国大陆) private static final String PHONE_REGEX = "^1\\d{10}$"; /** diff --git a/src/main/java/cn/teammodel/model/dto/admin/teacher/PtDto.java b/src/main/java/cn/teammodel/model/dto/admin/teacher/PtDto.java new file mode 100644 index 0000000..f1de994 --- /dev/null +++ b/src/main/java/cn/teammodel/model/dto/admin/teacher/PtDto.java @@ -0,0 +1,11 @@ +package cn.teammodel.model.dto.admin.teacher; + +import lombok.Data; + +import java.util.List; + +@Data +public class PtDto { + private String code; + private List ids; +} diff --git a/src/main/java/cn/teammodel/model/entity/school/PaperTeacher.java b/src/main/java/cn/teammodel/model/entity/school/PaperTeacher.java index 312cc2e..7a5fe6f 100644 --- a/src/main/java/cn/teammodel/model/entity/school/PaperTeacher.java +++ b/src/main/java/cn/teammodel/model/entity/school/PaperTeacher.java @@ -15,5 +15,7 @@ import lombok.EqualsAndHashCode; @JsonInclude(JsonInclude.Include.NON_NULL) public class PaperTeacher extends BaseItem { + public String pk; + public String code; } diff --git a/src/main/java/cn/teammodel/model/entity/teacher/PtTeacherInfo.java b/src/main/java/cn/teammodel/model/entity/teacher/PtTeacherInfo.java index db9fe7c..2183a84 100644 --- a/src/main/java/cn/teammodel/model/entity/teacher/PtTeacherInfo.java +++ b/src/main/java/cn/teammodel/model/entity/teacher/PtTeacherInfo.java @@ -47,4 +47,9 @@ public class PtTeacherInfo extends BaseItem { public Integer state = 1; public Integer version = 1; public String source; + private Double teachingScore; // 教学分数 + private Double researchScore; // 教研分数 + private Double honorScore; // 荣誉分数 + private Double trainingScore; // 培训分数 + private Double scientificScore; // 科研分数 } diff --git a/src/main/java/cn/teammodel/repository/LessonRecordRepository.java b/src/main/java/cn/teammodel/repository/LessonRecordRepository.java index 8ed6041..5e72fbf 100644 --- a/src/main/java/cn/teammodel/repository/LessonRecordRepository.java +++ b/src/main/java/cn/teammodel/repository/LessonRecordRepository.java @@ -33,5 +33,10 @@ public interface LessonRecordRepository extends CosmosRepository404 and c.periodId = @periodId and" + "(IS_NULL(@subjectId) or c.subjectId = @subjectId) ") Slice findAll(String code,String subjectId,String periodId,Pageable pageable); + @Query("select c.tmdid from LessonRecord as c where c.code = @code and c.expire<=0 and c.status<>404 and c.periodId = @periodId and" + + "(IS_NULL(@startTime) OR c.startTime >= @startTime) and " + + "(IS_NULL(@endTime) OR c.startTime <= @endTime) and "+ + "(IS_NULL(@subjectId) or c.subjectId = @subjectId) ") + List findAllIds(String code,String periodId,Long startTime, Long endTime ,String subjectId); } diff --git a/src/main/java/cn/teammodel/repository/PaperTeacherRepository.java b/src/main/java/cn/teammodel/repository/PaperTeacherRepository.java index a3c4fc9..ab6c50d 100644 --- a/src/main/java/cn/teammodel/repository/PaperTeacherRepository.java +++ b/src/main/java/cn/teammodel/repository/PaperTeacherRepository.java @@ -11,4 +11,6 @@ import java.util.List; public interface PaperTeacherRepository extends CosmosRepository{ @Query("select value count(1) from c where c.pk='Paper' and c.code=@code") int getPaperCount(String code); + @Query("select c.code from c where c.pk='Paper'") + List getAllPaperCode(); } diff --git a/src/main/java/cn/teammodel/repository/PtTeacherRepository.java b/src/main/java/cn/teammodel/repository/PtTeacherRepository.java index c28f81b..0d0390b 100644 --- a/src/main/java/cn/teammodel/repository/PtTeacherRepository.java +++ b/src/main/java/cn/teammodel/repository/PtTeacherRepository.java @@ -20,5 +20,7 @@ public interface PtTeacherRepository extends CosmosRepository findAllTeacher(String school,String code); @Query(value = "SELECT * FROM c WHERE c.pk = 'PtTeacher' and c.code = @code and c.state = 1 and c.status != 'delete' ") List findByCode(String code); + @Query(value = "SELECT * FROM c WHERE c.pk = 'PtTeacher' and c.state = 1 and c.status != 'delete' ") + List findAllTeacher(); }