package com.ruoyi.postCheck.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.PostAssessmentRatingOtherEnum;
import com.ruoyi.common.constant.PostAssessmentRulesEnum;
import com.ruoyi.common.constant.PostCheckedEnum;
import com.ruoyi.common.constant.PostCheckedProblemEnum;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.SysDeptEnum;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.postCheck.domain.*;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingOtherInfoMapper;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingOtherMapper;
import com.ruoyi.postCheck.mapper.PostAssessmentRulesMapper;
import com.ruoyi.postCheck.mapper.PostCheckedProblemMapper;
import com.ruoyi.postCheck.mapper.PostPlanInfoMapper;
import com.ruoyi.postCheck.mapper.PostPlanMapper;
import com.ruoyi.postCheck.service.IPostCheckedService;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingMapper;
import com.ruoyi.postCheck.service.IPostAssessmentRatingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;

/**
 * 考核评比Service业务层处理
 *
 * @author csg
 * @date 2023-12-21
 */
@Service
public class PostAssessmentRatingServiceImpl extends ServiceImpl<PostAssessmentRatingMapper, PostAssessmentRating> implements IPostAssessmentRatingService {
    @Autowired
    private PostAssessmentRatingOtherMapper postAssessmentRatingOtherMapper;
    @Autowired
    private PostAssessmentRatingOtherInfoMapper postAssessmentRatingOtherInfoMapper;
    @Autowired
    private PostAssessmentRatingMapper postAssessmentRatingMapper;
    @Autowired
    private PostCheckedProblemMapper postCheckedProblemMapper;
    @Autowired
    private PostPlanInfoMapper postPlanInfoMapper;
    @Autowired
    private PostPlanMapper postPlanMapper;
    @Autowired
    private PostAssessmentRulesMapper postAssessmentRulesMapper;


    @Autowired
    private IPostCheckedService postCheckedService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private ISysPostService sysPostService;

    /**
     * 查询考核评比
     *
     * @param id 考核评比主键
     * @return 考核评比
     */
    @Override
    public PostAssessmentRating selectPostAssessmentRatingById(Long id) {
        return postAssessmentRatingMapper.selectPostAssessmentRatingById(id);
    }

    /**
     * 查询考核评比列表
     *
     * @param postAssessmentRating 考核评比
     * @return 考核评比
     */
    @Override
    public List<PostAssessmentRating> selectPostAssessmentRatingList(PostAssessmentRating postAssessmentRating) {
        // type 1 是职能管理部门， 2 生产运营部门
        Integer type; //考核规则->评分分类/项目/专业：1-岗检考核规则；2-职能部门互评表；；3-生产部门日常得分；
        if (postAssessmentRating.getType() == 2) {
            type = 3;
        } else {
            type = 2;
        }
        List<PostAssessmentRating> postAssessmentRatings = new ArrayList<>();

        //1、查询部门列表：职能部门 OR 生产部门
        List<Map<String, Object>> deptIdListByType = postAssessmentRatingOtherMapper.getDeptIdListByType(postAssessmentRating.getType());

        //2、查询考核规则：扣分
        List<PostAssessmentRules> postAssessmentRulesList = postAssessmentRulesMapper.selectList(Wrappers.lambdaQuery());

        //3、遍历部门
        for (Map<String, Object> map : deptIdListByType) {
            PostAssessmentRating post = new PostAssessmentRating();
            post.setDeptId(Long.parseLong(map.get("deptId").toString()));
            post.setDeptName(String.valueOf(map.get("deptName")));

            // 计算一个部门的岗检得分
            BigDecimal postSouce = new BigDecimal("100");

            //TODO BUG：缺少时间范围
            //4、问题列表：该部门下的问题汇总
            List<PostCheckedProblem> postCheckedProblems = postCheckedProblemMapper.selectList(Wrappers.<PostCheckedProblem>lambdaQuery()
                    .eq(PostCheckedProblem::getCheckedDeptId, post.getDeptId())
            );

            //5、查询部门下的岗位数量
            BigDecimal postTotal = postCheckedProblemMapper.getPostTotalByDeptId(post.getDeptId());

            if (postCheckedProblems.size() > 0) {
                // 岗检扣除分数
                BigDecimal postAfter = new BigDecimal("100");

                //过滤考核规则：职能部门 时 互评规则
                //过滤考核规则：产部门部门 时 日常得分规则
                Set<PostAssessmentRules> deptRulesSet = postAssessmentRulesList.stream().filter(d -> d.getType() == type).collect(Collectors.toSet());

                for (PostCheckedProblem postCheckedProblem : postCheckedProblems) {
                    //TODO BUG：条件错误 d.getType() == type 应该是取出岗检问题规则
                    Optional<PostAssessmentRules> first = postAssessmentRulesList.stream().filter(d -> d.getType() == type && d.getDutyType() == postCheckedProblem.getDutyType()).findFirst();
                    if (first.isPresent()) {
                        //问题等级：1一般
                        if (postCheckedProblem.getProblemLevel().equals("1")) {
                            postAfter = postAfter.subtract(new BigDecimal(String.valueOf(first.get().getProblemLevelOne() != null ? first.get().getProblemLevelOne() : "0")));//计算-例如：减 0.2
                        }
                        //问题等级：2 重要
                        else {
                            postAfter = postAfter.subtract(new BigDecimal(String.valueOf(first.get().getProblemLevelTwo() != null ? first.get().getProblemLevelTwo() : "0")));//计算-例如：减 0.5
                        }
                    }
                }

                BigDecimal divide = new BigDecimal("0");

                if (postTotal != null && !CollectionUtils.isEmpty(deptRulesSet)) {//collect.size() = 0 时  / by zero 异常
                    // TODO BUG：系数辅助计算不正确（得分 *（1-问题数/检查项数）= 岗检得分）
                    // 问题数量 / ( 岗位数量 * 规则数量)
                    divide = new BigDecimal(postCheckedProblems.size()).divide(postTotal.multiply(new BigDecimal(deptRulesSet.size())), 2, RoundingMode.HALF_UP);
                }

                // 计算系数 1-问题总数/需要查的问题数
                if (divide.compareTo(new BigDecimal("1")) < 0 && divide.compareTo(new BigDecimal("0")) > 0) {
                    postSouce = postAfter.multiply(new BigDecimal("1").subtract(divide));
                } else {
                    postSouce = new BigDecimal("0");
                }
            } else {
                postSouce = new BigDecimal("0");
            }
            post.setPositionScore(postSouce);

            //TODO BUG：未界定时间范围 未判断打分状态

            // 计算互评得分：年度内 别人给该部门的全部打分记录 按分数正序排列
            List<PostAssessmentRatingOtherInfo> postAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoMapper.selectList(Wrappers.<PostAssessmentRatingOtherInfo>lambdaQuery()
                    .eq(PostAssessmentRatingOtherInfo::getByDeptId, post.getDeptId())
                    .apply(" \"rating_other_id\" in (SELECT \"id\" FROM \"public\".\"post_assessment_rating_other\" WHERE \"type\"  = 1\n)")//打分表 职能部门 打分记录ID
                    .orderByAsc(PostAssessmentRatingOtherInfo::getByDeptScore)
            );

            BigDecimal peerEvaluationScore = new BigDecimal("100");

            //求平均分：去掉 最高分 和 最低分
            if (postAssessmentRatingOtherInfoList.size() > 0) {
                postAssessmentRatingOtherInfoList.remove(postAssessmentRatingOtherInfoList.size() - 1);
                postAssessmentRatingOtherInfoList.remove(0);
                BigDecimal bigDecimal = postAssessmentRatingOtherInfoList.stream().filter(d -> d.getByDeptScore() != null).map(e -> e.getByDeptScore()).reduce(BigDecimal.ZERO, BigDecimal::add);
                peerEvaluationScore = bigDecimal.divide(new BigDecimal(postAssessmentRatingOtherInfoList.size()), 2, RoundingMode.HALF_UP);
            }
            post.setPeerEvaluationScore(peerEvaluationScore);
            // 计算总得分：(岗位得分 + 互评得分) / 2
            post.setDepartmentScore(post.getPositionScore().add(post.getPeerEvaluationScore()).divide(new BigDecimal("2"), 2, RoundingMode.HALF_UP));

            postAssessmentRatings.add(post);
        }
        List<PostAssessmentRating> collect = postAssessmentRatings.stream()
                .sorted(Comparator.comparing(PostAssessmentRating::getDepartmentScore).reversed())
                .collect(Collectors.toList());
        // 计算  岗检得分
        return collect;
    }

    /**
     * 查询考核评比列表
     *
     * @param beginTime 开始时间：年的第一天
     * @param endTime   结束时间：年的最后一天
     * @return 考核评比
     */
    @Override
    public List<PostAssessmentRating> statisticsPostAssessmentRatingZN(String beginTime, String endTime) {
        List<PostAssessmentRating> postAssessmentRatingList = new ArrayList<>();

        //1、查询职能部门列表
        SysDept deptParam = new SysDept();
        deptParam.setStatus(SysDeptEnum.STATUS_VALID.getValue().toString());//部门状态（0正常 1停用）
        deptParam.setType(SysDeptEnum.TYPE_ZN.getValue());//1 职能部门 2 生产部门 3 其他
        List<SysDept> deptList = sysDeptService.selectDeptListByCondition(deptParam);
        List<Long> deptIdList = deptList.stream().map(SysDept::getDeptId).collect(Collectors.toList());

        //2、查询岗检问题的考核规则
        List<PostAssessmentRules> postAssessmentRulesList = postAssessmentRulesMapper.selectList(
                Wrappers.lambdaQuery(PostAssessmentRules.class)
                        .eq(PostAssessmentRules::getType, PostAssessmentRulesEnum.TYPE_POST.getValue())
        );

        //3、查询职能部门问题汇总
        List<PostCheckedProblem> postCheckedProblemList = postCheckedProblemMapper.selectList(Wrappers.<PostCheckedProblem>lambdaQuery()
                .in(PostCheckedProblem::getCheckedDeptId, deptIdList)
        );

        //4、查询所有职能部门下的岗位检查表
        PostChecked postChecked = new PostChecked();
        postChecked.setStatus(PostCheckedEnum.STATUS_PASS.getValue());
        postChecked.setDeptIdList(deptIdList);
        List<PostChecked> postCheckedList = postCheckedService.selectPostCheckedList(postChecked);
        //按创建时间倒叙
        postCheckedList = postCheckedList.stream().sorted(Comparator.comparing(PostChecked::getCreateTime).reversed()).collect(Collectors.toList());

        //5、年度内职能部门互评打分记录： 按分数正序排列
        List<PostAssessmentRatingOtherInfo> postAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoMapper.selectList(
                Wrappers.<PostAssessmentRatingOtherInfo>lambdaQuery()
                        .apply("rating_other_id in (" +
                                "SELECT id FROM post_assessment_rating_other WHERE type = " + PostAssessmentRatingOtherEnum.TYPE_ZN_HP.getValue() + "\n" +
                                "AND status = " + PostAssessmentRatingOtherEnum.STATUS_FINISH.getValue() + "\n" +
                                "AND TO_DATE(start_time, 'yyyy-mm-dd') >= TO_DATE('" + beginTime + "', 'yyyy-mm-dd')" + "\n" +
                                "AND TO_DATE(start_time, 'yyyy-mm-dd') <= TO_DATE('" + endTime + "', 'yyyy-mm-dd')" + "\n" +
                                ")" + "\n")//打分表 职能部门 打分记录ID
                        .orderByAsc(PostAssessmentRatingOtherInfo::getByDeptScore)
        );

        //6、遍历职能部门计算分数
        for (SysDept dept : deptList) {
            Long deptId = dept.getDeptId();
            PostAssessmentRating assessmentRating = new PostAssessmentRating();
            assessmentRating.setRatingTime(DateUtils.parseDate(beginTime));
            assessmentRating.setDeptId(deptId);
            assessmentRating.setDeptName(dept.getDeptName());

            //岗检得分：100 - 问题扣分
            BigDecimal postSouce = new BigDecimal("100");

            // 1 过滤出当前部门的问题
            List<PostCheckedProblem> deptProblemList = postCheckedProblemList.stream().filter(d -> d.getCheckedDeptId().equals(deptId)).collect(Collectors.toList());


            if (deptProblemList.size() > 0) {
                // 计算扣除分数
                BigDecimal postAfter = new BigDecimal("100");

                //遍历问题按规则计算扣分
                for (PostCheckedProblem postCheckedProblem : deptProblemList) {
                    Optional<PostAssessmentRules> firstRules = postAssessmentRulesList.stream().filter(d -> d.getDutyType() == postCheckedProblem.getDutyType()).findFirst();
                    if (firstRules.isPresent()) {
                        //1一般
                        if (postCheckedProblem.getProblemLevel() == PostCheckedProblemEnum.LEVEL_Y.getValue()) {
                            postAfter = postAfter.subtract(new BigDecimal(firstRules.get().getProblemLevelOne()));
                        }
                        //2 重要
                        else {
                            postAfter = postAfter.subtract(new BigDecimal(firstRules.get().getProblemLevelTwo()));
                        }
                    }
                }

                //根据受检部门过滤该部门下岗位检查表列表
                List<PostChecked> deptPostCheckedList = postCheckedList.stream().filter(pc -> pc.getCheckedDeptId().equals(deptId)).collect(Collectors.toList());

                //部门下所有岗位的检查表中检查项目总数
                int checkedItemsTotal = 0;
                Set<Long> postIdSet = new HashSet<>();
                for (PostChecked checked : deptPostCheckedList) {
                    Long postId = checked.getCheckedPostId();
                    //保证 相同岗位有多张检查表时不重复计算
                    if (postIdSet.contains(postId)) {
                        continue;
                    }
                    postIdSet.add(postId);
                    List<PostCheckedItems> children = checked.getChildren();
                    checkedItemsTotal += children.size();
                }

                // 问题数量 / 检查项数
                BigDecimal problemCheckedDivide = null;
                try {
                    problemCheckedDivide = new BigDecimal(deptProblemList.size())
                            .divide(new BigDecimal(checkedItemsTotal), 2, RoundingMode.HALF_UP);
                } catch (Exception e) {
                    problemCheckedDivide = new BigDecimal("0.00");
                    log.error("【考核评比】统计：未设置岗检表，出现除以0的异常，设置默认辅助系数 = 0.00");
                    //e.printStackTrace();
                }

                // 系数计算: 1 - 问题数 / 检查项数
                BigDecimal coefficient = new BigDecimal("1").subtract(problemCheckedDivide);
                //当系数大于1或者小于0时，设置默认值=1
                if (coefficient.compareTo(new BigDecimal("0")) < 0 || coefficient.compareTo(new BigDecimal("1")) > 0) {
                    coefficient = new BigDecimal("1");
                }

                //计算最终岗检得分：得分 *（ 1 - 问题数 / 检查项数 ）= 岗检得分
                postSouce = postAfter.multiply(coefficient);
            }
            assessmentRating.setPositionScore(postSouce);


            //计算互评得分：该部门的评分记录（多部门多项目的合计）
            List<PostAssessmentRatingOtherInfo> deptAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoList.stream().filter(a -> a.getByDeptId().equals(deptId)).collect(Collectors.toList());
            //按打分部门分组：将一个部门的打分,放到一个List中，key代表不同的打分部门标识（打分记录表ID）
            Map<Long, List<PostAssessmentRatingOtherInfo>> deptAssessmentRatingOtherInfoMap = deptAssessmentRatingOtherInfoList.stream().collect(Collectors.groupingBy(PostAssessmentRatingOtherInfo::getRatingOtherId));
            //多个部门对该部门的打分集合：值是打分项目的合计分数
            List<BigDecimal> peerEvaluationScoreList = new ArrayList<>();
            //分组后计算最终的得分：将一个部门的打分记录相加后再除以打分项目得出最终的部门得分
            Set<Long> ratingOtherIdSet = deptAssessmentRatingOtherInfoMap.keySet();
            for (Long ratingOtherId : ratingOtherIdSet) {
                List<PostAssessmentRatingOtherInfo> ratingOtherInfoList = deptAssessmentRatingOtherInfoMap.get(ratingOtherId);//一个部门的打分项集合
                BigDecimal deptScore = ratingOtherInfoList.stream().filter(d -> d.getByDeptScore() != null).map(e -> e.getByDeptScore()).reduce(BigDecimal.ZERO, BigDecimal::add);//部门得分所有项目的总和
                BigDecimal peerEvaluationScore = deptScore.divide(new BigDecimal(String.valueOf(ratingOtherInfoList.size())), 2, RoundingMode.HALF_UP);//部门得分：一个部门的打分合计计算值（项目总分/项目数）
                peerEvaluationScoreList.add(peerEvaluationScore);
            }
            //去掉最高分和最低分
            if (peerEvaluationScoreList.size() > 2) {
                Collections.sort(peerEvaluationScoreList);
                peerEvaluationScoreList.remove(peerEvaluationScoreList.size() - 1);
                peerEvaluationScoreList.remove(0);
            }
            //计算剩余评分的平均分
            BigDecimal deptScore = peerEvaluationScoreList.stream().map(a -> a).reduce(BigDecimal.ZERO, BigDecimal::add);//多个部门的打分合计
            BigDecimal peerEvaluationScore = null;//部门得分：多个部门的打分合计求的平均值
            try {
                peerEvaluationScore = deptScore.divide(new BigDecimal(String.valueOf(peerEvaluationScoreList.size())), 2, RoundingMode.HALF_UP);
            } catch (Exception e) {
                peerEvaluationScore = new BigDecimal("0.00");
            }

            //保存互评得分
            assessmentRating.setPeerEvaluationScore(peerEvaluationScore);//互评得分

/*
            //5、年度内该部门互评时别人给他的打分记录明细： 按分数正序排列
            List<PostAssessmentRatingOtherInfo> deptAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoList.stream().filter(a -> a.getByDeptId() == deptId).collect(Collectors.toList());
            BigDecimal peerEvaluationScore = new BigDecimal("0");

            //求平均分：去掉 最高分 和 最低分
            if (deptAssessmentRatingOtherInfoList.size() > 2) {
                deptAssessmentRatingOtherInfoList.remove(deptAssessmentRatingOtherInfoList.size() - 1);
                deptAssessmentRatingOtherInfoList.remove(0);
            }

//            if(deptAssessmentRatingOtherInfoList.size()>0){
            BigDecimal bigDecimal = deptAssessmentRatingOtherInfoList.stream().filter(d -> d.getByDeptScore() != null).map(e -> e.getByDeptScore()).reduce(BigDecimal.ZERO, BigDecimal::add);
            peerEvaluationScore = bigDecimal.divide(new BigDecimal(deptAssessmentRatingOtherInfoList.size()), 2, RoundingMode.HALF_UP);
//            }
            assessmentRating.setPeerEvaluationScore(peerEvaluationScore);//互评得分
*/


            // 计算总得分：部门得分 = (岗位得分 + 互评得分) / 2
            assessmentRating.setDepartmentScore(
                    assessmentRating.getPositionScore()//岗位得分
                            .add(assessmentRating.getPeerEvaluationScore()//互评得分
                            ).divide(new BigDecimal("2"), 2, RoundingMode.HALF_UP));

            postAssessmentRatingList.add(assessmentRating);
        }

        //按得分倒叙
        postAssessmentRatingList = postAssessmentRatingList.stream()
                .sorted(Comparator.comparing(PostAssessmentRating::getDepartmentScore).reversed())
                .collect(Collectors.toList());

        // 计算  岗检得分
        return postAssessmentRatingList;
    }

    /**
     * 查询考核评比列表
     *
     * @param beginTime 开始时间：年的第一天
     * @param endTime   结束时间：年的最后一天
     * @return 考核评比
     */
    @Override
    public List<PostAssessmentRating> statisticsPostAssessmentRatingSC(String beginTime, String endTime) {
        List<PostAssessmentRating> postAssessmentRatingList = new ArrayList<>();

        //1、查询生产运行部门列表
        SysDept deptParam = new SysDept();
        deptParam.setStatus(SysDeptEnum.STATUS_VALID.getValue().toString());//部门状态（0正常 1停用）
        deptParam.setType(SysDeptEnum.TYPE_SC.getValue());//1 职能部门 2 生产部门 3 其他
        List<SysDept> deptList = sysDeptService.selectDeptListByCondition(deptParam);
        List<Long> deptIdList = deptList.stream().map(SysDept::getDeptId).collect(Collectors.toList());


        //2、查询岗检问题的考核规则
        List<PostAssessmentRules> postAssessmentRulesList = postAssessmentRulesMapper.selectList(
                Wrappers.lambdaQuery(PostAssessmentRules.class)
                        .eq(PostAssessmentRules::getType, PostAssessmentRulesEnum.TYPE_POST.getValue())
        );

        //3、查询生产运行部门问题汇总
        List<PostCheckedProblem> postCheckedProblemList = postCheckedProblemMapper.selectList(Wrappers.<PostCheckedProblem>lambdaQuery()
                .in(PostCheckedProblem::getCheckedDeptId, deptIdList)
        );

        //4、查询所有生产运行部门下的岗位检查表
        PostChecked postChecked = new PostChecked();
        postChecked.setStatus(PostCheckedEnum.STATUS_PASS.getValue());
        postChecked.setDeptIdList(deptIdList);
        List<PostChecked> postCheckedList = postCheckedService.selectPostCheckedList(postChecked);
        //按创建时间倒叙
        postCheckedList = postCheckedList.stream().sorted(Comparator.comparing(PostChecked::getCreateTime).reversed()).collect(Collectors.toList());

        //5、年度内职能部门互评打分记录： 按分数正序排列
        List<PostAssessmentRatingOtherInfo> postAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoMapper.selectList(
                Wrappers.<PostAssessmentRatingOtherInfo>lambdaQuery()
                        .apply("rating_other_id in (" +
                                "SELECT id FROM post_assessment_rating_other WHERE type = " + PostAssessmentRatingOtherEnum.TYPE_SC_RC.getValue() + "\n" +
                                "AND status = " + PostAssessmentRatingOtherEnum.STATUS_FINISH.getValue() + "\n" +
                                "AND TO_DATE(start_time, 'yyyy-mm-dd') >= TO_DATE('" + beginTime + "', 'yyyy-mm-dd')" + "\n" +
                                "AND TO_DATE(start_time, 'yyyy-mm-dd') <= TO_DATE('" + endTime + "', 'yyyy-mm-dd')" + "\n" +
                                ")" + "\n")//打分表 职能部门 打分记录ID
                        .orderByAsc(PostAssessmentRatingOtherInfo::getByDeptScore)
        );

        //6、遍历生产运行部门计算分数
        for (SysDept dept : deptList) {
            Long deptId = dept.getDeptId();
            PostAssessmentRating assessmentRating = new PostAssessmentRating();
            assessmentRating.setDeptId(deptId);
            assessmentRating.setDeptName(dept.getDeptName());

            //岗检得分：100 - 问题扣分
            BigDecimal postSouce = new BigDecimal("100");

            // 1 过滤出当前部门的问题
            List<PostCheckedProblem> deptProblemList = postCheckedProblemList.stream().filter(d -> d.getCheckedDeptId().equals(deptId)).collect(Collectors.toList());


            if (deptProblemList.size() > 0) {
                // 计算扣除分数
                BigDecimal postAfter = new BigDecimal("100");

                //遍历问题按规则计算扣分
                for (PostCheckedProblem postCheckedProblem : deptProblemList) {
                    Optional<PostAssessmentRules> firstRules = postAssessmentRulesList.stream().filter(p -> p.getDutyType() == postCheckedProblem.getDutyType()).findFirst();
                    if (firstRules.isPresent()) {
                        //1一般
                        if (postCheckedProblem.getProblemLevel() == PostCheckedProblemEnum.LEVEL_Y.getValue()) {
                            postAfter = postAfter.subtract(new BigDecimal(firstRules.get().getProblemLevelOne()));
                        }
                        //2 重要
                        else {
                            postAfter = postAfter.subtract(new BigDecimal(firstRules.get().getProblemLevelTwo()));
                        }
                    }
                }

                //根据受检部门过滤该部门下岗位检查表列表
                List<PostChecked> deptPostCheckedList = postCheckedList.stream().filter(pc -> pc.getCheckedDeptId().longValue() == deptId.longValue()).collect(Collectors.toList());

                //部门下所有岗位的检查表中检查项目总数
                int checkedItemsTotal = 0;
                Set<Long> postIdSet = new HashSet<>();
                for (PostChecked checked : deptPostCheckedList) {
                    Long postId = checked.getCheckedPostId();
                    //保证 相同岗位有多张检查表时不重复计算
                    if (postIdSet.contains(postId)) {
                        continue;
                    }
                    postIdSet.add(postId);
                    List<PostCheckedItems> children = checked.getChildren();
                    checkedItemsTotal += children.size();
                }

                // 问题数量 / 检查项数
                BigDecimal problemCheckedDivide = null;
                try {
                    problemCheckedDivide = new BigDecimal(String.valueOf(deptProblemList.size()))
                            .divide(new BigDecimal(String.valueOf(checkedItemsTotal)), 2, RoundingMode.HALF_UP);
                } catch (Exception e) {
                    problemCheckedDivide = new BigDecimal("0.00");
                    log.error("【考核评比】统计：未设置岗检表，出现除以0的异常，设置默认辅助系数 = 0.00");
//                    e.printStackTrace();
                }

                // 系数计算: 1 - 问题数 / 检查项数
                BigDecimal coefficient = new BigDecimal("1").subtract(problemCheckedDivide);
                //当系数大于1或者小于0时，设置默认值=1
                if (coefficient.compareTo(new BigDecimal("0")) < 0 || coefficient.compareTo(new BigDecimal("1")) > 0) {
                    coefficient = new BigDecimal("1");
                }

                //计算最终岗检得分：得分 *（ 1 - 问题数 / 检查项数 ）= 岗检得分
                postSouce = postAfter.multiply(coefficient);
            }
            assessmentRating.setPositionScore(postSouce);


            //计算互评得分：该部门的评分记录（多部门多项目的合计）
            List<PostAssessmentRatingOtherInfo> deptAssessmentRatingOtherInfoList = postAssessmentRatingOtherInfoList.stream().filter(a -> a.getByDeptId().longValue() == deptId.longValue()).collect(Collectors.toList());
            //按打分部门分组：将一个部门的打分,放到一个List中，key代表不同的打分部门标识（打分记录表ID）
            Map<Long, List<PostAssessmentRatingOtherInfo>> deptAssessmentRatingOtherInfoMap = deptAssessmentRatingOtherInfoList.stream().collect(Collectors.groupingBy(PostAssessmentRatingOtherInfo::getRatingOtherId));
            //多个部门对该部门的打分集合：值是打分项目的合计分数
            List<BigDecimal> peerEvaluationScoreList = new ArrayList<>();
            //分组后计算最终的得分：将一个部门的打分记录相加后再除以打分项目得出最终的部门得分
            Set<Long> ratingOtherIdSet = deptAssessmentRatingOtherInfoMap.keySet();
            for (Long ratingOtherId : ratingOtherIdSet) {
                List<PostAssessmentRatingOtherInfo> ratingOtherInfoList = deptAssessmentRatingOtherInfoMap.get(ratingOtherId);//一个部门的打分项集合
                BigDecimal deptScore = ratingOtherInfoList.stream().filter(d -> d.getByDeptScore() != null)
                        .map(e ->
                                e.getByDeptScore()//单项得分
                                        .multiply(new BigDecimal(String.valueOf(e.getScoreWeight())))//乘以权重
                                        .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP)//除以100（权重的百分比）
                        )
                        .reduce(BigDecimal.ZERO, BigDecimal::add);//部门得分所有项目的总和
                peerEvaluationScoreList.add(deptScore);
            }
            //去掉最高分和最低分
            if (peerEvaluationScoreList.size() > 2) {
                Collections.sort(peerEvaluationScoreList);
                peerEvaluationScoreList.remove(peerEvaluationScoreList.size() - 1);
                peerEvaluationScoreList.remove(0);
            }
            //计算剩余评分的平均分
            BigDecimal deptScore = peerEvaluationScoreList.stream().map(a -> a).reduce(BigDecimal.ZERO, BigDecimal::add);//多个部门的打分合计
            BigDecimal peerEvaluationScore = null;//部门得分：多个部门的打分合计求的平均值
            try {
                peerEvaluationScore = deptScore.divide(new BigDecimal(String.valueOf(peerEvaluationScoreList.size())), 2, RoundingMode.HALF_UP);
            } catch (Exception e) {
                peerEvaluationScore = new BigDecimal("0.00");
            }

            //保存互评得分
            assessmentRating.setPeerEvaluationScore(peerEvaluationScore);//互评得分


            // 计算总得分：部门得分 = (岗位得分 + 互评得分) / 2
            assessmentRating.setDepartmentScore(
                    assessmentRating.getPositionScore()//岗位得分
                            .add(assessmentRating.getPeerEvaluationScore()//互评得分
                            ).divide(new BigDecimal("2"), 2, RoundingMode.HALF_UP));

            postAssessmentRatingList.add(assessmentRating);
        }

        //按得分倒叙
        postAssessmentRatingList = postAssessmentRatingList.stream()
                .sorted(Comparator.comparing(PostAssessmentRating::getDepartmentScore).reversed())
                .collect(Collectors.toList());

        // 计算  岗检得分
        return postAssessmentRatingList;
    }

    /**
     * 新增考核评比
     *
     * @param postAssessmentRating 考核评比
     * @return 结果
     */
    @Override
    public int insertPostAssessmentRating(PostAssessmentRating postAssessmentRating) {
        //TODO 自增主键修改为-MyBatis-Plus雪花算法(截取5位解决VUE精度丢失BUG)-系统登录日志
        if (postAssessmentRating.getId() == null)
            postAssessmentRating.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));

        postAssessmentRating.setCreateDefault();
        return postAssessmentRatingMapper.insertPostAssessmentRating(postAssessmentRating);
    }

    /**
     * 修改考核评比
     *
     * @param postAssessmentRating 考核评比
     * @return 结果
     */
    @Override
    public int updatePostAssessmentRating(PostAssessmentRating postAssessmentRating) {
        postAssessmentRating.setUpdateDefault();
        return postAssessmentRatingMapper.updatePostAssessmentRating(postAssessmentRating);
    }

    /**
     * 批量删除考核评比
     *
     * @param ids 需要删除的考核评比主键
     * @return 结果
     */
    @Override
    public int deletePostAssessmentRatingByIds(Long[] ids) {
        return postAssessmentRatingMapper.deletePostAssessmentRatingByIds(ids);
    }

    /**
     * 删除考核评比信息
     *
     * @param id 考核评比主键
     * @return 结果
     */
    @Override
    public int deletePostAssessmentRatingById(Long id) {
        return postAssessmentRatingMapper.deletePostAssessmentRatingById(id);
    }

    @Override
    public List<PostCheckedProblem> getProblemByDeptId(Long id) {
        return postCheckedProblemMapper.selectList(Wrappers.<PostCheckedProblem>lambdaQuery()
                .eq(PostCheckedProblem::getCheckedDeptId, id)
        );
    }


    @Override
    public Map<String, Object> assessmentstatistics(Integer type, String year) {
        if (type == 1)
            return postCheckedProblemMapper.getYearStatistics(year);
        if (type == 2)
            return postCheckedProblemMapper.getQuarterStatistics(year);
        if (type == 3)
            return postCheckedProblemMapper.getMonthStatistics(year);
        return new HashMap<>();
    }

    //    @ApiImplicitParam(name = "type", value = "类型1 年度 2 季度 3 月度", dataType = "String", dataTypeClass = Integer.class),
//    @ApiImplicitParam(name = "year", value = "年份", dataType = "String", dataTypeClass = String.class)
    @Override
    public List<Map<String, Object>> assessmentstatisticsV2(Integer type, String year) {
        return postCheckedProblemMapper.getQuarterStatisticsV2(year, type);
    }
}
