package com.xinyilu.system.service.kinderPhysiqueAnalysis.impl;

import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.core.domain.AjaxResult;
import com.xinyilu.common.enums.ItemCodeEnums;
import com.xinyilu.common.utils.AgeUtil;
import com.xinyilu.common.utils.BigDecimalUtil;
import com.xinyilu.system.domain.systemarea.SysArea;
import com.xinyilu.system.domain.testLevel.TestItemLevel;
import com.xinyilu.system.domain.vo.kinderPhysiqueAnalysis.*;
import com.xinyilu.system.mapper.kindergarteninfo.KindergartenInfoMapper;
import com.xinyilu.system.mapper.studentInfo.StudentInfoMapper;
import com.xinyilu.system.mapper.systemarea.SysAreaMapper;
import com.xinyilu.system.service.kinderPhysiqueAnalysis.KinderPhysiqueAnalysisService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description 幼儿园体质综合分析业务层实现类
 * @Author 纪寒
 * @Date 2022-08-15 18:36:13
 * @Version 1.0
 */
@Service
public class KinderPhysiqueAnalysisServiceImpl implements KinderPhysiqueAnalysisService {

    @Resource
    private KindergartenInfoMapper kindergartenInfoMapper;
    @Resource
    private StudentInfoMapper studentInfoMapper;
    @Resource
    private SysAreaMapper sysAreaMapper;

    /**
     * 根据幼儿园id和批次信息查询综合体质分析数据
     *
     * @param kindergartenId 幼儿园id
     * @param batchCode      批次编号
     * @param studentSex     性别
     * @return AjaxResult 综合体质分析数据
     * @throws Exception 异常信息
     */
    @Override
    public AjaxResult getKinderPhysiqueAnalysis(Long kindergartenId, String batchCode, String studentSex) throws Exception {
        //查询一级分类的得分信息
        List<KinderCategoryScoreVO> kinderCategoryScoreList = kindergartenInfoMapper.getFirstKinderCategoryScoreInfo(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        if (CollectionUtils.isEmpty(kinderCategoryScoreList)) {
            return AjaxResult.success();
        }
        //一级分类父级id
        List<KinderCategoryScoreVO> getTestItemCategoryParentId = kindergartenInfoMapper.getTestItemCategoryParentId(ItemCodeEnums.BMI_CODE.getInfo());
        if (CollectionUtils.isEmpty(getTestItemCategoryParentId)) {
            return AjaxResult.success();
        }
        //该学校、该批次、该性别的总人数
        Long studentCount = kindergartenInfoMapper.getStudentCount(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        //计算每个一级分类的平均得分
        for (KinderCategoryScoreVO kinderCategoryScoreVO : kinderCategoryScoreList) {
            kinderCategoryScoreVO.setParentId(getTestItemCategoryParentId.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getItemCode()) && item.getItemCode().equals(kinderCategoryScoreVO.getItemCode())).findFirst().orElseGet(KinderCategoryScoreVO::new).getParentId());
            kinderCategoryScoreVO.setId(getTestItemCategoryParentId.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getItemCode()) && item.getItemCode().equals(kinderCategoryScoreVO.getItemCode())).findFirst().orElseGet(KinderCategoryScoreVO::new).getId());
            kinderCategoryScoreVO.setCategoryName(getTestItemCategoryParentId.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getItemCode()) && item.getItemCode().equals(kinderCategoryScoreVO.getItemCode())).findFirst().orElseGet(KinderCategoryScoreVO::new).getCategoryName());
        }
        Map<Long, List<KinderCategoryScoreVO>> firstCategoryMap = kinderCategoryScoreList.stream().filter(item -> Objects.nonNull(item.getParentId())).collect(Collectors.groupingBy(KinderCategoryScoreVO::getParentId));
        if (firstCategoryMap.isEmpty()) {
            return AjaxResult.success();
        }
        KinderPhysiqueAnalysisVO analysisVO = new KinderPhysiqueAnalysisVO();
        this.getFirstCategoryInfo(firstCategoryMap, analysisVO, studentCount, kinderCategoryScoreList);
        //查询每个分类的成绩信息
        List<KinderCategoryScoreVO> categoryScoreInfoList = kindergartenInfoMapper.getKinderCategoryScoreInfo(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        if (CollectionUtils.isEmpty(categoryScoreInfoList)) {
            return AjaxResult.success(analysisVO);
        }
        //查询每个分类的得分区间信息
        List<Long> categoryIdList = categoryScoreInfoList.stream().filter(item -> Objects.nonNull(item.getId())).map(KinderCategoryScoreVO::getId).distinct().collect(Collectors.toList());
        Map<Long, List<TestItemLevel>> itemLevelMap = studentInfoMapper.getTestItemLevelByCategoryId(categoryIdList).stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getItemCategoryId())).collect(Collectors.groupingBy(TestItemLevel::getItemCategoryId));
        if (itemLevelMap.isEmpty()) {
            return AjaxResult.success(analysisVO);
        }
        //计算每个分类的平均得分以及每个分类的平均得分描述信息网状图
        this.getCategoryLevelInfo(categoryScoreInfoList, itemLevelMap, analysisVO, studentCount);
        //计算不同年龄段的各分类的平均得分 -查询分类项目信息总成绩（含重复成绩）及学生日期
        List<KinderCategoryScoreVO> categoryScoreAndStudentBirthDate = kindergartenInfoMapper.getCategoryScoreAndStudentBirthDate(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        for (KinderCategoryScoreVO kinderCategoryScoreVO : categoryScoreAndStudentBirthDate) {
            if (Objects.nonNull(kinderCategoryScoreVO.getBirthDate())) {
                kinderCategoryScoreVO.setStudentAge(AgeUtil.getStudentAgeMonth(kinderCategoryScoreVO.getBirthDate().toString()));
            }
        }
        List<Long> categoryScoreId = categoryScoreAndStudentBirthDate.stream().filter(item -> Objects.nonNull(item.getId())).map(KinderCategoryScoreVO::getId).distinct().collect(Collectors.toList());
        List<CategoryScoreVO> ageTotalScore = computeAgeTotalScore(kindergartenId, batchCode, studentSex);
        List<CategoryScoreVO> categoryAvgScoreInfo = this.getCategoryAvgScoreInfo(categoryScoreAndStudentBirthDate, ageTotalScore, categoryScoreId);
        //求全园平均成绩
        List<FirstCategoryScoreVO> avgKinderCategoryScoreInfo = kindergartenInfoMapper.getAvgKinderCategoryScoreInfo(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        avgKinderCategoryScoreInfo.forEach(item -> {
            if (studentCount != 0 && Objects.nonNull(item.getAvgCategoryFraction())) {
                item.setAvgCategoryFraction(BigDecimalUtil.getAvgScore(BigDecimal.valueOf(studentCount), item.getAvgCategoryFraction()));
            }
        });
        CategoryScoreVO avgKinderCategoryScore = new CategoryScoreVO();
        avgKinderCategoryScore.setStudentAge("全园平均分");
        avgKinderCategoryScore.setTotalAvgFraction(analysisVO.getTotalAvgFraction());
        avgKinderCategoryScore.setCategoryAvgFractionList(avgKinderCategoryScoreInfo);
        categoryAvgScoreInfo.add(avgKinderCategoryScore);
        //全市平均成绩
        this.getAvgCityScoreIno(kindergartenId, studentSex, batchCode, categoryAvgScoreInfo, analysisVO);
        //区表头信息
        setCategoryTableName(avgKinderCategoryScoreInfo, analysisVO);
        return AjaxResult.success(analysisVO);
    }

    /**
     * 计算一级分类的得分平得分信息
     *
     * @param firstCategoryMap 输入参数
     * @param analysisVO       返回值信息
     */
    private void getFirstCategoryInfo(Map<Long, List<KinderCategoryScoreVO>> firstCategoryMap,
                                      KinderPhysiqueAnalysisVO analysisVO, Long studentCount, List<KinderCategoryScoreVO> kinderCategoryScoreList) {
        List<FirstCategoryScoreVO> firstCategoryScoreList = Lists.newArrayList();
        for (Map.Entry<Long, List<KinderCategoryScoreVO>> categoryEntry : firstCategoryMap.entrySet()) {
            List<KinderCategoryScoreVO> categoryScoreList = categoryEntry.getValue();
            if (CollectionUtils.isEmpty(categoryScoreList)) {
                continue;
            }
            //每个分类的总成绩相加
            BigDecimal totalScore = categoryScoreList.stream().filter(item -> Objects.nonNull(item.getItemFraction())).map(KinderCategoryScoreVO::getItemFraction).reduce(BigDecimal.ZERO, BigDecimal::add);
            FirstCategoryScoreVO categoryScoreVO = new FirstCategoryScoreVO();
            categoryScoreVO.setCategoryName(categoryScoreList.get(0).getCategoryName());
            if (Objects.nonNull(totalScore) && studentCount != 0) {
                categoryScoreVO.setAvgCategoryFraction(BigDecimalUtil.getAvgScore(BigDecimal.valueOf(studentCount), totalScore));
            } else {
                categoryScoreVO.setAvgCategoryFraction(BigDecimal.ZERO);
            }
            firstCategoryScoreList.add(categoryScoreVO);
        }
        //一级分类总的平均得分
        BigDecimal bigDecimal = kinderCategoryScoreList.stream().map(KinderCategoryScoreVO::getItemFraction).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
        analysisVO.setTotalAvgFraction(bigDecimal.divide(new BigDecimal(studentCount), 2, BigDecimal.ROUND_HALF_UP));
        //一级分类平得分集合信息
        analysisVO.setFirstCategoryScoreList(firstCategoryScoreList);
    }

    /**
     * 每个分类的得分区间信息
     *
     * @param categoryScoreInfoList 每个分类的成绩信息
     * @param itemLevelMap          分类信息键值对
     * @param analysisVO            返回值信息
     * @throws Exception 异常信息
     */
    private void getCategoryLevelInfo(List<KinderCategoryScoreVO> categoryScoreInfoList,
                                      Map<Long, List<TestItemLevel>> itemLevelMap,
                                      KinderPhysiqueAnalysisVO analysisVO,
                                      Long studentNum) throws Exception {
        //计算每个分类的平均得分以及每个分类的平均得分描述信息
        for (KinderCategoryScoreVO score : categoryScoreInfoList) {
            List<TestItemLevel> itemLevelList = itemLevelMap.getOrDefault(Objects.isNull(score.getId()) ? 0 : score.getId(), Lists.newArrayList());
            for (TestItemLevel level : itemLevelList) {
                setCategoryName(score, level, studentNum);
            }
            //求每个区间的最高得分
            List<BigDecimal> minScoreList = itemLevelList.stream().filter(item -> Objects.nonNull(item.getLevelMinScore())).map(TestItemLevel::getLevelMinScore).distinct().collect(Collectors.toList());
            List<BigDecimal> maxScoreList = itemLevelList.stream().filter(item -> Objects.nonNull(item.getLevelMaxScore())).map(TestItemLevel::getLevelMaxScore).distinct().collect(Collectors.toList());
            List<BigDecimal> scoreList = Lists.newArrayList();
            scoreList.addAll(minScoreList);
            scoreList.addAll(maxScoreList);
            BigDecimal max = BigDecimal.ZERO;
            if (CollectionUtils.isNotEmpty(scoreList)) {
                max = Collections.max(scoreList);
            }
            score.setMaxFraction(max);
        }
        //将一级分类区间信息去除
        List<KinderCategoryScoreVO> distinctScoreList = categoryScoreInfoList.stream().filter(item -> Objects.nonNull(item.getId())).distinct().collect(Collectors.toList());
        analysisVO.setCategoryScoreList(distinctScoreList);
    }

    /**
     * 设置平均得分区间描述信息
     *
     * @param score 得分信息
     * @param level 得分区间标准信息
     */
    private void setCategoryName(KinderCategoryScoreVO score, TestItemLevel level, Long studentNum) throws Exception {
        if (Objects.nonNull(score.getItemFraction()) && Objects.nonNull(level.getLevelMinScore())
                && Objects.nonNull(level.getLevelMaxScore())) {
            score.setAvgItemFraction(score.getItemFraction().divide(new BigDecimal(studentNum), 2, BigDecimal.ROUND_HALF_UP));
            if ((score.getAvgItemFraction().compareTo(level.getLevelMinScore()) >= 0
                    && score.getAvgItemFraction().compareTo(level.getLevelMaxScore()) <= 0)) {
                //得分区间信息
                score.setAvgCategoryName(StringUtils.isBlank(level.getLevelName()) ? "" : level.getLevelName());
            }
        }
    }

    /**
     * 计算不同年龄段的分类平均得分信息
     *
     * @param studentBirthDate 分类得分信息集合
     * @param categoryIdList   分类id集合
     * @return List<CategoryScoreVO> 不同年龄段每个分类的平均成绩信息
     */
    private List<CategoryScoreVO> getCategoryAvgScoreInfo(List<KinderCategoryScoreVO> studentBirthDate, List<CategoryScoreVO> ageTotalScore, List<Long> categoryIdList) {
        Map<Double, List<KinderCategoryScoreVO>> studentAgeMap = studentBirthDate.stream()
                .filter(item -> Objects.nonNull(item.getStudentAge()) && item.getStudentAge() != 0)
                .collect(Collectors.groupingBy(KinderCategoryScoreVO::getStudentAge));
        List<CategoryScoreVO> categoryAgeFractionList = Lists.newArrayList();
        for (Map.Entry<Double, List<KinderCategoryScoreVO>> studentAgeEntry : studentAgeMap.entrySet()) {
            CategoryScoreVO categoryScoreVO = new CategoryScoreVO();
            //年龄
            categoryScoreVO.setStudentAge(Objects.isNull(studentAgeEntry.getKey()) ? "0.0" : studentAgeEntry.getKey() + "岁");
            //每个分类的信息
            List<KinderCategoryScoreVO> scoreList = CollectionUtils.isEmpty(studentAgeEntry.getValue()) ? Lists.newArrayList() : studentAgeEntry.getValue();
            Map<Long, List<KinderCategoryScoreVO>> categoryIdMap = scoreList.stream().filter(item -> Objects.nonNull(item.getId())).collect(Collectors.groupingBy(KinderCategoryScoreVO::getId));
            //每个分类的平均得分
            List<FirstCategoryScoreVO> categoryAvgFractionList = Lists.newArrayList();
            for (Long categoryId : categoryIdList) {
                List<KinderCategoryScoreVO> categoryList = categoryIdMap.getOrDefault(categoryId, Lists.newArrayList());
                if (CollectionUtils.isEmpty(categoryList)) {
                    continue;
                }
                FirstCategoryScoreVO firstCategoryScoreVO = new FirstCategoryScoreVO();
                //分类id
                firstCategoryScoreVO.setCategoryId(categoryId);
                //分类名称
                firstCategoryScoreVO.setCategoryName(categoryList.get(0).getCategoryName());
                //平均成绩
                long studentCount = categoryList.stream().filter(item -> Objects.nonNull(item.getStudentId())).map(KinderCategoryScoreVO::getStudentId).distinct().count();
                BigDecimal totalItemFraction = categoryList.stream().filter(item -> Objects.nonNull(item.getItemFraction())).map(KinderCategoryScoreVO::getItemFraction).reduce(BigDecimal.ZERO, BigDecimal::add);
                firstCategoryScoreVO.setAvgCategoryFraction(BigDecimalUtil.getAvgScore(BigDecimal.valueOf(studentCount), totalItemFraction));
                categoryAvgFractionList.add(firstCategoryScoreVO);
            }
            //每个分类的平均成绩
            categoryScoreVO.setCategoryAvgFractionList(categoryAvgFractionList);
            categoryAgeFractionList.add(categoryScoreVO);
        }
        for (CategoryScoreVO categoryScoreVO : categoryAgeFractionList) {
            BigDecimal totalAvgFraction = ageTotalScore.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getStudentAge()) && categoryScoreVO.getStudentAge().equals(item.getStudentAge())).findFirst().orElseGet(CategoryScoreVO::new).getTotalAvgFraction();
            categoryScoreVO.setTotalAvgFraction(totalAvgFraction);
        }
        return categoryAgeFractionList;
    }

    /**
     * 分类表头信息
     *
     * @param avgKinderCategoryScoreInfo 表头信息
     * @param analysisVO                 各级表头信息
     */
    private void setCategoryTableName(List<FirstCategoryScoreVO> avgKinderCategoryScoreInfo,
                                      KinderPhysiqueAnalysisVO analysisVO) {
        Map<Long, List<FirstCategoryScoreVO>> tableNameMap = avgKinderCategoryScoreInfo.stream().filter(item -> Objects.nonNull(item.getParentId())).collect(Collectors.groupingBy(FirstCategoryScoreVO::getParentId));
        List<CategoryTableName> categoryTableNameList = Lists.newArrayList();
        for (Map.Entry<Long, List<FirstCategoryScoreVO>> tableName : tableNameMap.entrySet()) {
            CategoryTableName categoryTableName = new CategoryTableName();
            categoryTableName.setParentId(Objects.isNull(tableName.getKey()) ? 0L : tableName.getKey());
            List<FirstCategoryScoreVO> tableNameList = tableName.getValue();
            if (tableNameList.size() > 0L) {
                categoryTableName.setParentName(tableNameList.get(0).getParentName());
            }
            List<ChildrenTableName> childrenTableNameList = tableNameList.stream().map(item -> ChildrenTableName.builder().categoryId(item.getCategoryId()).categoryName(item.getCategoryName()).build()).collect(Collectors.toList());
            categoryTableName.setChildrenTableNameList(childrenTableNameList);
            categoryTableNameList.add(categoryTableName);
        }
        analysisVO.setCategoryTableNameList(categoryTableNameList);
    }

    /**
     * 查询全是平均成绩信息
     *
     * @param kindergartenId       幼儿园id
     * @param studentSex           学生性别
     * @param batchCode            批次编号
     * @param categoryAvgScoreInfo 平均成绩信息集合
     * @param analysisVO           返回值
     */
    private void getAvgCityScoreIno(Long kindergartenId, String studentSex, String batchCode,
                                    List<CategoryScoreVO> categoryAvgScoreInfo, KinderPhysiqueAnalysisVO analysisVO) {
        //全市平均成绩
        List<Long> areaIdList = this.getSysAreaInfoByKindergartenId(kindergartenId);
        //查询当前幼儿园所属市下得所有的幼儿园信息和学生信息
        List<StudentAndKindergartenVO> studentAndKindergartenList = kindergartenInfoMapper.getStudentAndKindergartenCount(areaIdList);
        if (CollectionUtils.isEmpty(areaIdList) && CollectionUtils.isEmpty(studentAndKindergartenList)) {
            CategoryScoreVO avgCityCategoryScore = new CategoryScoreVO();
            avgCityCategoryScore.setStudentAge("全市平均分");
            avgCityCategoryScore.setTotalAvgFraction(BigDecimal.ZERO);
            avgCityCategoryScore.setCategoryAvgFractionList(Lists.newArrayList());
            categoryAvgScoreInfo.add(avgCityCategoryScore);
            analysisVO.setCategoryAgeFractionList(categoryAvgScoreInfo);
            return;
        }
        //全市下的幼儿园id集合
        List<Long> kindergartenIdList = studentAndKindergartenList.stream().filter(item -> Objects.nonNull(item.getKindergartenId())).map(StudentAndKindergartenVO::getKindergartenId).distinct().collect(Collectors.toList());
        //全市下的所有学生数量
        long studentSexCount = studentAndKindergartenList.stream().filter(item -> Objects.nonNull(item.getStudentId()) && StringUtils.isNotBlank(item.getStudentSex())).filter(item -> studentSex.equals(item.getStudentSex())).distinct().count();
        //查询全市下的每个分类的总成绩信息
        List<FirstCategoryScoreVO> avgWholeCityCategoryScoreInfo = kindergartenInfoMapper.getAvgWholeCityCategoryScoreInfo(kindergartenIdList, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        //查询全市下的每个项目的总成绩信息
        List<FirstCategoryScoreVO> avgWholeCityCategoryScore = kindergartenInfoMapper.getAvgWholeCityItemScore(kindergartenIdList, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        //计算平均成绩
        avgWholeCityCategoryScoreInfo.forEach(item -> {
            if (studentSexCount != 0 && Objects.nonNull(item.getAvgCategoryFraction())) {
                item.setAvgCategoryFraction(BigDecimalUtil.getAvgScore(BigDecimal.valueOf(studentSexCount), item.getAvgCategoryFraction()));
            }
        });
        //全市平均成绩
        CategoryScoreVO avgCityCategoryScore = new CategoryScoreVO();
        avgCityCategoryScore.setStudentAge("全市平均分");
        BigDecimal bigDecimal = avgWholeCityCategoryScore.stream().filter(item -> Objects.nonNull(item.getAvgCategoryFraction())).map(FirstCategoryScoreVO::getAvgCategoryFraction).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_HALF_UP);
        avgCityCategoryScore.setTotalAvgFraction(bigDecimal.divide(new BigDecimal(studentSexCount), 2, BigDecimal.ROUND_HALF_UP));
        avgCityCategoryScore.setCategoryAvgFractionList(avgWholeCityCategoryScoreInfo);
        categoryAvgScoreInfo.add(avgCityCategoryScore);
        analysisVO.setCategoryAgeFractionList(categoryAvgScoreInfo);
    }

    /**
     * 根据幼儿园id查询对应得区域信息
     *
     * @param kindergartenId 幼儿园id
     * @return 区域信息集合
     */
    private List<Long> getSysAreaInfoByKindergartenId(Long kindergartenId) {
        SysArea sysArea = kindergartenInfoMapper.getSysAreaByKindergartenId(kindergartenId);
        List<Long> sysAreaIdList = Lists.newArrayList();
        if (Objects.nonNull(sysArea.getLevel())) {
            //所属市
            if (Constants.CITY_LEVEL.equals(sysArea.getLevel())) {
                sysAreaIdList = sysAreaMapper.getSysAreaIdList(Objects.isNull(sysArea.getId()) ? 0L : sysArea.getId());
                if (Objects.nonNull(sysArea.getId())) {
                    sysAreaIdList.add(sysArea.getId());
                }
            }
            //所属区
            if (Constants.REGION_LEVEL.equals(sysArea.getLevel())) {
                sysAreaIdList = sysAreaMapper.getSysAreaIdList(Objects.isNull(sysArea.getParentId()) ? 0L : sysArea.getParentId());
                if (Objects.nonNull(sysArea.getParentId())) {
                    sysAreaIdList.add(sysArea.getParentId());
                }
            }
        }
        return sysAreaIdList;
    }

    /**
     * 计算个年龄平均成绩综合
     *
     * @param kindergartenId 学校id
     * @param batchCode      批次编号
     * @param studentSex     性别
     * @return 成绩
     */
    private List<CategoryScoreVO> computeAgeTotalScore(Long kindergartenId, String batchCode, String studentSex) {
        List<KinderCategoryScoreVO> studentBirthDate = kindergartenInfoMapper.getStudentBirthDate(kindergartenId, batchCode, studentSex, ItemCodeEnums.BMI_CODE.getInfo());
        for (KinderCategoryScoreVO kinderCategoryScoreVO : studentBirthDate) {
            if (Objects.nonNull(kinderCategoryScoreVO.getBirthDate())) {
                kinderCategoryScoreVO.setStudentAge(AgeUtil.getStudentAgeMonth(kinderCategoryScoreVO.getBirthDate().toString()));
            }
        }
        List<CategoryScoreVO> categoryAgeFractionList = Lists.newArrayList();
        Map<Double, List<KinderCategoryScoreVO>> studentAgeMap = studentBirthDate.stream()
                .filter(item -> Objects.nonNull(item.getStudentAge()) && item.getStudentAge() != 0)
                .collect(Collectors.groupingBy(KinderCategoryScoreVO::getStudentAge));
        for (Map.Entry<Double, List<KinderCategoryScoreVO>> studentAgeEntry : studentAgeMap.entrySet()) {
            CategoryScoreVO categoryScoreVO = new CategoryScoreVO();
            //年龄
            categoryScoreVO.setStudentAge(Objects.isNull(studentAgeEntry.getKey()) ? "0.0" : studentAgeEntry.getKey() + "岁");
            List<KinderCategoryScoreVO> scoreList = CollectionUtils.isEmpty(studentAgeEntry.getValue()) ? Lists.newArrayList() : studentAgeEntry.getValue();
            long studentCount = scoreList.stream().map(KinderCategoryScoreVO::getStudentId).filter(Objects::nonNull).distinct().count();
            BigDecimal reduce = scoreList.stream().map(KinderCategoryScoreVO::getItemFraction).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
            categoryScoreVO.setTotalAvgFraction(reduce.divide(new BigDecimal(studentCount), 2, BigDecimal.ROUND_HALF_UP));
            categoryAgeFractionList.add(categoryScoreVO);
        }
        return categoryAgeFractionList;
    }
}
