package com.sundot.airport.personnel.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.dto.SysPersonnelUserConditionDto;
import com.sundot.airport.common.dto.SysUserLeaderConditionDto;
import com.sundot.airport.common.enums.AssessmentTeamEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorApplicationMethodRuleEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorAssessmentResultRuleEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorExemptionRuleEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorLeaveTypeEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorQcDeptTypeEnum;
import com.sundot.airport.common.enums.BasePerformanceIndicatorRewardPunishmentTypeTypeEnum;
import com.sundot.airport.common.enums.DeptTypeEnum;
import com.sundot.airport.common.enums.RoleTypeEnum;
import com.sundot.airport.common.event.PersonnelEvent;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.common.utils.MonthUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.personnel.domain.PersonnelMonthlyAssessmentIndicatorDetail;
import com.sundot.airport.personnel.domain.PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail;
import com.sundot.airport.personnel.service.IPersonnelMonthlyAssessmentIndicatorDetailService;
import com.sundot.airport.personnel.service.IPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailService;
import com.sundot.airport.system.domain.BasePerformanceIndicator;
import com.sundot.airport.system.domain.BasePerformanceIndicatorCategory;
import com.sundot.airport.system.service.IBasePerformanceIndicatorCategoryService;
import com.sundot.airport.system.service.IBasePerformanceIndicatorService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import com.sundot.airport.personnel.mapper.PersonnelNonCadreMonthlyAssessmentMapper;
import com.sundot.airport.personnel.domain.PersonnelNonCadreMonthlyAssessment;
import com.sundot.airport.personnel.service.IPersonnelNonCadreMonthlyAssessmentService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 非干部月度考核Service业务层处理
 *
 * @author ruoyi
 * @date 2026-05-07
 */
@Service
public class PersonnelNonCadreMonthlyAssessmentServiceImpl extends ServiceImpl<PersonnelNonCadreMonthlyAssessmentMapper, PersonnelNonCadreMonthlyAssessment> implements IPersonnelNonCadreMonthlyAssessmentService {
    // 基础分
    private static final BigDecimal BASE_SCORE = new BigDecimal(80);
    // 红线分
    private static final BigDecimal RED_LINE_SCORE = new BigDecimal(69);

    @Autowired
    private PersonnelNonCadreMonthlyAssessmentMapper personnelNonCadreMonthlyAssessmentMapper;
    @Autowired
    private IPersonnelMonthlyAssessmentIndicatorDetailService personnelMonthlyAssessmentIndicatorDetailService;
    @Autowired
    private IPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailService personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService;
    @Autowired
    private IBasePerformanceIndicatorCategoryService basePerformanceIndicatorCategoryService;
    @Autowired
    private IBasePerformanceIndicatorService basePerformanceIndicatorService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    /**
     * 查询非干部月度考核
     *
     * @param id 非干部月度考核主键
     * @return 非干部月度考核
     */
    @Override
    public PersonnelNonCadreMonthlyAssessment selectPersonnelNonCadreMonthlyAssessmentById(Long id) {
        PersonnelNonCadreMonthlyAssessment result = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentById(id);
        if (ObjUtil.isNull(result)) {
            return result;
        }
        // 指标明细列表
        LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(PersonnelMonthlyAssessmentIndicatorDetail::getSourceId, result.getId());
        List<PersonnelMonthlyAssessmentIndicatorDetail> personnelMonthlyAssessmentIndicatorDetailList = personnelMonthlyAssessmentIndicatorDetailService.getBaseMapper().selectList(detailQueryWrapper);
        result.setPersonnelMonthlyAssessmentIndicatorDetailList(personnelMonthlyAssessmentIndicatorDetailList);
        if (CollUtil.isNotEmpty(result.getPersonnelMonthlyAssessmentIndicatorDetailList())) {
            // 奖罚明细列表
            LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> rewardPunishmentDetailQueryWrapper = new LambdaQueryWrapper<>();
            rewardPunishmentDetailQueryWrapper.in(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getSourceId, result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getId).toArray());
            List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> personnelMonthlyAssessmentIndicatorRewardPunishmentDetailList = personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.getBaseMapper().selectList(rewardPunishmentDetailQueryWrapper);
            if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailList)) {
                Map<Long, List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail>> rewardPunishmentDetailMap = personnelMonthlyAssessmentIndicatorRewardPunishmentDetailList.stream().collect(Collectors.groupingBy(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getSourceId));
                result.getPersonnelMonthlyAssessmentIndicatorDetailList().forEach(item -> {
                    item.setPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList(rewardPunishmentDetailMap.get(item.getId()));
                });
            }
        }
        return result;
    }

    /**
     * 查询非干部月度考核列表
     *
     * @param personnelNonCadreMonthlyAssessment 非干部月度考核
     * @return 非干部月度考核
     */
    @Override
    public List<PersonnelNonCadreMonthlyAssessment> selectPersonnelNonCadreMonthlyAssessmentList(PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessment) {
        return personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(personnelNonCadreMonthlyAssessment);
    }

    /**
     * 新增非干部月度考核
     *
     * @param personnelNonCadreMonthlyAssessment 非干部月度考核
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertPersonnelNonCadreMonthlyAssessment(PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessment) {
        PersonnelNonCadreMonthlyAssessment temp = new PersonnelNonCadreMonthlyAssessment();
        temp.setAssessmentMonth(personnelNonCadreMonthlyAssessment.getAssessmentMonth());
        temp.setUserId(personnelNonCadreMonthlyAssessment.getUserId());
        List<PersonnelNonCadreMonthlyAssessment> tempList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(temp);
        if (CollUtil.isNotEmpty(tempList)) {
            throw new ServiceException("该用户已存在该考核月份的考核记录");
        }
        personnelNonCadreMonthlyAssessment.setCreateTime(DateUtils.getNowDate());
        // 完善数据
        doImprove(personnelNonCadreMonthlyAssessment);
        int result = personnelNonCadreMonthlyAssessmentMapper.insertPersonnelNonCadreMonthlyAssessment(personnelNonCadreMonthlyAssessment);
        if (CollUtil.isNotEmpty(personnelNonCadreMonthlyAssessment.getPersonnelMonthlyAssessmentIndicatorDetailList())) {
            personnelNonCadreMonthlyAssessment.getPersonnelMonthlyAssessmentIndicatorDetailList().forEach(personnelMonthlyAssessmentIndicatorDetail -> {
                personnelMonthlyAssessmentIndicatorDetail.setSourceId(personnelNonCadreMonthlyAssessment.getId());
                personnelMonthlyAssessmentIndicatorDetail.setCreateBy(personnelNonCadreMonthlyAssessment.getCreateBy());
                personnelMonthlyAssessmentIndicatorDetail.setCreateTime(DateUtils.getNowDate());
                personnelMonthlyAssessmentIndicatorDetailService.insertPersonnelMonthlyAssessmentIndicatorDetail(personnelMonthlyAssessmentIndicatorDetail);
                if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList())) {
                    personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().forEach(personnelMonthlyAssessmentIndicatorRewardPunishmentDetail -> {
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setSourceId(personnelMonthlyAssessmentIndicatorDetail.getId());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setCreateBy(personnelMonthlyAssessmentIndicatorDetail.getCreateBy());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setCreateTime(DateUtils.getNowDate());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.insertPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail(personnelMonthlyAssessmentIndicatorRewardPunishmentDetail);
                    });
                }
            });
        }
        eventPublisher.publishEvent(new PersonnelEvent(this, personnelNonCadreMonthlyAssessment.getAssessmentMonth()));
        return result;
    }

    /**
     * 修改非干部月度考核
     *
     * @param personnelNonCadreMonthlyAssessment 非干部月度考核
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updatePersonnelNonCadreMonthlyAssessment(PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessment) {
        personnelNonCadreMonthlyAssessment.setUpdateTime(DateUtils.getNowDate());
        int result = personnelNonCadreMonthlyAssessmentMapper.updatePersonnelNonCadreMonthlyAssessment(personnelNonCadreMonthlyAssessment);
        // 删除旧数据
        LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(PersonnelMonthlyAssessmentIndicatorDetail::getSourceId, personnelNonCadreMonthlyAssessment.getId());
        List<PersonnelMonthlyAssessmentIndicatorDetail> personnelMonthlyAssessmentIndicatorDetailListOld = personnelMonthlyAssessmentIndicatorDetailService.getBaseMapper().selectList(detailQueryWrapper);
        if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorDetailListOld)) {
            personnelMonthlyAssessmentIndicatorDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorDetailListOld);
            LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> rewardPunishmentDetailQueryWrapper = new LambdaQueryWrapper<>();
            rewardPunishmentDetailQueryWrapper.in(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getSourceId, personnelMonthlyAssessmentIndicatorDetailListOld.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getId).toArray());
            List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld = personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.getBaseMapper().selectList(rewardPunishmentDetailQueryWrapper);
            if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld)) {
                personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld);
            }
        }
        // 完善数据
        doImprove(personnelNonCadreMonthlyAssessment);
        // 新增新数据
        if (CollUtil.isNotEmpty(personnelNonCadreMonthlyAssessment.getPersonnelMonthlyAssessmentIndicatorDetailList())) {
            personnelNonCadreMonthlyAssessment.getPersonnelMonthlyAssessmentIndicatorDetailList().forEach(personnelMonthlyAssessmentIndicatorDetail -> {
                personnelMonthlyAssessmentIndicatorDetail.setId(null);
                personnelMonthlyAssessmentIndicatorDetail.setSourceId(personnelNonCadreMonthlyAssessment.getId());
                personnelMonthlyAssessmentIndicatorDetail.setCreateBy(personnelNonCadreMonthlyAssessment.getCreateBy());
                personnelMonthlyAssessmentIndicatorDetail.setCreateTime(DateUtils.getNowDate());
                personnelMonthlyAssessmentIndicatorDetail.setUpdateBy(personnelNonCadreMonthlyAssessment.getCreateBy());
                personnelMonthlyAssessmentIndicatorDetail.setUpdateTime(DateUtils.getNowDate());
                personnelMonthlyAssessmentIndicatorDetailService.insertPersonnelMonthlyAssessmentIndicatorDetail(personnelMonthlyAssessmentIndicatorDetail);
                if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList())) {
                    personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().forEach(personnelMonthlyAssessmentIndicatorRewardPunishmentDetail -> {
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setId(null);
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setSourceId(personnelMonthlyAssessmentIndicatorDetail.getId());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setCreateBy(personnelMonthlyAssessmentIndicatorDetail.getCreateBy());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setCreateTime(DateUtils.getNowDate());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setUpdateBy(personnelMonthlyAssessmentIndicatorDetail.getCreateBy());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetail.setUpdateTime(DateUtils.getNowDate());
                        personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.insertPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail(personnelMonthlyAssessmentIndicatorRewardPunishmentDetail);
                    });
                }
            });
        }
        eventPublisher.publishEvent(new PersonnelEvent(this, personnelNonCadreMonthlyAssessment.getAssessmentMonth()));
        return result;
    }

    /**
     * 批量删除非干部月度考核
     *
     * @param ids 需要删除的非干部月度考核主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deletePersonnelNonCadreMonthlyAssessmentByIds(Long[] ids) {
        int result = personnelNonCadreMonthlyAssessmentMapper.deletePersonnelNonCadreMonthlyAssessmentByIds(ids);
        for (Long id : ids) {
            LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
            detailQueryWrapper.eq(PersonnelMonthlyAssessmentIndicatorDetail::getSourceId, id);
            List<PersonnelMonthlyAssessmentIndicatorDetail> personnelMonthlyAssessmentIndicatorDetailListOld = personnelMonthlyAssessmentIndicatorDetailService.getBaseMapper().selectList(detailQueryWrapper);
            if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorDetailListOld)) {
                personnelMonthlyAssessmentIndicatorDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorDetailListOld);
                LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> rewardPunishmentDetailQueryWrapper = new LambdaQueryWrapper<>();
                rewardPunishmentDetailQueryWrapper.in(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getSourceId, personnelMonthlyAssessmentIndicatorDetailListOld.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getId).toArray());
                List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld = personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.getBaseMapper().selectList(rewardPunishmentDetailQueryWrapper);
                if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld)) {
                    personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld);
                }
            }
        }
        return result;
    }

    /**
     * 删除非干部月度考核信息
     *
     * @param id 非干部月度考核主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deletePersonnelNonCadreMonthlyAssessmentById(Long id) {
        int result = personnelNonCadreMonthlyAssessmentMapper.deletePersonnelNonCadreMonthlyAssessmentById(id);
        LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorDetail> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(PersonnelMonthlyAssessmentIndicatorDetail::getSourceId, id);
        List<PersonnelMonthlyAssessmentIndicatorDetail> personnelMonthlyAssessmentIndicatorDetailListOld = personnelMonthlyAssessmentIndicatorDetailService.getBaseMapper().selectList(detailQueryWrapper);
        if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorDetailListOld)) {
            personnelMonthlyAssessmentIndicatorDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorDetailListOld);
            LambdaQueryWrapper<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> rewardPunishmentDetailQueryWrapper = new LambdaQueryWrapper<>();
            rewardPunishmentDetailQueryWrapper.in(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getSourceId, personnelMonthlyAssessmentIndicatorDetailListOld.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getId).toArray());
            List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld = personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.getBaseMapper().selectList(rewardPunishmentDetailQueryWrapper);
            if (CollUtil.isNotEmpty(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld)) {
                personnelMonthlyAssessmentIndicatorRewardPunishmentDetailService.removeBatchByIds(personnelMonthlyAssessmentIndicatorRewardPunishmentDetailListOld);
            }
        }
        return result;
    }

    /**
     * 完善数据
     *
     * @param result 非干部月度考核
     * @return 非干部月度考核
     */
    @Override
    public void doImprove(PersonnelNonCadreMonthlyAssessment result) {
        // 大队
        Map<Long, Long> userBrigadeIdMap = new HashMap<>();
        SysDept brigadeQuery = new SysDept();
        brigadeQuery.setDeptType(DeptTypeEnum.BRIGADE.getCode());
        List<SysDept> brigadeList = sysDeptService.selectDeptInfoAll(brigadeQuery);
        Map<Long, String> brigadeMap = brigadeList.stream().collect(Collectors.toMap(SysDept::getDeptId, SysDept::getDeptName));
        brigadeList.forEach(brigade -> {
            List<SysUser> sysUserList = sysUserService.selectUserByDeptId(brigade.getDeptId());
            sysUserList.forEach(sysUser -> {
                userBrigadeIdMap.put(sysUser.getUserId(), brigade.getDeptId());
            });
        });
        result.setBrigadeId(userBrigadeIdMap.get(result.getUserId()));
        result.setBrigadeName(brigadeMap.get(result.getBrigadeId()));
        List<BasePerformanceIndicatorCategory> indicatorCategoryyList = basePerformanceIndicatorCategoryService.selectBasePerformanceIndicatorCategoryListTree(new BasePerformanceIndicatorCategory());
        // 红线指标
        BasePerformanceIndicatorCategory redLineIndexCategory = indicatorCategoryyList.stream().filter(item -> StrUtil.equals("红线指标", item.getName())).findFirst().orElse(null);
        List<BasePerformanceIndicatorCategory> redLineIndexCategoryChildren = (List<BasePerformanceIndicatorCategory>) redLineIndexCategory.getChildren();
        List<String> redLineIndexCategoryCodeList = getIndicatorCodeList(redLineIndexCategoryChildren.stream().map(BasePerformanceIndicatorCategory::getCode).collect(Collectors.toList()));
        List<PersonnelMonthlyAssessmentIndicatorDetail> redLineIndexAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream().filter(item -> redLineIndexCategoryCodeList.contains(item.getIndicatorCode())).collect(Collectors.toList());
        Integer redLineIndexTriggerCount = redLineIndexAccordList.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getOccurCount).filter(ObjUtil::isNotNull).reduce(0, Integer::sum);
        result.setRedLineIndexTriggerCount(redLineIndexTriggerCount);
        result.setRedLineIndexAccordList(redLineIndexAccordList);
        // 核心指标
        BasePerformanceIndicatorCategory coreIndexCategory = indicatorCategoryyList.stream().filter(item -> StrUtil.equals("核心指标", item.getName())).findFirst().orElse(null);
        List<BasePerformanceIndicatorCategory> coreIndexCategoryChildren = (List<BasePerformanceIndicatorCategory>) coreIndexCategory.getChildren();
        List<String> coreIndexCategoryCodeList = getIndicatorCodeList(coreIndexCategoryChildren.stream().map(BasePerformanceIndicatorCategory::getCode).collect(Collectors.toList()));
        List<PersonnelMonthlyAssessmentIndicatorDetail> coreIndexAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream().filter(item -> coreIndexCategoryCodeList.contains(item.getIndicatorCode())).collect(Collectors.toList());
        BigDecimal coreIndexScore = coreIndexAccordList.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getScoreResult).filter(ObjUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setCoreIndexScore(coreIndexScore);
        result.setCoreIndexAccordList(coreIndexAccordList);
        // 其他指标
        BasePerformanceIndicatorCategory otherIndexCategory = indicatorCategoryyList.stream().filter(item -> StrUtil.equals("其他指标", item.getName())).findFirst().orElse(null);
        List<BasePerformanceIndicatorCategory> otherIndexCategoryChildren = (List<BasePerformanceIndicatorCategory>) otherIndexCategory.getChildren();
        List<String> otherIndexCategoryCodeList = getIndicatorCodeList(otherIndexCategoryChildren.stream().map(BasePerformanceIndicatorCategory::getCode).collect(Collectors.toList()));
        List<PersonnelMonthlyAssessmentIndicatorDetail> otherIndexAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream().filter(item -> otherIndexCategoryCodeList.contains(item.getIndicatorCode())).collect(Collectors.toList());
        BigDecimal otherIndexScore = otherIndexAccordList.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getScoreResult).filter(ObjUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setOtherIndexScore(otherIndexScore);
        result.setOtherIndexAccordList(otherIndexAccordList);
        // 其他指标-安全
        List<BasePerformanceIndicatorCategory> otherIndexSafetyCategory = otherIndexCategoryChildren.stream().filter(item -> StrUtil.equals("安全", item.getName())).collect(Collectors.toList());
        List<String> otherIndexSafetyCategoryCodeList = getIndicatorCodeList(otherIndexSafetyCategory.stream().map(BasePerformanceIndicatorCategory::getCode).collect(Collectors.toList()));
        // 其他指标-安全-仅含SOC/站品控检查扣分
        List<PersonnelMonthlyAssessmentIndicatorDetail> otherIndexWithSocStationQcAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> otherIndexSafetyCategoryCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        otherIndexWithSocStationQcAccordList = otherIndexWithSocStationQcAccordList.stream()
                .peek(personnelMonthlyAssessmentIndicatorDetail -> {
                    List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> filteredItemList = personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream()
                            .filter(item -> StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.SOC.getCode(), item.getQcDeptType()) || StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.STATION_QC.getCode(), item.getQcDeptType()))
                            .collect(Collectors.toList());
                    personnelMonthlyAssessmentIndicatorDetail.setPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList(filteredItemList);
                })
                .filter(item -> CollUtil.isNotEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()))
                .collect(Collectors.toList());
        BigDecimal otherIndexSafetyScoreWithSocStationQcDeduction = CollUtil.isEmpty(otherIndexWithSocStationQcAccordList) ? BigDecimal.ZERO :
                otherIndexWithSocStationQcAccordList.stream()
                        .flatMap(item -> CollUtil.isEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()) ? Stream.empty() : item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream())
                        .map(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getScore)
                        .filter(ObjUtil::isNotNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setOtherIndexSafetyScoreWithSocStationQcDeduction(otherIndexSafetyScoreWithSocStationQcDeduction);
        result.setOtherIndexSafetyScoreWithSocStationQcAccordList(otherIndexWithSocStationQcAccordList);
        // 其他指标-安全-不仅含SOC/站品控检查扣分
        List<PersonnelMonthlyAssessmentIndicatorDetail> otherIndexWithoutSocStationQcAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> otherIndexSafetyCategoryCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        otherIndexWithoutSocStationQcAccordList = otherIndexWithoutSocStationQcAccordList.stream()
                .peek(personnelMonthlyAssessmentIndicatorDetail -> {
                    List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> filteredItemList = personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream()
                            .filter(item -> !(StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.SOC.getCode(), item.getQcDeptType()) || StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.STATION_QC.getCode(), item.getQcDeptType())))
                            .collect(Collectors.toList());
                    personnelMonthlyAssessmentIndicatorDetail.setPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList(filteredItemList);
                })
                .filter(item -> CollUtil.isNotEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()))
                .collect(Collectors.toList());
        BigDecimal otherIndexSafetyScoreWithoutSocStationQcDeduction = CollUtil.isEmpty(otherIndexWithoutSocStationQcAccordList) ? BigDecimal.ZERO :
                otherIndexWithoutSocStationQcAccordList.stream()
                        .flatMap(item -> CollUtil.isEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()) ? Stream.empty() : item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream())
                        .map(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getScore)
                        .filter(ObjUtil::isNotNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setOtherIndexSafetyScoreWithoutSocStationQcDeduction(otherIndexSafetyScoreWithoutSocStationQcDeduction);
        result.setOtherIndexSafetyScoreWithoutSocStationQcAccordList(otherIndexWithoutSocStationQcAccordList);
        // 其他指标-非安全
        List<BasePerformanceIndicatorCategory> otherIndexNonSafetyCategory = otherIndexCategoryChildren.stream().filter(item -> !StrUtil.equals("安全", item.getName())).collect(Collectors.toList());
        List<String> otherIndexNonSafetyCategoryCodeList = getIndicatorCodeList(otherIndexNonSafetyCategory.stream().map(BasePerformanceIndicatorCategory::getCode).collect(Collectors.toList()));
        List<PersonnelMonthlyAssessmentIndicatorDetail> otherIndexNonSafetyAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> otherIndexNonSafetyCategoryCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        BigDecimal otherIndexNonSafetyDeduction = otherIndexNonSafetyAccordList.stream().map(PersonnelMonthlyAssessmentIndicatorDetail::getScoreResult).filter(ObjUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setOtherIndexNonSafetyDeduction(otherIndexNonSafetyDeduction);
        result.setOtherIndexNonSafetyAccordList(otherIndexNonSafetyAccordList);
        // 非核心安全+核心扣分
        BigDecimal nonCoreSafetyPlusCoreDeduction = result.getOtherIndexSafetyScoreWithSocStationQcDeduction().add(result.getOtherIndexSafetyScoreWithoutSocStationQcDeduction()).add(result.getOtherIndexNonSafetyDeduction());
        result.setNonCoreSafetyPlusCoreDeduction(nonCoreSafetyPlusCoreDeduction);
        // 核心指标+其他指标-安全
        List<String> socStationQcInvolvedCoreSafetyCodeList = new ArrayList<>();
        socStationQcInvolvedCoreSafetyCodeList.addAll(coreIndexCategoryCodeList);
        socStationQcInvolvedCoreSafetyCodeList.addAll(otherIndexSafetyCategoryCodeList);
        List<PersonnelMonthlyAssessmentIndicatorDetail> socStationQcInvolvedCoreSafetyAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> socStationQcInvolvedCoreSafetyCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        socStationQcInvolvedCoreSafetyAccordList = socStationQcInvolvedCoreSafetyAccordList.stream()
                .peek(personnelMonthlyAssessmentIndicatorDetail -> {
                    List<PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail> filteredItemList = personnelMonthlyAssessmentIndicatorDetail.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream()
                            .filter(item -> !(StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.SOC.getCode(), item.getQcDeptType()) || StrUtil.equals(BasePerformanceIndicatorQcDeptTypeEnum.STATION_QC.getCode(), item.getQcDeptType())))
                            .collect(Collectors.toList());
                    personnelMonthlyAssessmentIndicatorDetail.setPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList(filteredItemList);
                })
                .filter(item -> CollUtil.isNotEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()))
                .collect(Collectors.toList());
        BigDecimal socStationQcInvolvedCoreSafetyDeduction = CollUtil.isEmpty(socStationQcInvolvedCoreSafetyAccordList) ? BigDecimal.ZERO :
                socStationQcInvolvedCoreSafetyAccordList.stream()
                        .flatMap(item -> CollUtil.isEmpty(item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList()) ? Stream.empty() : item.getPersonnelMonthlyAssessmentIndicatorRewardPunishmentDetailList().stream())
                        .map(PersonnelMonthlyAssessmentIndicatorRewardPunishmentDetail::getScore)
                        .filter(ObjUtil::isNotNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setSocStationQcInvolvedCoreSafetyDeduction(socStationQcInvolvedCoreSafetyDeduction);
        result.setSocStationQcInvolvedCoreSafetyAccordList(socStationQcInvolvedCoreSafetyAccordList);
        // 分管员工数量+扣分平均值
        if (StrUtil.equals(RoleTypeEnum.kezhang.getCode(), result.getRoleKey())) {
            PersonnelNonCadreMonthlyAssessment queryKeZhang = new PersonnelNonCadreMonthlyAssessment();
            queryKeZhang.setAssessmentMonth(result.getAssessmentMonth());
            queryKeZhang.setDeputySupervisorId(result.getUserId());
            List<PersonnelNonCadreMonthlyAssessment> personnelNonCadreMonthlyAssessmentKeZhangList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(queryKeZhang);
            result.setInChargeEmployeeCount(personnelNonCadreMonthlyAssessmentKeZhangList.size());
            result.setDeductionAverage(CollUtil.isEmpty(personnelNonCadreMonthlyAssessmentKeZhangList) ? BigDecimal.ZERO : result.getSocStationQcInvolvedCoreSafetyDeduction().divide(BigDecimal.valueOf(personnelNonCadreMonthlyAssessmentKeZhangList.size()), 2, RoundingMode.HALF_UP));
        }
        // 总分
        BigDecimal totalScore = BASE_SCORE.add(result.getCoreIndexScore()).add(result.getOtherIndexScore());
        if (result.getRedLineIndexTriggerCount() > 0) {
            totalScore = RED_LINE_SCORE;
        }
        result.setTotalScore(totalScore);
        // 奖励明细+惩罚明细
        List<String> coreAndOtherCategoryCodeList = new ArrayList<>();
        coreAndOtherCategoryCodeList.addAll(coreIndexCategoryCodeList);
        coreAndOtherCategoryCodeList.addAll(otherIndexCategoryCodeList);
        List<PersonnelMonthlyAssessmentIndicatorDetail> rewardAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> coreAndOtherCategoryCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.REWARD.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        result.setRewardAccordList(rewardAccordList);
        List<PersonnelMonthlyAssessmentIndicatorDetail> punishmentAccordList = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> coreAndOtherCategoryCodeList.contains(item.getIndicatorCode()))
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .collect(Collectors.toList());
        punishmentAccordList.addAll(result.getRedLineIndexAccordList());
        result.setPunishmentAccordList(punishmentAccordList);
        // 奖励金额+惩罚金额
        BigDecimal rewardAmount = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.REWARD.getCode(), item.getRewardPunishmentType()))
                .map(PersonnelMonthlyAssessmentIndicatorDetail::getAmountResult)
                .filter(ObjUtil::isNotNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setRewardAmount(rewardAmount);
        BigDecimal punishmentAmount = result.getPersonnelMonthlyAssessmentIndicatorDetailList().stream()
                .filter(item -> StrUtil.equals(BasePerformanceIndicatorRewardPunishmentTypeTypeEnum.PUNISHMENT.getCode(), item.getRewardPunishmentType()))
                .map(PersonnelMonthlyAssessmentIndicatorDetail::getAmountResult)
                .filter(ObjUtil::isNotNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        result.setPunishmentAmount(punishmentAmount);
        // 考核结果+是否豁免+应用方式
        if (StrUtil.equals(RoleTypeEnum.SecurityCheck.getCode(), result.getRoleKey())) {
            doSecurityCheck(result);
        } else if (StrUtil.equals(RoleTypeEnum.banzuzhang.getCode(), result.getRoleKey())) {
            doTeamLeader(result);
        } else if (StrUtil.equals(RoleTypeEnum.kezhang.getCode(), result.getRoleKey())) {
            doSupervisor(result);
        }
    }

    /**
     * 获取指标编码列表
     *
     * @param categoryCodeList
     * @return
     */
    private List<String> getIndicatorCodeList(List<String> categoryCodeList) {
        List<BasePerformanceIndicator> indicatorList = basePerformanceIndicatorService.selectBasePerformanceIndicatorListByCategoryCodeList(categoryCodeList);
        return indicatorList.stream().map(BasePerformanceIndicator::getCode).collect(Collectors.toList());
    }

    /**
     * 安检员考核
     *
     * @param result
     */
    private void doSecurityCheck(PersonnelNonCadreMonthlyAssessment result) {
        // 考核结果
        PersonnelNonCadreMonthlyAssessment assessmentTeamQuery = new PersonnelNonCadreMonthlyAssessment();
        assessmentTeamQuery.setAssessmentMonth(result.getAssessmentMonth());
        assessmentTeamQuery.setAssessmentTeam(result.getAssessmentTeam());
        List<PersonnelNonCadreMonthlyAssessment> assessmentTeamList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(assessmentTeamQuery);
        boolean assessmentResultRuleOne = isInBottom5Percent(result, assessmentTeamList, PersonnelNonCadreMonthlyAssessment::getTotalScore);
        boolean assessmentResultRuleTwo = result.getTotalScore().compareTo(BigDecimal.valueOf(75)) < 0;
        boolean assessmentResultRuleThree = result.getNonCoreSafetyPlusCoreDeduction().abs().compareTo(BigDecimal.valueOf(10)) >= 0;
        boolean assessmentResultRuleFour = result.getRedLineIndexTriggerCount() > 0 || result.getTotalScore().compareTo(BigDecimal.valueOf(70)) < 0;
        List<String> assessmentResultRuleList = new ArrayList<>();
        if (assessmentResultRuleOne) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getDesc());
        }
        if (assessmentResultRuleTwo) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getDesc());
        }
        if (assessmentResultRuleThree) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getDesc());
        }
        if (assessmentResultRuleFour) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getDesc());
        }
        if (CollUtil.isNotEmpty(assessmentResultRuleList)) {
            result.setAssessmentResultRemark(String.join(";", assessmentResultRuleList));
        }
        // 是否豁免
        if (StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName(), result.getAssessmentResult())) {
            boolean exemptionRuleOne = CollUtil.isEmpty(result.getPunishmentAccordList());
            boolean exemptionRuleTwo = result.getPunishmentAccordList().stream()
                    .filter(item -> !(StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_LEAVE.getCode(), item.getLeaveType())
                            || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.SICK_LEAVE.getCode(), item.getLeaveType())
                            || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_SICK_LEAVE.getCode(), item.getLeaveType())))
                    .count() == 0;
            if (exemptionRuleOne) {
                result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getName());
                result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getDesc());
                result.setAssessmentResult(null);
            } else if (exemptionRuleTwo) {
                result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getName());
                result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getDesc());
                result.setAssessmentResult(null);
            }
        }
        // 应用方式
        boolean applicationMethodRuleOne = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult());
        boolean applicationMethodRuleTwo1 = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), result.getAssessmentResult());
        boolean applicationMethodRuleTwo2_1 = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult());
        String previousMonth = MonthUtils.getPreviousMonth(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment previousMonthQuery = new PersonnelNonCadreMonthlyAssessment();
        previousMonthQuery.setUserId(result.getUserId());
        previousMonthQuery.setAssessmentMonth(previousMonth);
        previousMonthQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
        List<PersonnelNonCadreMonthlyAssessment> previousMonthList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(previousMonthQuery);
        boolean applicationMethodRuleTwo2_2 = CollUtil.isNotEmpty(previousMonthList);
        boolean applicationMethodRuleTwo2 = applicationMethodRuleTwo2_1 && applicationMethodRuleTwo2_2;
        boolean applicationMethodRuleTwo = applicationMethodRuleTwo1 || applicationMethodRuleTwo2;
        boolean applicationMethodRuleThree = false;
        if (StrUtil.equals(AssessmentTeamEnum.SECURITY_INSPECTOR_AND_X_RAY_PASSENGER_INSPECTION_STAFF.getCode(), result.getAssessmentTeam())) {
            MonthUtils.MonthRange last3Months = MonthUtils.getLast3MonthsIncludeCurrent(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment last3MonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            last3MonthsQuery.setUserId(result.getUserId());
            last3MonthsQuery.setAssessmentMonthStart(last3Months.getStartMonth());
            last3MonthsQuery.setAssessmentMonthEnd(last3Months.getEndMonth());
            last3MonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            List<PersonnelNonCadreMonthlyAssessment> last3MonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last3MonthsQuery);
            boolean applicationMethodRuleThree1 = last3MonthsList.size() >= 3;
            MonthUtils.MonthRange currentYearMonths = MonthUtils.getCurrentYearToMonth(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment currentYearMonthsResultRuleQuery = new PersonnelNonCadreMonthlyAssessment();
            currentYearMonthsResultRuleQuery.setUserId(result.getUserId());
            currentYearMonthsResultRuleQuery.setAssessmentMonthStart(currentYearMonths.getStartMonth());
            currentYearMonthsResultRuleQuery.setAssessmentMonthEnd(currentYearMonths.getEndMonth());
            currentYearMonthsResultRuleQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            List<PersonnelNonCadreMonthlyAssessment> currentYearMonthsResultRuleList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentYearMonthsResultRuleQuery);
            boolean applicationMethodRuleThree2 = currentYearMonthsResultRuleList.size() >= 4;
            MonthUtils.MonthRange last12Months = MonthUtils.getLast12MonthsIncludeCurrent(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment last12MonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            last12MonthsQuery.setUserId(result.getUserId());
            last12MonthsQuery.setAssessmentMonthStart(last12Months.getStartMonth());
            last12MonthsQuery.setAssessmentMonthEnd(last12Months.getEndMonth());
            last12MonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            List<PersonnelNonCadreMonthlyAssessment> last12MonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last12MonthsQuery);
            boolean applicationMethodRuleThree3 = last12MonthsList.size() >= 2;
            applicationMethodRuleThree = applicationMethodRuleThree1 || applicationMethodRuleThree2 || applicationMethodRuleThree3;
        }
        boolean applicationMethodRuleFour = false;
        MonthUtils.MonthRange currentYearMonthsMethod = MonthUtils.getCurrentYearToMonth(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment currentYearMonthsMethodQuery = new PersonnelNonCadreMonthlyAssessment();
        currentYearMonthsMethodQuery.setUserId(result.getUserId());
        currentYearMonthsMethodQuery.setAssessmentMonthStart(currentYearMonthsMethod.getStartMonth());
        currentYearMonthsMethodQuery.setAssessmentMonthEnd(currentYearMonthsMethod.getEndMonth());
        currentYearMonthsMethodQuery.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getName());
        List<PersonnelNonCadreMonthlyAssessment> currentYearMonthsMethodList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentYearMonthsMethodQuery);
        String maxAssessmentMonth = currentYearMonthsMethodList.stream().map(PersonnelNonCadreMonthlyAssessment::getAssessmentMonth).max(String::compareTo).orElse(null);
        if (ObjUtil.isNotNull(maxAssessmentMonth) && !StrUtil.equals(maxAssessmentMonth, result.getAssessmentMonth())) {
            PersonnelNonCadreMonthlyAssessment remainingMonthsOfYearQuery = new PersonnelNonCadreMonthlyAssessment();
            remainingMonthsOfYearQuery.setUserId(result.getUserId());
            remainingMonthsOfYearQuery.setAssessmentMonthStart(MonthUtils.getNextMonth(maxAssessmentMonth));
            remainingMonthsOfYearQuery.setAssessmentMonthEnd(result.getAssessmentMonth());
            List<PersonnelNonCadreMonthlyAssessment> remainingMonthsOfYearQueryList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(remainingMonthsOfYearQuery);
            applicationMethodRuleFour = remainingMonthsOfYearQueryList.stream().filter(item -> StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), item.getAssessmentResult()) || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), item.getAssessmentResult())).count() > 0;
        }
        if (applicationMethodRuleOne) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getDesc());
        }
        if (applicationMethodRuleTwo) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getDesc());
        }
        if (applicationMethodRuleThree) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_THREE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_THREE.getDesc());
        }
        if (applicationMethodRuleFour) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FOUR.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FOUR.getDesc());
        }
    }

    /**
     * 班组长考核
     *
     * @param result
     */
    private void doTeamLeader(PersonnelNonCadreMonthlyAssessment result) {
        // 考核结果
        PersonnelNonCadreMonthlyAssessment assessmentTeamQuery = new PersonnelNonCadreMonthlyAssessment();
        assessmentTeamQuery.setAssessmentMonth(result.getAssessmentMonth());
        assessmentTeamQuery.setAssessmentTeam(result.getAssessmentTeam());
        List<PersonnelNonCadreMonthlyAssessment> assessmentTeamList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(assessmentTeamQuery);
        boolean assessmentResultRuleOne = isInBottom5Percent(result, assessmentTeamList, PersonnelNonCadreMonthlyAssessment::getTotalScore);
        boolean assessmentResultRuleTwo = result.getTotalScore().compareTo(BigDecimal.valueOf(75)) < 0;
        boolean assessmentResultRuleThree = result.getNonCoreSafetyPlusCoreDeduction().abs().compareTo(BigDecimal.valueOf(10)) >= 0;
        boolean assessmentResultRuleFour = result.getRedLineIndexTriggerCount() > 0 || result.getTotalScore().compareTo(BigDecimal.valueOf(70)) < 0;
        SysUser sysUser = sysUserService.selectUserById(result.getUserId());
        List<String> roleKeyList = Collections.singletonList(RoleTypeEnum.SecurityCheck.getCode());
        List<SysUser> sysUserList = sysUserService.selectUserListByRoleKeyAndDeptId(roleKeyList, sysUser.getDeptId());
        List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
        PersonnelNonCadreMonthlyAssessment currentMonthQuery = new PersonnelNonCadreMonthlyAssessment();
        currentMonthQuery.setAssessmentMonth(result.getAssessmentMonth());
        currentMonthQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
        List<PersonnelNonCadreMonthlyAssessment> currentMonthList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentMonthQuery);
        boolean assessmentResultRuleFive = currentMonthList.stream().filter(item -> userIdList.contains(item.getUserId())).count() >= 2;
        MonthUtils.MonthRange last12MonthsCurrent = MonthUtils.getLast12MonthsIncludeCurrent(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment last12MonthsResultRuleQuery = new PersonnelNonCadreMonthlyAssessment();
        last12MonthsResultRuleQuery.setUserId(result.getUserId());
        last12MonthsResultRuleQuery.setAssessmentMonthStart(last12MonthsCurrent.getStartMonth());
        last12MonthsResultRuleQuery.setAssessmentMonthEnd(last12MonthsCurrent.getEndMonth());
        last12MonthsResultRuleQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
        List<PersonnelNonCadreMonthlyAssessment> last12MonthsCurrentList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last12MonthsResultRuleQuery);
        boolean assessmentResultRuleSix = last12MonthsCurrentList.size() >= 2;
        List<String> assessmentResultRuleList = new ArrayList<>();
        if (assessmentResultRuleOne) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getDesc());
        }
        if (assessmentResultRuleTwo) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getDesc());
        }
        if (assessmentResultRuleThree) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getDesc());
        }
        if (assessmentResultRuleFour) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getDesc());
        }
        if (assessmentResultRuleFive) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FIVE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FIVE.getDesc());
        }
        if (assessmentResultRuleSix) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SIX.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SIX.getDesc());
        }
        if (CollUtil.isNotEmpty(assessmentResultRuleList)) {
            result.setAssessmentResultRemark(String.join(";", assessmentResultRuleList));
        }
        // 是否豁免
        if (StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName(), result.getAssessmentResult())) {
            boolean exemptionRuleOne = CollUtil.isEmpty(result.getPunishmentAccordList());
            boolean exemptionRuleTwo = result.getPunishmentAccordList().stream()
                    .filter(item -> !(StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_LEAVE.getCode(), item.getLeaveType())
                            || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.SICK_LEAVE.getCode(), item.getLeaveType())
                            || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_SICK_LEAVE.getCode(), item.getLeaveType())))
                    .count() == 0;
            if (exemptionRuleOne) {
                result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getName());
                result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getDesc());
                result.setAssessmentResult(null);
            } else if (exemptionRuleTwo) {
                result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getName());
                result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getDesc());
                result.setAssessmentResult(null);
            }
        }
        // 应用方式
        boolean applicationMethodRuleOne = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult());
        boolean applicationMethodRuleTwo1 = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), result.getAssessmentResult());
        boolean applicationMethodRuleTwo2_1 = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult());
        String previousMonth = MonthUtils.getPreviousMonth(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment previousMonthQuery = new PersonnelNonCadreMonthlyAssessment();
        previousMonthQuery.setUserId(result.getUserId());
        previousMonthQuery.setAssessmentMonth(previousMonth);
        previousMonthQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
        List<PersonnelNonCadreMonthlyAssessment> previousMonthList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(previousMonthQuery);
        boolean applicationMethodRuleTwo2_2 = CollUtil.isNotEmpty(previousMonthList);
        boolean applicationMethodRuleTwo2 = applicationMethodRuleTwo2_1 && applicationMethodRuleTwo2_2;
        boolean applicationMethodRuleTwo = applicationMethodRuleTwo1 || applicationMethodRuleTwo2;
        boolean applicationMethodRuleThree = false;
        if (StrUtil.equals(AssessmentTeamEnum.SECURITY_INSPECTOR_AND_X_RAY_PASSENGER_INSPECTION_STAFF.getCode(), result.getAssessmentTeam())) {
            MonthUtils.MonthRange last3Months = MonthUtils.getLast3MonthsIncludeCurrent(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment last3MonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            last3MonthsQuery.setUserId(result.getUserId());
            last3MonthsQuery.setAssessmentMonthStart(last3Months.getStartMonth());
            last3MonthsQuery.setAssessmentMonthEnd(last3Months.getEndMonth());
            last3MonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            List<PersonnelNonCadreMonthlyAssessment> last3MonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last3MonthsQuery);
            boolean applicationMethodRuleThree1 = last3MonthsList.size() >= 3;
            MonthUtils.MonthRange currentYearMonths = MonthUtils.getCurrentYearToMonth(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment currentYearMonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            currentYearMonthsQuery.setUserId(result.getUserId());
            currentYearMonthsQuery.setAssessmentMonthStart(currentYearMonths.getStartMonth());
            currentYearMonthsQuery.setAssessmentMonthEnd(currentYearMonths.getEndMonth());
            currentYearMonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            List<PersonnelNonCadreMonthlyAssessment> currentYearMonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentYearMonthsQuery);
            boolean applicationMethodRuleThree2 = currentYearMonthsList.size() >= 4;
            MonthUtils.MonthRange last12Months = MonthUtils.getLast12MonthsIncludeCurrent(result.getAssessmentMonth());
            PersonnelNonCadreMonthlyAssessment last12MonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            last12MonthsQuery.setUserId(result.getUserId());
            last12MonthsQuery.setAssessmentMonthStart(last12Months.getStartMonth());
            last12MonthsQuery.setAssessmentMonthEnd(last12Months.getEndMonth());
            last12MonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            List<PersonnelNonCadreMonthlyAssessment> last12MonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last12MonthsQuery);
            boolean applicationMethodRuleThree3 = last12MonthsList.size() >= 2;
            applicationMethodRuleThree = applicationMethodRuleThree1 || applicationMethodRuleThree2 || applicationMethodRuleThree3;
        }
        boolean applicationMethodRuleFour = false;
        MonthUtils.MonthRange currentYearMonthsTraining = MonthUtils.getCurrentYearToMonth(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment currentYearMonthsTrainingQuery = new PersonnelNonCadreMonthlyAssessment();
        currentYearMonthsTrainingQuery.setUserId(result.getUserId());
        currentYearMonthsTrainingQuery.setAssessmentMonthStart(currentYearMonthsTraining.getStartMonth());
        currentYearMonthsTrainingQuery.setAssessmentMonthEnd(currentYearMonthsTraining.getEndMonth());
        currentYearMonthsTrainingQuery.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getName());
        List<PersonnelNonCadreMonthlyAssessment> currentYearMonthsTrainingList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentYearMonthsTrainingQuery);
        String maxAssessmentMonth = currentYearMonthsTrainingList.stream().map(PersonnelNonCadreMonthlyAssessment::getAssessmentMonth).max(String::compareTo).orElse(null);
        if (ObjUtil.isNotNull(maxAssessmentMonth) && !StrUtil.equals(maxAssessmentMonth, result.getAssessmentMonth())) {
            PersonnelNonCadreMonthlyAssessment remainingMonthsOfYearQuery = new PersonnelNonCadreMonthlyAssessment();
            remainingMonthsOfYearQuery.setUserId(result.getUserId());
            remainingMonthsOfYearQuery.setAssessmentMonthStart(MonthUtils.getNextMonth(maxAssessmentMonth));
            remainingMonthsOfYearQuery.setAssessmentMonthEnd(result.getAssessmentMonth());
            List<PersonnelNonCadreMonthlyAssessment> remainingMonthsOfYearQueryList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(remainingMonthsOfYearQuery);
            applicationMethodRuleFour = remainingMonthsOfYearQueryList.stream().filter(item -> StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), item.getAssessmentResult()) || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), item.getAssessmentResult())).count() > 0;
        }
        if (applicationMethodRuleOne) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getDesc());
        }
        if (applicationMethodRuleTwo) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_TWO.getDesc());
        }
        if (applicationMethodRuleThree) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_THREE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_THREE.getDesc());
        }
        if (applicationMethodRuleFour) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FOUR.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FOUR.getDesc());
        }
    }

    /**
     * 主管考核
     *
     * @param result
     */
    private void doSupervisor(PersonnelNonCadreMonthlyAssessment result) {
        // 考核结果
        PersonnelNonCadreMonthlyAssessment assessmentTeamQuery = new PersonnelNonCadreMonthlyAssessment();
        assessmentTeamQuery.setAssessmentMonth(result.getAssessmentMonth());
        assessmentTeamQuery.setAssessmentTeam(result.getAssessmentTeam());
        List<PersonnelNonCadreMonthlyAssessment> assessmentTeamList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(assessmentTeamQuery);
        boolean assessmentResultRuleOne = isInBottom5Percent(result, assessmentTeamList, PersonnelNonCadreMonthlyAssessment::getTotalScore);
        boolean assessmentResultRuleSeven = isInBottom1Ranking(result, assessmentTeamList, PersonnelNonCadreMonthlyAssessment::getTotalScore);
        boolean assessmentResultRuleTwo = result.getTotalScore().compareTo(BigDecimal.valueOf(75)) < 0;
        boolean assessmentResultRuleThree = result.getNonCoreSafetyPlusCoreDeduction().abs().compareTo(BigDecimal.valueOf(10)) >= 0;
        boolean assessmentResultRuleFour = result.getRedLineIndexTriggerCount() > 0 || result.getTotalScore().compareTo(BigDecimal.valueOf(70)) < 0;
        List<String> assessmentResultRuleList = new ArrayList<>();
        if (assessmentResultRuleOne) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getDesc());
        }
        if (assessmentResultRuleSeven) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SEVEN.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SEVEN.getDesc());
        }
        if (assessmentResultRuleTwo) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getDesc());
        }
        if (assessmentResultRuleThree) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getDesc());
        }
        if (assessmentResultRuleFour) {
            result.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName());
            assessmentResultRuleList.add(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getDesc());
        }
        if (CollUtil.isNotEmpty(assessmentResultRuleList)) {
            result.setAssessmentResultRemark(String.join(";", assessmentResultRuleList));
        }
        // 是否豁免
        if (StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_THREE.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_FOUR.getName(), result.getAssessmentResult())
                || StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SEVEN.getName(), result.getAssessmentResult())) {
            if (!result.getAssessmentResultRemark().contains(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_SEVEN.getDesc())) {
                boolean exemptionRuleOne = CollUtil.isEmpty(result.getPunishmentAccordList());
                boolean exemptionRuleTwo = result.getPunishmentAccordList().stream()
                        .filter(item -> !(StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_LEAVE.getCode(), item.getLeaveType())
                                || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.SICK_LEAVE.getCode(), item.getLeaveType())
                                || StrUtil.equals(BasePerformanceIndicatorLeaveTypeEnum.PERSONAL_SICK_LEAVE.getCode(), item.getLeaveType())))
                        .count() == 0;
                if (exemptionRuleOne) {
                    result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getName());
                    result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_ONE.getDesc());
                    result.setAssessmentResult(null);
                } else if (exemptionRuleTwo) {
                    result.setExemption(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getName());
                    result.setExemptionReasonRemark(BasePerformanceIndicatorExemptionRuleEnum.EXEMPTION_RULE_TWO.getDesc());
                    result.setAssessmentResult(null);
                }
            }
        }
        // 应用方式
        boolean applicationMethodRuleOne = StrUtil.equals(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName(), result.getAssessmentResult());
        boolean applicationMethodRuleFive = false;
        MonthUtils.MonthRange last12Months = MonthUtils.getLast12MonthsIncludeCurrent(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment last12MonthsQuery = new PersonnelNonCadreMonthlyAssessment();
        last12MonthsQuery.setUserId(result.getUserId());
        last12MonthsQuery.setAssessmentMonthStart(last12Months.getStartMonth());
        last12MonthsQuery.setAssessmentMonthEnd(last12Months.getEndMonth());
        last12MonthsQuery.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getName());
        List<PersonnelNonCadreMonthlyAssessment> last12MonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(last12MonthsQuery);
        String last12MonthsMaxAssessmentMonth = last12MonthsList.stream().map(PersonnelNonCadreMonthlyAssessment::getAssessmentMonth).max(String::compareTo).orElse(null);
        if (ObjUtil.isNotNull(last12MonthsMaxAssessmentMonth) && !StrUtil.equals(last12MonthsMaxAssessmentMonth, result.getAssessmentMonth())) {
            PersonnelNonCadreMonthlyAssessment lastMonthsQuery = new PersonnelNonCadreMonthlyAssessment();
            lastMonthsQuery.setUserId(result.getUserId());
            lastMonthsQuery.setAssessmentMonthStart(MonthUtils.getNextMonth(last12MonthsMaxAssessmentMonth));
            lastMonthsQuery.setAssessmentMonthEnd(result.getAssessmentMonth());
            lastMonthsQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_ONE.getName());
            List<PersonnelNonCadreMonthlyAssessment> lastMonthsList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(lastMonthsQuery);
            applicationMethodRuleFive = lastMonthsList.size() >= 3;
        }
        boolean applicationMethodRuleSix = false;
        MonthUtils.MonthRange currentYearMonthsTraining = MonthUtils.getCurrentYearToMonth(result.getAssessmentMonth());
        PersonnelNonCadreMonthlyAssessment currentYearMonthsTrainingQuery = new PersonnelNonCadreMonthlyAssessment();
        currentYearMonthsTrainingQuery.setUserId(result.getUserId());
        currentYearMonthsTrainingQuery.setAssessmentMonthStart(currentYearMonthsTraining.getStartMonth());
        currentYearMonthsTrainingQuery.setAssessmentMonthEnd(currentYearMonthsTraining.getEndMonth());
        currentYearMonthsTrainingQuery.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getName());
        List<PersonnelNonCadreMonthlyAssessment> currentYearMonthsTrainingList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(currentYearMonthsTrainingQuery);
        String maxAssessmentMonth = currentYearMonthsTrainingList.stream().map(PersonnelNonCadreMonthlyAssessment::getAssessmentMonth).max(String::compareTo).orElse(null);
        if (ObjUtil.isNotNull(maxAssessmentMonth) && !StrUtil.equals(maxAssessmentMonth, result.getAssessmentMonth())) {
            PersonnelNonCadreMonthlyAssessment remainingMonthsOfYearQuery = new PersonnelNonCadreMonthlyAssessment();
            remainingMonthsOfYearQuery.setUserId(result.getUserId());
            remainingMonthsOfYearQuery.setAssessmentMonthStart(MonthUtils.getNextMonth(maxAssessmentMonth));
            remainingMonthsOfYearQuery.setAssessmentMonthEnd(result.getAssessmentMonth());
            remainingMonthsOfYearQuery.setAssessmentResult(BasePerformanceIndicatorAssessmentResultRuleEnum.ASSESSMENT_RESULT_RULE_TWO.getName());
            List<PersonnelNonCadreMonthlyAssessment> remainingMonthsOfYearQueryList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(remainingMonthsOfYearQuery);
            applicationMethodRuleSix = CollUtil.isNotEmpty(remainingMonthsOfYearQueryList);
        }
        if (applicationMethodRuleOne) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_ONE.getDesc());
        }
        if (applicationMethodRuleFive) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FIVE.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_FIVE.getDesc());
        }
        if (applicationMethodRuleSix) {
            result.setApplicationMethod(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_SIX.getName());
            result.setApplicationMethodRemark(BasePerformanceIndicatorApplicationMethodRuleEnum.APPLICATION_METHOD_RULE_SIX.getDesc());
        }
    }

    /**
     * 判断当前用户分数是否处于最低的5%以内（包括并列）
     *
     * @param currentObj 当前用户对象
     * @param list       列表
     * @param scoreExtractor 分数提取器
     * @return true表示处于最低的5%以内，false表示处于最低的5%以外
     */
    private boolean isInBottom5Percent(PersonnelNonCadreMonthlyAssessment currentObj, List<PersonnelNonCadreMonthlyAssessment> list, java.util.function.Function<PersonnelNonCadreMonthlyAssessment, BigDecimal> scoreExtractor) {
        if (CollUtil.isEmpty(list)) {
            return false;
        }

        // 获取当前用户的分数
        BigDecimal currentScore = scoreExtractor.apply(currentObj);

        // 统计分数大于当前用户分数的人数（包括并列）
        long higherCount = list.stream()
                .map(scoreExtractor)
                .filter(score -> score.compareTo(currentScore) > 0)
                .count();

        // 计算百分比
        BigDecimal percentage = BigDecimal.valueOf(higherCount).divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP);

        // 判断当前用户的分数是否处于最高的95%以外（包括并列）
        return percentage.compareTo(BigDecimal.valueOf(0.95)) > 0;
    }

    /**
     * 判断当前用户分数是否排名最后1名（包括并列）
     *
     * @param currentObj 当前用户对象
     * @param list       列表
     * @param scoreExtractor 分数提取器
     * @return true表示排名最后1名，false表示排名非最后1名
     */
    private boolean isInBottom1Ranking(PersonnelNonCadreMonthlyAssessment currentObj, List<PersonnelNonCadreMonthlyAssessment> list, java.util.function.Function<PersonnelNonCadreMonthlyAssessment, BigDecimal> scoreExtractor) {
        if (CollUtil.isEmpty(list)) {
            return false;
        }

        // 获取当前用户的分数
        BigDecimal currentScore = scoreExtractor.apply(currentObj);

        // 统计分数小于当前用户分数的人数（包括并列）
        long lowerOrEqualCount = list.stream()
                .map(scoreExtractor)
                .filter(score -> score.compareTo(currentScore) < 0)
                .count();

        // 判断当前用户分数是否分数最低（包括并列）
        return lowerOrEqualCount == 0;
    }

    /**
     * 修改非干部月度考核-仅更新主表数据
     *
     * @param personnelNonCadreMonthlyAssessment 非干部月度考核
     * @return 结果
     */
    @Override
    public int updatePersonnelNonCadreMonthlyAssessmentOnly(PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessment) {
        personnelNonCadreMonthlyAssessment.setUpdateTime(DateUtils.getNowDate());
        return personnelNonCadreMonthlyAssessmentMapper.updatePersonnelNonCadreMonthlyAssessment(personnelNonCadreMonthlyAssessment);
    }

    /**
     * 自动生成指定月份非干部月度考核
     *
     * @param month 月份值
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<PersonnelNonCadreMonthlyAssessment> autoGenerate(String month) {
        List<PersonnelNonCadreMonthlyAssessment> result = new ArrayList<>();
        SysPersonnelUserConditionDto sysPersonnelUserConditionDtoQuery = new SysPersonnelUserConditionDto();
        sysPersonnelUserConditionDtoQuery.setMonth(month);
        List<SysUser> sysUserList = sysUserService.selectPersonnelUserList(sysPersonnelUserConditionDtoQuery);
        PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessmentQuery = new PersonnelNonCadreMonthlyAssessment();
        personnelNonCadreMonthlyAssessmentQuery.setAssessmentMonth(month);
        List<PersonnelNonCadreMonthlyAssessment> existList = personnelNonCadreMonthlyAssessmentMapper.selectPersonnelNonCadreMonthlyAssessmentList(personnelNonCadreMonthlyAssessmentQuery);
        List<Long> existUserIdList = existList.stream().map(PersonnelNonCadreMonthlyAssessment::getUserId).collect(Collectors.toList());
        sysUserList = sysUserList.stream().filter(sysUser -> !existUserIdList.contains(sysUser.getUserId())).collect(Collectors.toList());
        sysUserList.forEach(sysUser -> {
            PersonnelNonCadreMonthlyAssessment personnelNonCadreMonthlyAssessmentNew = new PersonnelNonCadreMonthlyAssessment();
            personnelNonCadreMonthlyAssessmentNew.setCreateBy(SecurityUtils.getLoginUser().getUsername());
            personnelNonCadreMonthlyAssessmentNew.setCreateTime(DateUtils.getNowDate());
            personnelNonCadreMonthlyAssessmentNew.setAssessmentMonth(month);
            personnelNonCadreMonthlyAssessmentNew.setUserId(sysUser.getUserId());
            personnelNonCadreMonthlyAssessmentNew.setUserName(sysUser.getUserName());
            if (CollUtil.isNotEmpty(sysUser.getRoles())) {
                personnelNonCadreMonthlyAssessmentNew.setRoleId(sysUser.getRoles().get(0).getRoleId());
                personnelNonCadreMonthlyAssessmentNew.setRoleName(sysUser.getRoles().get(0).getRoleName());
                personnelNonCadreMonthlyAssessmentNew.setRoleKey(sysUser.getRoles().get(0).getRoleKey());
            }
            personnelNonCadreMonthlyAssessmentNew.setEmploymentType(sysUser.getEmploymentType());
            personnelNonCadreMonthlyAssessmentNew.setAssessmentTeam(sysUser.getAssessmentTeam());
            personnelNonCadreMonthlyAssessmentNew.setPost(sysUser.getPost());
            SysUserLeaderConditionDto teamLeaderDto = new SysUserLeaderConditionDto();
            teamLeaderDto.setUserId(sysUser.getUserId());
            teamLeaderDto.setRoleKeyList(Collections.singletonList(RoleTypeEnum.banzuzhang.getCode()));
            List<SysUser> teamLeaderList = sysUserService.selectUserLeaderListByCondition(teamLeaderDto);
            if (CollUtil.isNotEmpty(teamLeaderList)) {
                personnelNonCadreMonthlyAssessmentNew.setDeputyTeamLeaderId(teamLeaderList.get(0).getUserId());
                personnelNonCadreMonthlyAssessmentNew.setDeputyTeamLeaderName(teamLeaderList.get(0).getUserName());
            }
            SysUserLeaderConditionDto supervisorDto = new SysUserLeaderConditionDto();
            supervisorDto.setUserId(sysUser.getUserId());
            supervisorDto.setRoleKeyList(Collections.singletonList(RoleTypeEnum.kezhang.getCode()));
            List<SysUser> supervisorList = sysUserService.selectUserLeaderListByCondition(supervisorDto);
            if (CollUtil.isNotEmpty(supervisorList)) {
                personnelNonCadreMonthlyAssessmentNew.setDeputySupervisorId(supervisorList.get(0).getUserId());
                personnelNonCadreMonthlyAssessmentNew.setDeputySupervisorName(supervisorList.get(0).getUserName());
            }
            SysUserLeaderConditionDto managerDto = new SysUserLeaderConditionDto();
            managerDto.setUserId(sysUser.getUserId());
            managerDto.setRoleKeyList(Collections.singletonList(RoleTypeEnum.jingli.getCode()));
            List<SysUser> managerList = sysUserService.selectUserLeaderListByCondition(managerDto);
            if (CollUtil.isNotEmpty(managerList)) {
                if (managerList.size() > 1) {
                    managerList = managerList.stream().filter(item -> StrUtil.equals(item.getWorkArea(), sysUser.getWorkArea())).collect(Collectors.toList());
                }
                if (CollUtil.isNotEmpty(managerList)) {
                    personnelNonCadreMonthlyAssessmentNew.setDeputyManagerId(managerList.get(0).getUserId());
                    personnelNonCadreMonthlyAssessmentNew.setDeputyManagerName(managerList.get(0).getUserName());
                }
            }
            personnelNonCadreMonthlyAssessmentNew.setPersonnelMonthlyAssessmentIndicatorDetailList(new ArrayList<>());
            doImprove(personnelNonCadreMonthlyAssessmentNew);
            personnelNonCadreMonthlyAssessmentMapper.insertPersonnelNonCadreMonthlyAssessment(personnelNonCadreMonthlyAssessmentNew);
            result.add(personnelNonCadreMonthlyAssessmentNew);
        });
        return result;
    }
}
