package com.engine.salary.report.service.impl;

import com.alibaba.fastjson.JSON;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.cache.SalaryCacheKey;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.hrm.dto.EmployeeInfoExpandDTO;
import com.engine.salary.entity.hrm.dto.FieldSetting;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.report.SalaryStatisticsReportMapper;
import com.engine.salary.report.common.constant.SalaryConstant;
import com.engine.salary.report.common.constant.SalaryStatisticsDimensionConstant;
import com.engine.salary.report.entity.bo.SalaryStatisticsReportBO;
import com.engine.salary.report.entity.dto.SalaryStatisticsReportDataDTO;
import com.engine.salary.report.entity.param.*;
import com.engine.salary.report.entity.po.SalaryStatisticsDimensionPO;
import com.engine.salary.report.entity.po.SalaryStatisticsItemPO;
import com.engine.salary.report.entity.po.SalaryStatisticsReportPO;
import com.engine.salary.report.enums.SalaryStatisticsDimensionTypeEnum;
import com.engine.salary.report.service.SalaryStatisticsDimensionService;
import com.engine.salary.report.service.SalaryStatisticsItemService;
import com.engine.salary.report.service.SalaryStatisticsReportService;
import com.engine.salary.report.util.ReportTimeUtil;
import com.engine.salary.service.*;
import com.engine.salary.service.impl.*;
import com.engine.salary.util.*;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.wechat.util.Utils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 薪酬统计报表
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalaryStatisticsReportServiceImpl extends Service implements SalaryStatisticsReportService {

    private static final Logger log = LoggerFactory.getLogger(SalaryStatisticsReportServiceImpl.class);

    public static final String DM = "dimension";
    public static final String NOW_INFO = "nowInfoList";
    public static final String LAST_INFO = "lastInfoList";
    public static final String SAME_INFO = "sameInfoList";


    private SalaryStatisticsReportMapper getSalaryStatisticsReportMapper() {
        return MapperProxyFactory.getProxy(SalaryStatisticsReportMapper.class);
    }

    private SalaryStatisticsDimensionService getSalaryStatisticsDimensionService(User user) {
        return ServiceUtil.getService(SalaryStatisticsDimensionServiceImpl.class, user);
    }

    private SalaryStatisticsItemService getSalaryStatisticsItemService(User user) {
        return ServiceUtil.getService(SalaryStatisticsItemServiceImpl.class, user);
    }

    private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
        return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
    }

    private SalaryAcctResultService getSalaryAcctResultService(User user) {
        return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private SalarySobService getSalarySobService(User user) {
        return ServiceUtil.getService(SalarySobServiceImpl.class, user);
    }

    private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
        return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
    }

    private SalaryCacheService getSalaryCacheService(User user) {
        return ServiceUtil.getService(SalaryCacheServiceImpl.class, user);
    }

//    private ExtEmployeeService extEmployeeService;
//    
//    private HrmCommonEmployeeService hrmCommonEmployeeService;
//    
//    private HrmJobCallRemoteService hrmJobCallRemoteService;
//    
//    private RemoteUserInfoService remoteUserInfoService;
//    
//    private HrmCommonHrmStatusService hrmCommonHrmStatusService;
//    (name = "salaryStatReportLoggerTemplate")
//    private LoggerTemplate salaryStatReportLoggerTemplate;

    @Override
    public List<SalaryStatisticsReportPO> listAll() {
        return getSalaryStatisticsReportMapper().listAll();
    }

    @Override
    public List<SalaryStatisticsReportPO> list() {
        Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
        if (needAuth) {
            Boolean adminEnable = getTaxAgentService(user).isAdminEnable((long) user.getUID());
            if (!adminEnable) {
                return new ArrayList<>();
            }
        }

        return getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().build());
    }

    @Override
    public List<SalaryStatisticsReportPO> listByCreator(Long uid) {
        Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
        if (needAuth) {
            return getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().creator(uid).build());
        }

        return getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().build());
    }

    @Override
    public SalaryStatisticsReportPO getById(Long id) {
        return getSalaryStatisticsReportMapper().getById(id);
    }

    @Override
    public List<SalaryStatisticsReportPO> getByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().ids(ids).build());
    }

    /**
     * 根据名称模糊查询
     *
     * @param fieldName
     * @return
     */
    private List<SalaryStatisticsReportPO> listByName(String fieldName) {
        return getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().reportName(fieldName).build());
    }

    @Override
    public String save(SalaryStatisticsReportSaveParam saveParam) {
        SalaryStatisticsReportSaveParam.checkParam(saveParam);

        Date now = new Date();
        if (saveParam.getId() != null) {
            SalaryStatisticsReportPO po = this.getById(saveParam.getId());
            if (po == null) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(161845, "薪酬统计报表不存在"));
            }
            List<SalaryStatisticsReportPO> list = listByName(saveParam.getReportName());
            boolean nameExist = list.stream().anyMatch(e -> !Objects.equals(e.getId(), saveParam.getId()));
            if (nameExist) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98080, "名称不允许重复"));
            }
            SalaryStatisticsReportPO poNew = new SalaryStatisticsReportPO();
            BeanUtils.copyProperties(po, poNew);
            poNew.setReportName(saveParam.getReportName());
            poNew.setDimension(StringUtils.join(saveParam.getDimensionIds(), ","));
            this.getSalaryStatisticsReportMapper().updateIgnoreNull(poNew);

            // 记录日志
           LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
           loggerContext.setUser(user);
           loggerContext.setTargetId(String.valueOf(poNew.getId()));
           loggerContext.setTargetName(poNew.getReportName());
           loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
           loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "更新报表"));
           loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "更新报表"));
           loggerContext.setOldValues(po);
           loggerContext.setNewValues(poNew);
           SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
        } else {
            List<SalaryStatisticsReportPO> list = listByName(saveParam.getReportName());
            if (CollectionUtils.isNotEmpty(list)) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98080, "名称不允许重复"));
            }
            Long id = IdGenerator.generate();
            SalaryStatisticsReportPO poNew = SalaryStatisticsReportPO.builder().id(id).reportName(saveParam.getReportName()).dimension(StringUtils.join(saveParam.getDimensionIds(), ",")).createTime(now).creator((long) user.getUID()).updateTime(now).deleteType(0).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).salaryStartMonth(SalaryDateUtil.getFirstDayDateOfYear(new Date())).salaryEndMonth(SalaryDateUtil.getLastDayOfYear(new Date())).build();
            getSalaryStatisticsReportMapper().insertIgnoreNull(poNew);

            // 记录日志
           LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
           loggerContext.setUser(user);
           loggerContext.setTargetId(String.valueOf(poNew.getId()));
           loggerContext.setTargetName(poNew.getReportName());
           loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
           loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "新增报表"));
           loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "新增报表"));
           loggerContext.setNewValues(poNew);
           SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
        }
        return StringUtils.EMPTY;
    }

    @Override
    public String saveSearchCondition(SalaryStatisticsSearchConditionSaveParam param) {
        SalaryAssert.notNull(param.getId(), SalaryI18nUtil.getI18nLabel(152562, "报表id不能为空"));
        if (Objects.isNull(param.getSalaryStartMonth()) || Objects.isNull(param.getSalaryEndMonth())) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100294, "薪资所属月必传"));
        }
        if ((CollectionUtils.isNotEmpty(param.getTaxAgent()) && param.getTaxAgent().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getIncomeCategory()) && param.getIncomeCategory().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getSubCompany()) && param.getSubCompany().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getGrade()) && param.getGrade().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getPosition()) && param.getPosition().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getStatus()) && param.getStatus().size() > 10)
                || (CollectionUtils.isNotEmpty(param.getEmployee()) && param.getEmployee().size() > 10)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(182014, "统计数据范围条件数量过多"));
        }

        SalaryStatisticsReportPO po = getById(param.getId());
        SalaryStatisticsReportPO oldPO = new SalaryStatisticsReportPO();
        BeanUtils.copyProperties(po, oldPO);
        SalaryAssert.notNull(po, SalaryI18nUtil.getI18nLabel(152563, "报表不存在"));
        po.setSalaryStartMonth(param.getSalaryStartMonth());
        po.setSalaryEndMonth(param.getSalaryEndMonth());

        if (param.getTaxAgent() != null) {
            po.setTaxAgentSetting(JSON.toJSONString(param.getTaxAgent()));
        }
        if (param.getSalarySob() != null) {
            po.setSalarySobSetting(JSON.toJSONString(param.getSalarySob()));
        }
        if (param.getIncomeCategory() != null) {
            po.setIncomeCategorySetting(JSON.toJSONString(param.getIncomeCategory()));
        }
        if (param.getSubCompany() != null) {
            po.setSubCompanySetting(JSON.toJSONString(param.getSubCompany()));
        }
        if (param.getDepartment() != null) {
            po.setDepartSetting(JSON.toJSONString(param.getDepartment()));
        }
        if (param.getGrade() != null) {
            po.setGradeSetting(JSON.toJSONString(param.getGrade()));
        }

        if (param.getPosition() != null) {
            po.setPositionSetting(JSON.toJSONString(param.getPosition()));
        }

        if (param.getStatus() != null) {
            po.setStatusSetting(JSON.toJSONString(param.getStatus()));
        }

        if (param.getEmployee() != null) {
            po.setEmployeeSetting(JSON.toJSONString(param.getEmployee()));
        }

        if (param.getHiredate() != null) {
            po.setHiredateSetting(JSON.toJSONString(param.getHiredate()));
        }
        if (param.getLeavedate() != null) {
            po.setLeavedateSetting(JSON.toJSONString(param.getLeavedate()));
        }

        po.setTimeType(param.getTimeType());

        getSalaryStatisticsReportMapper().updateIgnoreNull(po);

        // 获取自定义统计项目
        List<SalaryStatisticsItemPO> salaryStatisticsItemList = getSalaryStatisticsItemService(user).listByStatisticsReportId(po.getId());

        salaryStatisticsItemList.forEach(e -> param.getItems().stream().filter(i -> i.getId().equals(e.getId())).findFirst().ifPresent(salaryStatisticsItem -> {
            e.setUnitType(salaryStatisticsItem.getUnitType());
            e.setIndexValue(salaryStatisticsItem.getIndexValue());
        }));
        getSalaryStatisticsItemService(user).saveOrUpdateBatch(salaryStatisticsItemList);

        //记录日志
       LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
       loggerContext.setUser(user);
       loggerContext.setTargetId(String.valueOf(po.getId()));
       loggerContext.setTargetName(po.getReportName());
       loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
       loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "更新报表"));
       loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "更新报表"));
       loggerContext.setOldValues(oldPO);
       loggerContext.setNewValues(po);
       SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
        return StringUtils.EMPTY;
    }

    @Override
    public Map<String, Object> delete(Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
        }
        int total = ids.size();
        List<SalaryStatisticsReportPO> list = getSalaryStatisticsReportMapper().listSome(SalaryStatisticsReportPO.builder().ids(ids).build());

        int success = list.size();
        if (success > 0) {
            List<Long> deleteIds = list.stream().map(SalaryStatisticsReportPO::getId).collect(Collectors.toList());
            //删除报表
            getSalaryStatisticsReportMapper().deleteByIds(deleteIds);
            //删除薪资项
            getSalaryStatisticsItemService(user).deleteByReportIds(deleteIds);
           list.forEach(e -> {
               // 记录日志
               LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
               loggerContext.setUser(user);
               loggerContext.setTargetId(String.valueOf(e.getId()));
               loggerContext.setTargetName(e.getReportName());
               loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
               loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "删除报表"));
               loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "删除报表") + e.getReportName());
               SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
           });
        }

        Map<String, Object> resultMap = new HashMap<>(2);
        String resultMsg = SalaryI18nUtil.getI18nLabel(94620, "操作成功");
        String resultType = "success";
        // 单个设为定薪提示
        if (total > 1) {
            resultMsg = SalaryI18nUtil.getI18nLabel(134807, "成功条数") + ": " + (success) + "; " + SalaryI18nUtil.getI18nLabel(134808, "失败条数") + ": " + (total - success);
            if ((total - success) > 0) {
                resultType = "info";
            }
        } else if (total == 1 && success < 1) {
            resultType = "info";
        }
        resultMap.put("type", resultType);
        resultMap.put("msg", resultMsg);
        return resultMap;
    }

    @Override
    public void duplicate(Long id) {
        long uid = user.getUID();
        Date now = new Date();

        SalaryStatisticsReportPO po = getById(id);
        SalaryAssert.notNull(po, SalaryI18nUtil.getI18nLabel(152563, "报表不存在"));

        po.setId(IdGenerator.generate());
        po.setCreator(uid);
        po.setCreateTime(now);
        po.setUpdateTime(now);
        po.setReportName(po.getReportName() + "_copy");

        getSalaryStatisticsReportMapper().insertIgnoreNull(po);

        List<SalaryStatisticsItemPO> itemPOS = getSalaryStatisticsItemService(user).listByStatisticsReportId(id);
        List<SalaryStatisticsItemPO> itemList = itemPOS.stream().map(item -> {
            item.setId(IdGenerator.generate());
            item.setStatReportId(po.getId());
            item.setCreator(uid);
            item.setCreateTime(now);
            item.setUpdateTime(now);
            return item;
        }).collect(Collectors.toList());
        getSalaryStatisticsItemService(user).saveOrUpdateBatch(itemList);

        // 记录日志
        LoggerContext<SalaryStatisticsReportPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(po.getId()));
        loggerContext.setTargetName(po.getReportName());
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel( 0, "新增报表"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel( 0, "新增报表"));
        loggerContext.setNewValues(po);
        SalaryElogConfig.salaryStatReportLoggerTemplate.write(loggerContext);
    }

    @Override
    public PageInfo<Map<String, Object>> buildReportRecords(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataQueryParam param, List<SalaryStatisticsItemPO> salaryStatisticsItemList) {
        Map<String, Boolean> checkMap = SalaryStatisticsReportBO.checkLoad(salaryStatisticsItemList);
        // 如果一个都没有，直接返回
//        if (!checkMap.get("isNow")) {
//            return new PageInfo<Map<String, Object>>();
//        }


        // 获取本期报表分权后的核算人员
        List<SalaryAcctEmployeePO> list = getSalaryAcctEmployeeService(user).listBySalaryStatisticsReportParam(param);
        SalaryStatisticsReportDataQueryParam lastParam = SalaryStatisticsReportBO.lastParamConvert(param, dimension);
        // 获取上期报表分权后的核算人员
        List<SalaryAcctEmployeePO> lastList = checkMap.get("isLast") ? getSalaryAcctEmployeeService(user).listBySalaryStatisticsReportParam(lastParam) : Lists.newArrayList();
        SalaryStatisticsReportDataQueryParam sameParam = SalaryStatisticsReportBO.sameParamConvert(param);
        // 获取去年同期报表分权后的核算人员
        List<SalaryAcctEmployeePO> sameList = checkMap.get("isSame") ? getSalaryAcctEmployeeService(user).listBySalaryStatisticsReportParam(sameParam) : Lists.newArrayList();

        SalaryStatisticsReportDataDTO salaryStatisticsReportData = SalaryStatisticsReportDataDTO.builder().list(list).lastList(lastList).sameList(sameList).salaryStatisticsItemList(salaryStatisticsItemList).employeeId((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build();

        List<SalaryAcctEmployeePO> allList = Lists.newArrayList();
        allList.addAll(list);
        allList.addAll(lastList);
        allList.addAll(sameList);
        List<Long> salaryAcctEmployeeIds = allList.stream().map(SalaryAcctEmployeePO::getId).collect(Collectors.toList());
        List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
//        Map<Long, List<SalaryAcctResultPO>> salaryAcctResultValueMap = SalaryEntityUtil.convert2Map();
        Map<Long, List<SalaryAcctResultPO>> salaryAcctEmpResultMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId);
        Map<Long, Map<String, String>> map = new HashMap<>();
        salaryAcctEmpResultMap.forEach((k, v) -> {
            Map<String, String> collect = v.stream().collect(Collectors.toMap(p -> Util.null2String(p.getSalaryItemId()), p -> Util.null2String(p.getResultValue()), (key1, key2) -> key2));
            map.put(k, collect);
        });

        // 根据统计维度进行计算
        return calculateReportRecordsByDimension(dimension, param, salaryStatisticsReportData, map);
    }

    @Override
    public PageInfo<Map<String, Object>> buildDataPerspectiveRecords(SalaryStatisticsDataPerspectiveQueryParam param, SalaryStatisticsReportPO reportPO, SalaryStatisticsDimensionPO dimension, List<SalaryStatisticsItemPO> salaryStatisticsItemPOS) {
        // 获取报表统计薪资项目
        List<Long> salaryItemIds = salaryStatisticsItemPOS.stream().filter(item -> StringUtils.isNotBlank(item.getItemValue())).map(p -> p.getItemValue().split(",")).flatMap(Arrays::stream).map(Long::valueOf).collect(Collectors.toList());
        // 参数转换
        param.setSalaryStartMonth(SalaryDateUtil.getFormatYearMonth(reportPO.getSalaryStartMonth()));
        param.setSalaryEndMonth(SalaryDateUtil.getFormatYearMonth(reportPO.getSalaryEndMonth()));
        String key = "id";
        if (reportPO.getTaxAgentSetting() != null) {
            param.setTaxAgent(((List<Map>) JSON.parseArray(reportPO.getTaxAgentSetting(), Map.class)).stream().map(m -> Long.valueOf(m.get(key).toString())).collect(Collectors.toList()));
        }
        if (reportPO.getSubCompanySetting() != null) {
            param.setSubCompany(((List<Map>) JSON.parseArray(reportPO.getSubCompanySetting(), Map.class)).stream().map(m -> Long.valueOf(m.get(key).toString())).collect(Collectors.toList()));
        }
        if (reportPO.getDepartSetting() != null) {
            param.setDepart(((List<Map>) JSON.parseArray(reportPO.getDepartSetting(), Map.class)).stream().map(m -> Long.valueOf(m.get(key).toString())).collect(Collectors.toList()));
        }
        if (reportPO.getEmployeeSetting() != null) {
            param.setEmployee(((List<Map>) JSON.parseArray(reportPO.getEmployeeSetting(), Map.class)).stream().map(m -> Long.valueOf(m.get(key).toString())).collect(Collectors.toList()));
        }
        if (reportPO.getHiredateSetting() != null) {
            param.setHiredate(JSON.parseArray(reportPO.getHiredateSetting(), Date.class));
        }
        SalaryStatisticsReportDataQueryParam queryParam = new SalaryStatisticsReportDataQueryParam();
        com.mzlion.core.utils.BeanUtils.copyProperties(param, queryParam);
        // 获取本期报表分权后的核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeeList = getSalaryAcctEmployeeService(user).listBySalaryStatisticsReportParam(queryParam);

        // 设置dimensionValue为维度值
        SalaryStatisticsReportDataDTO salaryStatisticsReportData = SalaryStatisticsReportDataDTO.builder().list(salaryAcctEmployeeList).lastList(Collections.emptyList()).sameList(Collections.emptyList()).salaryStatisticsItemList(salaryStatisticsItemPOS).employeeId((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).dimensionValue(param.getDimensionValue()).build();

        Map<Long, Map<String, String>> resultMap = new HashMap<>();
        List<Long> salaryAcctEmployeeIds = salaryAcctEmployeeList.stream().map(SalaryAcctEmployeePO::getId).collect(Collectors.toList());
        if (NumberUtils.isCreatable(dimension.getDimCode())) {
            List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listByAcctEmployeeIdsAndSalaryItemIds(salaryAcctEmployeeIds, Collections.singleton(Long.valueOf(dimension.getDimCode())));
            List<Long> finalSalaryAcctEmpIds = getSalaryAcctResultService(user).listAcctEmpIdByAcctEmpId(salaryAcctEmployeeIds);
            Map<Long, List<SalaryAcctResultPO>> salaryAcctEmpResultMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId);
            salaryAcctEmpResultMap.forEach((k, v) -> {
                Map<String, String> collect = v.stream().collect(Collectors.toMap(p -> Util.null2String(p.getSalaryItemId()), SalaryAcctResultPO::getResultValue, (key1, key2) -> key2));
                resultMap.put(k, collect);
            });
            salaryAcctEmployeeIds.stream().forEach(id -> {
                if (!resultMap.containsKey(id) && finalSalaryAcctEmpIds.contains(id))
                    resultMap.put(id, Collections.emptyMap());
            });
        }


        // 获取根据维度值过滤出的本次核算人员信息
        calculateReportRecordsByDimension(dimension, SalaryStatisticsReportDataQueryParam.builder().build(), salaryStatisticsReportData, resultMap);
        List<SalaryAcctEmployeePO> listByDimensionValue = salaryStatisticsReportData.getListByDimensionValue();
        if (CollectionUtils.isEmpty(listByDimensionValue)) {
            throw new SalaryRunTimeException("该维度值中无数据！");
        }
        // 同一个人放在一起
        listByDimensionValue = listByDimensionValue.stream().sorted(Comparator.comparing(SalaryAcctEmployeePO::getEmployeeId)).collect(Collectors.toList());
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOList = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), listByDimensionValue);

        // 获取此分页的核算人员
        List<Long> pageSalaryAcctEmployeeIds = salaryAcctEmployeePOList.stream().map(SalaryAcctEmployeePO::getId).collect(Collectors.toList());
        // 获取核算结果
        List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listByAcctEmployeeIdsAndSalaryItemIds(pageSalaryAcctEmployeeIds, salaryItemIds);
        // 封装核算结果
        Map<Long, List<SalaryAcctResultPO>> salaryAcctEmpResultMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId);
        Map<Long, Map<String, String>> map = new HashMap<>();
        salaryAcctEmpResultMap.forEach((k, v) -> {
            Map<String, String> collect = v.stream().collect(Collectors.toMap(p -> Util.null2String(p.getSalaryItemId()), p -> Util.null2String(p.getResultValue()), (key1, key2) -> key2));
            map.put(k, collect);
        });

        // 构建核算结果数据
        List<Map<String, Object>> records = buildResultRecords(salaryAcctEmployeePOList, map);
        PageInfo<Map<String, Object>> pageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize());
        pageInfo.setTotal(listByDimensionValue.size());
        pageInfo.setList(records);
        return pageInfo;
    }

    @Override
    public void removeReportCache() {
        //获取所有缓存报表的id
        String salaryReportIds = Utils.null2String(getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_IDS));
        if (StringUtils.isNotBlank(salaryReportIds)) {
            Arrays.asList(salaryReportIds.split(",")).forEach(id -> {
                if (StringUtils.isNotBlank(id)) {
                    //报表下条件id
                    String salaryReportConditions = getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_CONDITIONS + id);
                    if (StringUtils.isNotBlank(salaryReportConditions)) {
                        Arrays.asList(salaryReportConditions.split(",")).forEach(paramMd5 -> {
                            if (StringUtils.isNotBlank(paramMd5)) {
                                //条件对应的结果
                                getSalaryCacheService(user).remove(SalaryCacheKey.SALARY_REPORT_DATA + id + "_" + paramMd5);
                            }
                        });
                        getSalaryCacheService(user).remove(SalaryCacheKey.SALARY_REPORT_CONDITIONS + id);
                    }
                }
            });
            getSalaryCacheService(user).remove(SalaryCacheKey.SALARY_REPORT_IDS);
        }

    }

    public List getReportCache() {
        List report = new ArrayList<>();

        //获取所有缓存报表的id
        String salaryReportIds = Utils.null2String(getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_IDS));
        if (StringUtils.isNotBlank(salaryReportIds)) {
            Arrays.asList(salaryReportIds.split(",")).forEach(id -> {
                if (StringUtils.isNotBlank(id)) {
                    //报表下条件id
                    String salaryReportConditions = getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_CONDITIONS + id);
                    List c = new ArrayList<>();
                    if (StringUtils.isNotBlank(salaryReportConditions)) {
                        Arrays.asList(salaryReportConditions.split(",")).forEach(paramMd5 -> {
                            if (StringUtils.isNotBlank(paramMd5)) {
                                Map<String, Object> data = getSalaryCacheService(user).get(SalaryCacheKey.SALARY_REPORT_DATA + paramMd5);
                                Map kv = new HashMap<>();
                                kv.put(paramMd5, data);
                                c.add(kv);
                            }
                        });
                        report.add(c);
                    }
                }
            });
        }

        return report;

    }


    /**
     * 获取根据维度值过滤出的本次核算人员信息
     *
     * @param listByDimensionValue 根据维度筛选后的薪资核算人员
     * @param map                  薪资核算结果
     */
    private List<Map<String, Object>> buildResultRecords(List<SalaryAcctEmployeePO> listByDimensionValue, Map<Long, Map<String, String>> map) {
        // 获取人员信息
        Set<Long> employeeIds = listByDimensionValue.stream().map(SalaryAcctEmployeePO::getEmployeeId).collect(Collectors.toSet());
        List<DataCollectionEmployee> employeeList = getSalaryEmployeeService(user).listByIds(employeeIds.stream().collect(Collectors.toList()));
        Map<Long, DataCollectionEmployee> employeeMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId);

        List<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAll();
        Map<Long, String> taxAgentMap = SalaryEntityUtil.convert2Map(taxAgentList, TaxAgentPO::getId, TaxAgentPO::getName);

        List<SalarySobPO> salarySobPOS = getSalarySobService(user).listAll();
        Map<Long, String> SalarySobMap = SalaryEntityUtil.convert2Map(salarySobPOS, SalarySobPO::getId, SalarySobPO::getName);

        List<SalaryAcctRecordPO> salaryAcctRecordPOS = getSalaryAcctRecordService(user).listAll();
        Map<Long, Integer> salaryAcctRecordMap = SalaryEntityUtil.convert2Map(salaryAcctRecordPOS, SalaryAcctRecordPO::getId, SalaryAcctRecordPO::getAcctTimes);
        List<Map<String, Object>> resultList = Lists.newArrayList();
        Map<String, Object> resultMap;
        for (SalaryAcctEmployeePO se : listByDimensionValue) {
            resultMap = Maps.newHashMap();
            Map<String, String> resultValueMap = Optional.ofNullable(map.get(se.getId())).orElse(Maps.newHashMap());
            Map<String, Object> finalMap = resultMap;
            resultValueMap.forEach((k, v) -> {
                finalMap.put(k + SalaryConstant.DYNAMIC_SUFFIX, v);
            });
            DataCollectionEmployee emp = employeeMap.get(se.getEmployeeId());
            resultMap.put("id", se.getId().toString());
            resultMap.put("userName", emp == null ? "" : emp.getUsername());
            resultMap.put("departmentName", emp == null ? "" : emp.getDepartmentName());
            resultMap.put("salaryMonth", SalaryDateUtil.getFormatYearMonth(se.getSalaryMonth()));
            resultMap.put("taxAgent", taxAgentMap.get(se.getTaxAgentId()));
            resultMap.put("salarySob", SalarySobMap.get(se.getSalarySobId()));
            resultMap.put("acctTimes", salaryAcctRecordMap.get(se.getSalaryAcctRecordId()));
            resultList.add(resultMap);
        }
        return resultList;
    }

    private PageInfo<Map<String, Object>> calculateReportRecordsByDimension(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataQueryParam param, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        // 定性
        if (SalaryStatisticsDimensionTypeEnum.QUALITATIVE.getValue().equals(dimension.getDimType())) {
            switch (dimension.getDimCode()) {
                case SalaryStatisticsDimensionConstant.DM_SALARY_MONTH:
                    return buildSalaryMonthRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_TAX_AGENT:
                    return buildTaxAgentRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_INCOME_CATEGORY:
//                    return buildIncomeCategoryRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_SUB_COMPANY:
                    return buildSubComRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_DEPARTMENT:
                    return buildDepartRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_POSITION:
//                    return buildPositionRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_GRADE:
//                    return buildGradeRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_HRM_STATUS:
//                    return buildStatusRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_EMPLOYEE_TYPE:
//                    return buildTypeRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_EMPLOYEE:
                    return buildEmployeeRecords(param, data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_QUARTER:
                    return buildQuarterRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_HALF_YEAR:
                    return buildHalfYearRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_YEAR:
                    return buildYearRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_SEX:
//                    return buildSexRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_JOB_CALL:
//                    return buildJobCallRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_SUPERIOR:
//                    return buildSuperiorRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_MARITAL_STATUS:
//                    return buildMaritalStatusRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_EDUCATION:
//                    return buildEducationRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_DEGREE:
//                    return buildDegreeRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_NATION:
//                    return buildNationRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_HOUSEHOLD_TYPE:
//                    return buildHouseholdTypeRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_POLITICS_STATUS:
//                    return buildPoliticsStatusRecords(data, salaryAcctResultValueMap);
//                case SalaryStatisticsDimensionConstant.DM_AGE:
//                    return buildAgeRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_WORK_YEAR:
                    return buildWorkYearRecords(data, salaryAcctResultValueMap);
                case SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR:
                    return buildCompanyYearRecords(data, salaryAcctResultValueMap);
                default:
                    return buildSalaryItemRecords(dimension, data, salaryAcctResultValueMap);
            }
            // 定量-组距式分组
        } else if (SalaryStatisticsDimensionTypeEnum.RATION_GROUP_SPACING.getValue().equals(dimension.getDimType())) {
            return buildRationGroupSpacing4Records(dimension, data, salaryAcctResultValueMap);
            // 定量-单项式分组
        } else if (SalaryStatisticsDimensionTypeEnum.RATION_GROUP_INDIVIDUAL.getValue().equals(dimension.getDimType())) {
            return buildRationGroupIndividual4Records(dimension, data, salaryAcctResultValueMap);
        }
        return new PageInfo<>();
    }

    private PageInfo<Map<String, Object>> buildSalaryMonthRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();
        Map<Date, List<SalaryAcctEmployeePO>> listMap = data.getList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getSalaryMonth));
        Map<Date, List<SalaryAcctEmployeePO>> lastListMap = data.getLastList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getSalaryMonth));
        Map<Date, List<SalaryAcctEmployeePO>> sameListMap = data.getSameList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getSalaryMonth));
        List<Date> salaryMonthList = listMap.keySet().stream().sorted().collect(Collectors.toList());
        String dimensionValue = data.getDimensionValue();
        salaryMonthList.forEach(k -> {
            if (dimensionValue == null) {
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, SalaryDateUtil.getFormatYearMonth(k));
                temp.putAll(SalaryStatisticsReportBO.calculateItem(listMap.get(k), lastListMap.get(ReportTimeUtil.getLastYearMonth(k)), sameListMap.get(ReportTimeUtil.getSameYearMonth(k)), salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, SalaryDateUtil.getFormatYearMonth(k))) {
                data.setListByDimensionValue(listMap.get(k));
            }
        });
        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildTaxAgentRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        Map<Long, List<SalaryAcctEmployeePO>> listMap = data.getList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getTaxAgentId));
        Map<Long, List<SalaryAcctEmployeePO>> lastListMap = data.getLastList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getTaxAgentId));
        Map<Long, List<SalaryAcctEmployeePO>> sameListMap = data.getSameList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getTaxAgentId));

        List<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAll();
        Map<Long, String> taxAgentMap = SalaryEntityUtil.convert2Map(taxAgentList, TaxAgentPO::getId, TaxAgentPO::getName);
        String dimensionValue = data.getDimensionValue();
        listMap.forEach((k, v) -> {
            if (dimensionValue == null) {
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, taxAgentMap.get(k));
                temp.putAll(SalaryStatisticsReportBO.calculateItem(v, lastListMap.get(k), sameListMap.get(k), salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, taxAgentMap.get(k))) {
                data.setListByDimensionValue(v);
            }
        });

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildIncomeCategoryRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        Map<String, List<SalaryAcctEmployeePO>> listMap = data.getList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getIncomeCategory));
//        Map<String, List<SalaryAcctEmployeePO>> lastListMap = data.getLastList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getIncomeCategory));
//        Map<String, List<SalaryAcctEmployeePO>> sameListMap = data.getSameList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getIncomeCategory));
//
//        List<String> incomeCategoryList = listMap.keySet().stream().sorted().collect(Collectors.toList());
//        incomeCategoryList.forEach(k -> {
//            IncomeCategoryEnum incomeCategory = IncomeCategoryEnum.parseByValue(Integer.parseInt(k));
//            if (Objects.nonNull(incomeCategory)) {
//                Map<String, Object> temp = new HashMap<>();
//                temp.put(DM, SalaryI18nUtil.getI18nLabel(incomeCategory.getLabelId(), incomeCategory.getDefaultLabel()));
//                temp.putAll(SalaryStatisticsReportBO.calculateItem(listMap.get(k), lastListMap.get(k), sameListMap.get(k), salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//                records.add(temp);
//            }
//        });
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildSubComRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());


        List<DataCollectionEmployee> comInfos = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
        Map<Long, DataCollectionEmployee> comInfoMap = SalaryEntityUtil.convert2Map(comInfos, DataCollectionEmployee::getEmployeeId);
        List<DataCollectionEmployee> lastComInfos = getSalaryEmployeeService(user).getEmployeeByIdsAll(lastEmployeeIds);
        Map<Long, DataCollectionEmployee> lastComInfoMap = SalaryEntityUtil.convert2Map(lastComInfos, DataCollectionEmployee::getEmployeeId);
        List<DataCollectionEmployee> sameComInfos = getSalaryEmployeeService(user).getEmployeeByIdsAll(sameEmployeeIds);
        Map<Long, DataCollectionEmployee> sameComInfoMap = SalaryEntityUtil.convert2Map(sameComInfos, DataCollectionEmployee::getEmployeeId);

        Set<Long> subComIds = new HashSet<>();
        Map<Long, Long> empIdSubComMap = new HashMap<>();
        Map<Long, String> subComIdNameMap = new HashMap<>();
        Map<Long, Long> lastEmpIdSubComMap = new HashMap<>();
        Map<Long, Long> sameEmpIdSubComMap = new HashMap<>();
        comInfoMap.forEach((k, v) -> {
            subComIdNameMap.put(v.getSubcompanyid(), v.getSubcompanyName());
            empIdSubComMap.put(k, v.getSubcompanyid());
            subComIds.add(v.getSubcompanyid());
        });
        lastComInfoMap.forEach((k, v) -> {
            lastEmpIdSubComMap.put(k, v.getSubcompanyid());
        });
        sameComInfoMap.forEach((k, v) -> {
            sameEmpIdSubComMap.put(k, v.getSubcompanyid());
        });

        String dimensionValue = data.getDimensionValue();
        subComIds.forEach(subComId -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> subComEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdSubComMap.get(po.getEmployeeId()), subComId)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastSubComEmployeePOS = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdSubComMap.get(po.getEmployeeId()), subComId)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameSubComEmployeePOS = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdSubComMap.get(po.getEmployeeId()), subComId)).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, subComIdNameMap.get(subComId));
                temp.putAll(SalaryStatisticsReportBO.calculateItem(subComEmployeePOS, lastSubComEmployeePOS, sameSubComEmployeePOS, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, subComIdNameMap.get(subComId))) {
                List<SalaryAcctEmployeePO> subComEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdSubComMap.get(po.getEmployeeId()), subComId)).collect(Collectors.toList());
                data.setListByDimensionValue(subComEmployeePOS);
            }
        });

        if (dimensionValue == null) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdSubComMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdSubComMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdSubComMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noGroupingList)) {
                Map<String, Object> noGrouping = new HashMap<>();
                noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
                noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(noGrouping);
            }
        } else if (StringUtils.equals(dimensionValue, "无分组")) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdSubComMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            data.setListByDimensionValue(noGroupingList);
        }

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildDepartRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<DataCollectionEmployee> simpleEmployeeList = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
        List<DataCollectionEmployee> lastSimpleEmployeeList = getSalaryEmployeeService(user).getEmployeeByIdsAll(lastEmployeeIds);
        List<DataCollectionEmployee> sameSimpleEmployeeList = getSalaryEmployeeService(user).getEmployeeByIdsAll(sameEmployeeIds);

        Set<Long> departIds = new HashSet<>();
        Map<Long, Long> empIdDepartIdMap = new HashMap<>();
        Map<Long, Long> lastEmpIdDepartIdMap = new HashMap<>();
        Map<Long, Long> sameEmpIdDepartIdMap = new HashMap<>();
        Map<Long, String> departIdNameMap = new HashMap<>();
        simpleEmployeeList.forEach(employee -> {
            if (employee.getDepartmentName() != null && employee.getDepartmentId() != null) {
                departIdNameMap.put(employee.getDepartmentId(), employee.getDepartmentName());
                departIds.add(employee.getDepartmentId());
                empIdDepartIdMap.put(employee.getEmployeeId(), employee.getDepartmentId());
            }
        });
        lastSimpleEmployeeList.forEach(employee -> {
            if (employee.getDepartmentName() != null && employee.getDepartmentId() != null) {
                lastEmpIdDepartIdMap.put(employee.getEmployeeId(), employee.getDepartmentId());
            }
        });
        sameSimpleEmployeeList.forEach(employee -> {
            if (employee.getDepartmentName() != null && employee.getDepartmentId() != null) {
                sameEmpIdDepartIdMap.put(employee.getEmployeeId(), employee.getDepartmentId());
            }
        });

        String dimensionValue = data.getDimensionValue();
        departIds.forEach(departId -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> departEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdDepartIdMap.get(po.getEmployeeId()), departId)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastDepartEmployeePOS = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdDepartIdMap.get(po.getEmployeeId()), departId)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameDepartEmployeePOS = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdDepartIdMap.get(po.getEmployeeId()), departId)).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, departIdNameMap.get(departId));
                temp.putAll(SalaryStatisticsReportBO.calculateItem(departEmployeePOS, lastDepartEmployeePOS, sameDepartEmployeePOS, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, departIdNameMap.get(departId))) {
                List<SalaryAcctEmployeePO> departEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdDepartIdMap.get(po.getEmployeeId()), departId)).collect(Collectors.toList());
                data.setListByDimensionValue(departEmployeePOS);
            }
        });

        if (dimensionValue == null) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdDepartIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdDepartIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> lastEmpIdDepartIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noGroupingList)) {
                Map<String, Object> noGrouping = new HashMap<>();
                noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
                noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(noGrouping);
            }
        } else if (StringUtils.equals(dimensionValue, "无分组")) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdDepartIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            data.setListByDimensionValue(noGroupingList);
        }

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildPositionRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(sameEmployeeIds, data.getTenantKey());
//
//        Set<Long> positionIds = new HashSet<>();
//        Map<Long, Long> empIdPositionIdMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdPositionIdMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdPositionIdMap = new HashMap<>();
//        Map<Long, String> positionIdNameMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (employee.getPosition() != null && employee.getPosition().getId() != null) {
//                positionIdNameMap.put(employee.getPosition().getId(), employee.getPosition().getName());
//                positionIds.add(employee.getPosition().getId());
//                empIdPositionIdMap.put(employee.getId(), employee.getPosition().getId());
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (employee.getPosition() != null && employee.getPosition().getId() != null) {
//                lastEmpIdPositionIdMap.put(employee.getId(), employee.getPosition().getId());
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (employee.getPosition() != null && employee.getPosition().getId() != null) {
//                sameEmpIdPositionIdMap.put(employee.getId(), employee.getPosition().getId());
//            }
//        });
//
//        positionIds.forEach(positionId -> {
//            List<SalaryAcctEmployeePO> positionEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdPositionIdMap.get(po.getEmployeeId()), positionId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastPositionEmployeePOS = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdPositionIdMap.get(po.getEmployeeId()), positionId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> samePositionEmployeePOS = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdPositionIdMap.get(po.getEmployeeId()), positionId)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, positionIdNameMap.get(positionId));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(positionEmployeePOS, lastPositionEmployeePOS, samePositionEmployeePOS, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdPositionIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdPositionIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdPositionIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildGradeRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(sameEmployeeIds, data.getTenantKey());
//
//        Set<Long> gradeIds = new HashSet<>();
//        Map<Long, Long> empIdGradeIdMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdGradeIdMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdGradeIdMap = new HashMap<>();
//        Map<Long, String> gradeIdNameMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (employee.getGrade() != null && employee.getGrade().getId() != null) {
//                gradeIdNameMap.put(employee.getGrade().getId(), employee.getGrade().getName());
//                gradeIds.add(employee.getGrade().getId());
//                empIdGradeIdMap.put(employee.getId(), employee.getGrade().getId());
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (employee.getGrade() != null && employee.getGrade().getId() != null) {
//                lastEmpIdGradeIdMap.put(employee.getId(), employee.getGrade().getId());
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (employee.getGrade() != null && employee.getGrade().getId() != null) {
//                sameEmpIdGradeIdMap.put(employee.getId(), employee.getGrade().getId());
//            }
//        });
//
//        gradeIds.forEach(gradeId -> {
//            List<SalaryAcctEmployeePO> gradeEmployeePOS = data.getList().stream().filter(po -> Objects.equals(empIdGradeIdMap.get(po.getEmployeeId()), gradeId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastGradeEmployeePos = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdGradeIdMap.get(po.getEmployeeId()), gradeId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameGradeEmployeePos = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdGradeIdMap.get(po.getEmployeeId()), gradeId)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, gradeIdNameMap.get(gradeId));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(gradeEmployeePOS, lastGradeEmployeePos, sameGradeEmployeePos, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdGradeIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdGradeIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdGradeIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildStatusRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(sameEmployeeIds, data.getTenantKey());
//        Map<Long, String> statusIdNameMap = hrmCommonHrmStatusService.list(data.getTenantKey()).stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(HrmStatus::getCodeId))), ArrayList::new)).stream().collect(Collectors.toMap(HrmStatus::getCodeId, HrmStatus::getName));
//
//        Set<Long> statusIds = new HashSet<>();
//        Map<Long, Long> empIdStatusIdMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdStatusIdMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdStatusIdMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (StringUtils.isNotBlank(employee.getPersonnelStatus())) {
//                statusIds.add(Long.valueOf(employee.getPersonnelStatus()));
//                empIdStatusIdMap.put(employee.getId(), Long.valueOf(employee.getPersonnelStatus()));
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (StringUtils.isNotBlank(employee.getPersonnelStatus())) {
//                lastEmpIdStatusIdMap.put(employee.getId(), Long.valueOf(employee.getPersonnelStatus()));
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (StringUtils.isNotBlank(employee.getPersonnelStatus())) {
//                sameEmpIdStatusIdMap.put(employee.getId(), Long.valueOf(employee.getPersonnelStatus()));
//            }
//        });
//
//        statusIds.forEach(statusId -> {
//            List<SalaryAcctEmployeePO> statusEmployeePOS = data.getList().stream().filter(po -> com.google.common.base.Objects.equal(empIdStatusIdMap.get(po.getEmployeeId()), statusId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastStatusEmployeePOS = data.getLastList().stream().filter(po -> com.google.common.base.Objects.equal(lastEmpIdStatusIdMap.get(po.getEmployeeId()), statusId)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameStatusEmployeePOS = data.getSameList().stream().filter(po -> com.google.common.base.Objects.equal(sameEmpIdStatusIdMap.get(po.getEmployeeId()), statusId)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, statusIdNameMap.get(statusId));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(statusEmployeePOS, lastStatusEmployeePOS, sameStatusEmployeePOS, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdStatusIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdStatusIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdStatusIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildTypeRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        Map<Integer, List<SalaryAcctEmployeePO>> typeEmployeeListMap = data.getList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeType));
//        Map<Integer, List<SalaryAcctEmployeePO>> lastTypeEmployeeListMap = data.getLastList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeType));
//        Map<Integer, List<SalaryAcctEmployeePO>> sameTypeEmployeeListMap = data.getSameList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeType));
//
//        typeEmployeeListMap.forEach((k, v) -> {
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, Objects.equals(k, EmployeeTypeEnum.ORGANIZATION.getValue()) ? SalaryI18nUtil.getI18nLabel( 110538, "内部人员") : SalaryI18nUtil.getI18nLabel( 119127, "非系统人员"));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(v, lastTypeEmployeeListMap.get(k), sameTypeEmployeeListMap.get(k), salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildEmployeeRecords(SalaryStatisticsReportDataQueryParam param, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());

//        List<Long> pageEmployeeIds = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), employeeIds);
//        List<SalaryAcctEmployeePO> accountDetailPOList = data.getList().stream().filter(po -> pageEmployeeIds.contains(po.getEmployeeId())).collect(Collectors.toList());
        List<Map<String, Object>> records = new ArrayList<>();
        List<SalaryAcctEmployeePO> accountDetailPOList = data.getList();
        Map<Long, List<SalaryAcctEmployeePO>> employeeListMap = accountDetailPOList.stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeId));
        Map<Long, List<SalaryAcctEmployeePO>> lastEmployeeListMap = data.getLastList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeId));
        Map<Long, List<SalaryAcctEmployeePO>> sameEmployeeListMap = data.getSameList().stream().collect(Collectors.groupingBy(SalaryAcctEmployeePO::getEmployeeId));

        List<Long> empIds = accountDetailPOList.stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        Map<Long, DataCollectionEmployee> employeeByIdMap = getSalaryEmployeeService(user).getEmployeeByIdsAll(empIds).stream().collect(Collectors.toMap(DataCollectionEmployee::getEmployeeId, o -> o));

        //人员维度扩展属性
        EmployeeInfoExpandDTO employeeInfoExpandDTO = getSalaryStatisticsDimensionService(user).getExpandFieldSettings("dim_employee");
        List<FieldSetting> fieldSettings = Optional.ofNullable(Optional.ofNullable(employeeInfoExpandDTO).orElse(new EmployeeInfoExpandDTO()).getFieldSettings()).orElse(new ArrayList<>());
        Map<Long, Map<String, String>> expandEmployeeMap = getSalaryEmployeeService(user).expandEmployeeMap(empIds, employeeInfoExpandDTO);

        log.info("扩展属性" + expandEmployeeMap);

//        List<ExtEmployeePO> extEmployees = extEmployeeService.listByIdsWithDeleted(accountDetailPOList.stream().filter(e -> EmployeeTypeEnum.EXT_EMPLOYEE.getValue().equals(e.getEmployeeType())).map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList()), data.getTenantKey());
//        Map<Long, String> employeeExtByIdMap = SalaryEntityUtil.convert2Map(extEmployees, ExtEmployeePO::getId, ExtEmployeePO::getUsername);

        String dimensionValue = data.getDimensionValue();
        employeeListMap.forEach((k, v) -> {
            if (dimensionValue == null) {
                Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, Objects.nonNull(employeeByIdMap.get(k)) ? employeeByIdMap.get(k) : employeeExtByIdMap.get(k));
                temp.put(DM, employeeByIdMap.get(k).getUsername());
                fieldSettings.forEach(fieldSetting -> {
                    temp.put(fieldSetting.getField(), expandEmployeeMap.getOrDefault(k, new HashMap<>()).get(fieldSetting.getField()));
                });
                temp.putAll(SalaryStatisticsReportBO.calculateItem(v, lastEmployeeListMap.get(k), sameEmployeeListMap.get(k), salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, employeeByIdMap.get(k).getUsername())) {
                data.setListByDimensionValue(v);
            }
        });

        PageInfo<Map<String, Object>> result = new PageInfo<>();
        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildQuarterRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        Set<String> quarterSet = Sets.newHashSet();
        data.getList().forEach(sa -> quarterSet.add(ReportTimeUtil.getQuarter(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()))));
        List<String> quarters = quarterSet.stream().sorted().collect(Collectors.toList());
        Collections.reverse(quarters);

        String dimensionValue = data.getDimensionValue();
        quarters.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> listYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getQuarter(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastListYear = data.getLastList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getQuarter(ReportTimeUtil.getPlusYearMonth(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()), 3)))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameListYear = data.getSameList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getQuarter(ReportTimeUtil.getPlusYearMonth(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()), 12)))).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(listYear, lastListYear, sameListYear, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k)) {
                List<SalaryAcctEmployeePO> listYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getQuarter(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                data.setListByDimensionValue(listYear);
            }
        });

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildHalfYearRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        Set<String> halfYearSet = Sets.newHashSet();
        data.getList().forEach(sa -> halfYearSet.add(ReportTimeUtil.getHalfYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()))));
        List<String> halfYears = halfYearSet.stream().sorted().collect(Collectors.toList());
        Collections.reverse(halfYears);

        String dimensionValue = data.getDimensionValue();
        halfYears.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> listHalfYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getHalfYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastListHalfYear = data.getLastList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getHalfYear(ReportTimeUtil.getPlusYearMonth(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()), 6)))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameListHalfYear = data.getSameList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getHalfYear(ReportTimeUtil.getPlusYearMonth(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()), 12)))).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(listHalfYear, lastListHalfYear, sameListHalfYear, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k)) {
                List<SalaryAcctEmployeePO> listHalfYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getHalfYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                data.setListByDimensionValue(listHalfYear);
            }
        });

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildYearRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        Set<String> yearSet = Sets.newHashSet();
        data.getList().forEach(sa -> yearSet.add(ReportTimeUtil.getYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth()))));
        List<String> years = yearSet.stream().sorted().collect(Collectors.toList());
        Collections.reverse(years);

        String dimensionValue = data.getDimensionValue();
        years.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> listYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastListYear = data.getLastList().stream().filter(sa -> Objects.equals(ReportTimeUtil.getLastYear(k), ReportTimeUtil.getYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameListYear = data.getSameList().stream().filter(sa -> Objects.equals(ReportTimeUtil.getLastYear(k), ReportTimeUtil.getYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(listYear, lastListYear, sameListYear, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k)) {
                List<SalaryAcctEmployeePO> listYear = data.getList().stream().filter(sa -> Objects.equals(k, ReportTimeUtil.getYear(SalaryDateUtil.getFormatYearMonth(sa.getSalaryMonth())))).collect(Collectors.toList());
                data.setListByDimensionValue(listYear);
            }
        });

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildSexRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        Map<String, String> sexMap = Arrays.stream(Sex.values()).collect(Collectors.toMap(Sex::getName, Sex::getDescription));
//
//        Map<Long, String> empIdSexIdMap = new HashMap<>();
//        Map<Long, String> lastEmpIdSexIdMap = new HashMap<>();
//        Map<Long, String> sameEmpIdSexIdMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (employee.getSex() != null) {
//                empIdSexIdMap.put(employee.getId(), employee.getSex().getName());
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (employee.getSex() != null) {
//                lastEmpIdSexIdMap.put(employee.getId(), employee.getSex().getName());
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (employee.getSex() != null) {
//                sameEmpIdSexIdMap.put(employee.getId(), employee.getSex().getName());
//            }
//        });
//
//        sexMap.forEach((k, v) -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdSexIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdSexIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdSexIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, v);
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdSexIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdSexIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdSexIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildJobCallRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(sameEmployeeIds, data.getTenantKey());
//
//        Set<Long> jobCallIds = Sets.newHashSet();
//        Map<Long, Long> empIdJobCallIdMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdJobCallIdMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdJobCallIdMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (employee.getJobCall() != null) {
//                empIdJobCallIdMap.put(employee.getId(), employee.getJobCall());
//                jobCallIds.add(employee.getJobCall());
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (employee.getJobCall() != null) {
//                lastEmpIdJobCallIdMap.put(employee.getId(), employee.getJobCall());
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (employee.getJobCall() != null) {
//                sameEmpIdJobCallIdMap.put(employee.getId(), employee.getJobCall());
//            }
//        });
//
//        HrmJobCallParam jobCallParam = new HrmJobCallParam();
//        jobCallParam.setIds(Lists.newArrayList(jobCallIds));
//        jobCallParam.setEmployeeId(data.getEmployeeId());
//        jobCallParam.setTenantKey(data.getTenantKey());
//        List<BrowserDataDto> jobCallList = CollectionUtils.isEmpty(jobCallIds) ? Lists.newArrayList() : hrmJobCallRemoteService.getJobCallBrowserByIds(jobCallParam);
//        Map<String, String> jobCallIdMap = jobCallList.stream().collect(Collectors.toMap(BrowserDataDto::getId, BrowserDataDto::getName));
//
//        jobCallIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdJobCallIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdJobCallIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdJobCallIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, jobCallIdMap.get(k.toString()));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdJobCallIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdJobCallIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdJobCallIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildSuperiorRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
//        List<SimpleEmployee> simpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(employeeIds, data.getTenantKey());
//        List<SimpleEmployee> lastSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(lastEmployeeIds, data.getTenantKey());
//        List<SimpleEmployee> sameSimpleEmployeeList = hrmCommonEmployeeService.getEmployeeByIds(sameEmployeeIds, data.getTenantKey());
//
//        Set<Long> superiorIds = new HashSet<>();
//        Map<Long, Long> empIdSuperiorIdMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdSuperiorIdMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdSuperiorIdMap = new HashMap<>();
//        simpleEmployeeList.forEach(employee -> {
//            if (employee.getSuperior() != null && employee.getSuperior().getId() != null) {
//                empIdSuperiorIdMap.put(employee.getId(), employee.getSuperior().getId());
//                superiorIds.add(employee.getSuperior().getId());
//            }
//        });
//        lastSimpleEmployeeList.forEach(employee -> {
//            if (employee.getSuperior() != null && employee.getSuperior().getId() != null) {
//                lastEmpIdSuperiorIdMap.put(employee.getId(), employee.getSuperior().getId());
//            }
//        });
//        sameSimpleEmployeeList.forEach(employee -> {
//            if (employee.getSuperior() != null && employee.getSuperior().getId() != null) {
//                sameEmpIdSuperiorIdMap.put(employee.getId(), employee.getSuperior().getId());
//            }
//        });
//
//        List<SimpleEmployee> superiorList = CollectionUtils.isEmpty(superiorIds) ? Lists.newArrayList() : hrmCommonEmployeeService.getEmployeeByIds(Lists.newArrayList(superiorIds), data.getTenantKey());
//        Map<Long, String> superiorMap = superiorList.stream().collect(Collectors.toMap(SimpleEmployee::getId, SimpleEmployee::getUsername));
//
//        superiorIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdSuperiorIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdSuperiorIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdSuperiorIdMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, superiorMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdSuperiorIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdSuperiorIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdSuperiorIdMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildMaritalStatusRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<String> maritalStatusIds = new HashSet<>();
//
//        Map<Long, String> empIdMaritalStatusMap = new HashMap<>();
//        Map<Long, String> lastEmpIdMaritalStatusMap = new HashMap<>();
//        Map<Long, String> sameEmpIdMaritalStatusMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (StringUtils.isNotEmpty(employee.getMaritalStatus())) {
//                maritalStatusIds.add(employee.getMaritalStatus());
//                empIdMaritalStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getMaritalStatus());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (StringUtils.isNotEmpty(employee.getMaritalStatus())) {
//                lastEmpIdMaritalStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getMaritalStatus());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (StringUtils.isNotEmpty(employee.getMaritalStatus())) {
//                sameEmpIdMaritalStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getMaritalStatus());
//            }
//        });
//        Map<String, String> maritalStatusMap = Maps.newHashMap();
//        maritalStatusMap.put("married", SalaryI18nUtil.getI18nLabel( 174138, "已婚"));
//        maritalStatusMap.put("unmarried", SalaryI18nUtil.getI18nLabel( 174139, "未婚"));
//        maritalStatusMap.put("divorced", SalaryI18nUtil.getI18nLabel( 174140, "离异"));
//
//        maritalStatusIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdMaritalStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdMaritalStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdMaritalStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, maritalStatusMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdMaritalStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdMaritalStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdMaritalStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel( 153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
        return result;
    }

    private Map<String, List<DataCollectionEmployee>> getSimpleUserInfoList(SalaryStatisticsReportDataDTO data) {
        List<Long> employeeIds = data.getList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> lastEmployeeIds = data.getLastList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());
        List<Long> sameEmployeeIds = data.getSameList().stream().map(SalaryAcctEmployeePO::getEmployeeId).distinct().collect(Collectors.toList());

        List<DataCollectionEmployee> simpleUserInfoList;
        List<DataCollectionEmployee> lastSimpleUserInfoList;
        List<DataCollectionEmployee> sameSimpleUserInfoList;
        Map<String, List<DataCollectionEmployee>> map = Maps.newHashMap();
        try {
            simpleUserInfoList = CollectionUtils.isEmpty(employeeIds) ? Lists.newArrayList() : getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
            lastSimpleUserInfoList = CollectionUtils.isEmpty(lastEmployeeIds) ? Lists.newArrayList() : getSalaryEmployeeService(user).getEmployeeByIdsAll(lastEmployeeIds);
            sameSimpleUserInfoList = CollectionUtils.isEmpty(sameEmployeeIds) ? Lists.newArrayList() : getSalaryEmployeeService(user).getEmployeeByIdsAll(sameEmployeeIds);
        } catch (Exception e) {
            log.info("获取员工个人信息失败: {}", e.getMessage());
            return map;
        }
        map.put(NOW_INFO, simpleUserInfoList);
        map.put(LAST_INFO, lastSimpleUserInfoList);
        map.put(SAME_INFO, sameSimpleUserInfoList);
        return map;
    }

//    private PageInfo<Map<String, Object>> buildEducationRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Long> educationIds = new HashSet<>();
//        Map<Long, String> educationMap = Maps.newHashMap();
//
//        Map<Long, Long> empIdEducationMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdEducationMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdEducationMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getEducation() != null && employee.getEducation().getId() != null) {
//                educationIds.add(employee.getEducation().getId());
//                empIdEducationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getEducation().getId());
//                educationMap.put(employee.getEducation().getId(), employee.getEducation().getName());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getEducation() != null && employee.getEducation().getId() != null) {
//                lastEmpIdEducationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getEducation().getId());
//                educationMap.put(employee.getEducation().getId(), employee.getEducation().getName());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getEducation() != null && employee.getEducation().getId() != null) {
//                sameEmpIdEducationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getEducation().getId());
//                educationMap.put(employee.getEducation().getId(), employee.getEducation().getName());
//            }
//        });
//
//        educationIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdEducationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdEducationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdEducationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, educationMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdEducationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdEducationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdEducationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }
//
//    private PageInfo<Map<String, Object>> buildDegreeRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Long> degreeIds = new HashSet<>();
//        Map<Long, String> degreeMap = Maps.newHashMap();
//
//        Map<Long, Long> empIdDegreeMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdDegreeMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdDegreeMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getDegree() != null && employee.getDegree().getId() != null) {
//                degreeIds.add(employee.getDegree().getId());
//                empIdDegreeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getDegree().getId());
//                degreeMap.put(employee.getDegree().getId(), employee.getDegree().getName());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getDegree() != null && employee.getDegree().getId() != null) {
//                lastEmpIdDegreeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getDegree().getId());
//                degreeMap.put(employee.getDegree().getId(), employee.getDegree().getName());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getDegree() != null && employee.getDegree().getId() != null) {
//                sameEmpIdDegreeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getDegree().getId());
//                degreeMap.put(employee.getDegree().getId(), employee.getDegree().getName());
//            }
//        });
//
//        degreeIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdDegreeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdDegreeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdDegreeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, degreeMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdDegreeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdDegreeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdDegreeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }
//
//    private PageInfo<Map<String, Object>> buildNationRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Long> nationIds = new HashSet<>();
//        Map<Long, String> nationMap = Maps.newHashMap();
//
//        Map<Long, Long> empIdNationMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdNationMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdNationMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getNation() != null && employee.getNation().getId() != null) {
//                nationIds.add(employee.getNation().getId());
//                empIdNationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getNation().getId());
//                nationMap.put(employee.getNation().getId(), employee.getNation().getName());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getNation() != null && employee.getNation().getId() != null) {
//                lastEmpIdNationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getNation().getId());
//                nationMap.put(employee.getNation().getId(), employee.getNation().getName());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getNation() != null && employee.getNation().getId() != null) {
//                sameEmpIdNationMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getNation().getId());
//                nationMap.put(employee.getNation().getId(), employee.getNation().getName());
//            }
//        });
//
//        nationIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdNationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdNationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdNationMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, nationMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdNationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdNationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdNationMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }
//
//    private PageInfo<Map<String, Object>> buildHouseholdTypeRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Long> householdTypeIds = new HashSet<>();
//        Map<Long, String> householdTypeMap = Maps.newHashMap();
//
//        Map<Long, Long> empIdHouseholdTypeMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdHouseholdTypeMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdHouseholdTypeMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getHouseholdType() != null && employee.getHouseholdType().getId() != null) {
//                householdTypeIds.add(employee.getHouseholdType().getId());
//                empIdHouseholdTypeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getHouseholdType().getId());
//                householdTypeMap.put(employee.getHouseholdType().getId(), employee.getHouseholdType().getName());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getHouseholdType() != null && employee.getHouseholdType().getId() != null) {
//                lastEmpIdHouseholdTypeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getHouseholdType().getId());
//                householdTypeMap.put(employee.getHouseholdType().getId(), employee.getHouseholdType().getName());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getHouseholdType() != null && employee.getHouseholdType().getId() != null) {
//                sameEmpIdHouseholdTypeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getHouseholdType().getId());
//                householdTypeMap.put(employee.getHouseholdType().getId(), employee.getHouseholdType().getName());
//            }
//        });
//
//        householdTypeIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdHouseholdTypeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdHouseholdTypeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdHouseholdTypeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, householdTypeMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdHouseholdTypeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdHouseholdTypeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdHouseholdTypeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }
//
//    private PageInfo<Map<String, Object>> buildPoliticsStatusRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Long> politicsStatusIds = new HashSet<>();
//        Map<Long, String> politicsStatusMap = Maps.newHashMap();
//
//        Map<Long, Long> empIdPoliticsStatusMap = new HashMap<>();
//        Map<Long, Long> lastEmpIdPoliticsStatusMap = new HashMap<>();
//        Map<Long, Long> sameEmpIdPoliticsStatusMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getPoliticsStatus() != null && employee.getPoliticsStatus().getId() != null) {
//                politicsStatusIds.add(employee.getPoliticsStatus().getId());
//                empIdPoliticsStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getPoliticsStatus().getId());
//                politicsStatusMap.put(employee.getPoliticsStatus().getId(), employee.getPoliticsStatus().getName());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getPoliticsStatus() != null && employee.getPoliticsStatus().getId() != null) {
//                lastEmpIdPoliticsStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getPoliticsStatus().getId());
//                politicsStatusMap.put(employee.getPoliticsStatus().getId(), employee.getPoliticsStatus().getName());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getPoliticsStatus() != null && employee.getPoliticsStatus().getId() != null) {
//                sameEmpIdPoliticsStatusMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getPoliticsStatus().getId());
//                politicsStatusMap.put(employee.getPoliticsStatus().getId(), employee.getPoliticsStatus().getName());
//            }
//        });
//
//        politicsStatusIds.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdPoliticsStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdPoliticsStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdPoliticsStatusMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, politicsStatusMap.get(k));
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdPoliticsStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdPoliticsStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdPoliticsStatusMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }
//
//    private PageInfo<Map<String, Object>> buildAgeRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
//        if (simpleUserInfoMap.isEmpty()) {
//            return result;
//        }
//
//        Set<Integer> ageSet = new HashSet<>();
//
//        Map<Long, Integer> empIdAgeMap = new HashMap<>();
//        Map<Long, Integer> lastEmpIdAgeMap = new HashMap<>();
//        Map<Long, Integer> sameEmpIdAgeMap = new HashMap<>();
//        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (employee.getAge() != null) {
//                ageSet.add(employee.getAge());
//                empIdAgeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge());
//            }
//        });
//        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (employee.getAge() != null) {
//                lastEmpIdAgeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge());
//            }
//        });
//        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (employee.getAge() != null) {
//                sameEmpIdAgeMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge());
//            }
//        });
//
//        List<Integer> ages = Lists.newArrayList(ageSet);
//        ages = ages.stream().sorted().collect(Collectors.toList());
//
//        ages.forEach(k -> {
//            List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdAgeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdAgeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdAgeMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
//            Map<String, Object> temp = new HashMap<>();
//            temp.put(DM, k);
//            temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(temp);
//        });
//
//        List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdAgeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdAgeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> lastEmpIdAgeMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(noGroupingList)) {
//            Map<String, Object> noGrouping = new HashMap<>();
//            noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
//            noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
//            records.add(noGrouping);
//        }
//
//        result.setList(records);
//        return result;
//    }

    private PageInfo<Map<String, Object>> buildWorkYearRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();
        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
        if (simpleUserInfoMap.isEmpty()) {
            return result;
        }

        Set<Double> workYearSet = new HashSet<>();

        Map<Long, Double> empIdWorkYearMap = new HashMap<>();
        Map<Long, Double> lastEmpIdWorkYearMap = new HashMap<>();
        Map<Long, Double> sameEmpIdWorkYearMap = new HashMap<>();
        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
            if (employee.getWorkYear() != null) {
                workYearSet.add(employee.getWorkYear());
                empIdWorkYearMap.put(employee.getEmployeeId(), employee.getWorkYear());
            }
        });
        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
            if (employee.getWorkYear() != null) {
                lastEmpIdWorkYearMap.put(employee.getEmployeeId(), employee.getWorkYear());
            }
        });
        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
            if (employee.getWorkYear() != null) {
                sameEmpIdWorkYearMap.put(employee.getEmployeeId(), employee.getWorkYear());
            }
        });
        List<Double> workYears = Lists.newArrayList(workYearSet);
        workYears = workYears.stream().sorted().collect(Collectors.toList());

        String dimensionValue = data.getDimensionValue();
        workYears.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdWorkYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdWorkYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdWorkYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (Double.compare(Double.valueOf(dimensionValue), k) == 0) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdWorkYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                data.setListByDimensionValue(salaryAcctEmployees);
            }
        });

        if (dimensionValue == null) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdWorkYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdWorkYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> lastEmpIdWorkYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noGroupingList)) {
                Map<String, Object> noGrouping = new HashMap<>();
                noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
                noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(noGrouping);
            }
        } else if (StringUtils.equals(dimensionValue, "无分组")) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdWorkYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            data.setListByDimensionValue(noGroupingList);
        }

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildCompanyYearRecords(SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();
        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
        if (simpleUserInfoMap.isEmpty()) {
            return result;
        }

        Set<String> companyYearSet = new HashSet<>();

        Map<Long, String> empIdCompanyYearMap = new HashMap<>();
        Map<Long, String> lastEmpIdCompanyYearMap = new HashMap<>();
        Map<Long, String> sameEmpIdCompanyYearMap = new HashMap<>();
        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
            if (employee.getCompanyWorkYear() != null) {
                companyYearSet.add(Util.null2String(employee.getCompanyWorkYear()));
                empIdCompanyYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });
        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
            if (employee.getCompanyWorkYear() != null) {
                lastEmpIdCompanyYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });
        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
            if (employee.getCompanyWorkYear() != null) {
                sameEmpIdCompanyYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });

        List<String> companyYears = Lists.newArrayList(companyYearSet);
        companyYears = companyYears.stream().sorted().collect(Collectors.toList());

        String dimensionValue = data.getDimensionValue();
        companyYears.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdCompanyYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = data.getLastList().stream().filter(po -> Objects.equals(lastEmpIdCompanyYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = data.getSameList().stream().filter(po -> Objects.equals(sameEmpIdCompanyYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k)) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = data.getList().stream().filter(po -> Objects.equals(empIdCompanyYearMap.get(po.getEmployeeId()), k)).collect(Collectors.toList());
                data.setListByDimensionValue(salaryAcctEmployees);
            }
        });

        if (dimensionValue == null) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdCompanyYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> lastNoGroupingList = data.getLastList().stream().filter(po -> lastEmpIdCompanyYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            List<SalaryAcctEmployeePO> sameNoGroupingList = data.getSameList().stream().filter(po -> sameEmpIdCompanyYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noGroupingList)) {
                Map<String, Object> noGrouping = new HashMap<>();
                noGrouping.put(DM, SalaryI18nUtil.getI18nLabel(153462, "无分组"));
                noGrouping.putAll(SalaryStatisticsReportBO.calculateItem(noGroupingList, lastNoGroupingList, sameNoGroupingList, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(noGrouping);
            }
        } else if (StringUtils.equals(dimensionValue, "无分组")) {
            List<SalaryAcctEmployeePO> noGroupingList = data.getList().stream().filter(po -> empIdCompanyYearMap.get(po.getEmployeeId()) == null).collect(Collectors.toList());
            data.setListByDimensionValue(noGroupingList);
        }

        result.setList(records);
        return result;
    }

    private PageInfo<Map<String, Object>> buildSalaryItemRecords(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {

        //查询薪资项目存在的种类（维度）
        Set<String> dimensionSet = new HashSet<>();
        for (Long k : salaryAcctResultValueMap.keySet()) {
            Map<String, String> map = salaryAcctResultValueMap.get(k);
            dimensionSet.add(map.getOrDefault(dimension.getDimCode(), ""));
        }

        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        Map<Long, String> empIdYearMap = new HashMap<>();
        Map<Long, String> lastEmpIdYearMap = new HashMap<>();
        Map<Long, String> sameEmpIdYearMap = new HashMap<>();

        String dimensionValue = data.getDimensionValue();
        dimensionSet.stream().sorted((a, b) -> b.length() - a.length()).forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, dimension.getDimCode(), data.getLastList(), lastEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, dimension.getDimCode(), data.getSameList(), sameEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k);
                temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k)) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                data.setListByDimensionValue(salaryAcctEmployees);
            }
        });
        result.setList(records);
        return result;
    }

//    private PageInfo<Map<String, Object>> buildRationGroupSpacing4NoItemRecords(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
//        PageInfo<Map<String, Object>> result = new PageInfo<>();
//        List<Map<String, Object>> records = new ArrayList<>();
//
//        // 分组设置
//        List<SalaryStatisticsDimensionSaveParam.Setting4RationGroupSpacing> groups = JsonUtil.parseList(dimension.getSetting(), SalaryStatisticsDimensionSaveParam.Setting4RationGroupSpacing.class);
//
//
//        result.setList(records);
//        return result;
//    }

    private PageInfo<Map<String, Object>> buildRationGroupSpacing4Records(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        // 分组设置
        List<SalaryStatisticsDimensionSaveParam.Setting4RationGroupSpacing> groups = JsonUtil.parseList(dimension.getSetting(), SalaryStatisticsDimensionSaveParam.Setting4RationGroupSpacing.class);

        Map<Long, String> empIdYearMap = new HashMap<>();
        Map<Long, String> lastEmpIdYearMap = new HashMap<>();
        Map<Long, String> sameEmpIdYearMap = new HashMap<>();

        String groupBelong;
        if (StringUtils.isEmpty(dimension.getDimCode())) {
            groupBelong = SalaryStatisticsReportBO.G_NO_ITEM;
        } else if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_AGE) || dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_WORK_YEAR) || dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR)) {
            groupBelong = SalaryStatisticsReportBO.G_YEAR;
            // 年份数据
            handle4GroupYear(dimension, empIdYearMap, lastEmpIdYearMap, sameEmpIdYearMap, data);
        } else {
            groupBelong = SalaryStatisticsReportBO.G_ITEM;
        }
        String dimensionValue = data.getDimensionValue();
        groups.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupSpacing(k, groupBelong, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupSpacing(k, groupBelong, dimension.getDimCode(), data.getLastList(), lastEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupSpacing(k, groupBelong, dimension.getDimCode(), data.getSameList(), sameEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k.getStartValue() + "-" + k.getEndValue());
                temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k.getStartValue() + "-" + k.getEndValue())) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupSpacing(k, groupBelong, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                data.setListByDimensionValue(salaryAcctEmployees);
            }
        });

        result.setList(records);
        return result;
    }

    private void handle4GroupYear(SalaryStatisticsDimensionPO dimension, Map<Long, String> empIdYearMap, Map<Long, String> lastEmpIdYearMap, Map<Long, String> sameEmpIdYearMap, SalaryStatisticsReportDataDTO data) {
        Map<String, List<DataCollectionEmployee>> simpleUserInfoMap = getSimpleUserInfoList(data);
        if (simpleUserInfoMap.isEmpty()) {
            return;
        }
        simpleUserInfoMap.get(NOW_INFO).forEach(employee -> {
//            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_AGE) && employee.getAge() != null) {
//                empIdYearMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge().toString());
//            } else

            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_WORK_YEAR) && employee.getWorkYear() != null) {
                empIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getWorkYear()));
            } else if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR) && employee.getCompanyWorkYear() != null) {
                empIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });
        simpleUserInfoMap.get(LAST_INFO).forEach(employee -> {
//            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_AGE) && employee.getAge() != null) {
//                lastEmpIdYearMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge().toString());
//            } else

            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_WORK_YEAR) && employee.getWorkYear() != null) {
                lastEmpIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getWorkYear()));
            } else if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR) && employee.getCompanyWorkYear() != null) {
                lastEmpIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });
        simpleUserInfoMap.get(SAME_INFO).forEach(employee -> {
//            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_AGE) && employee.getAge() != null) {
//                sameEmpIdYearMap.put(Objects.isNull(employee.getUser()) ? null : employee.getUser().getId(), employee.getAge().toString());
//            } else
            if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_WORK_YEAR) && employee.getWorkYear() != null) {
                sameEmpIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getWorkYear()));
            } else if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR) && employee.getCompanyWorkYear() != null) {
                sameEmpIdYearMap.put(employee.getEmployeeId(), Util.null2String(employee.getCompanyWorkYear()));
            }
        });
    }

    private PageInfo<Map<String, Object>> buildRationGroupIndividual4Records(SalaryStatisticsDimensionPO dimension, SalaryStatisticsReportDataDTO data, Map<Long, Map<String, String>> salaryAcctResultValueMap) {
        PageInfo<Map<String, Object>> result = new PageInfo<>();
        List<Map<String, Object>> records = new ArrayList<>();

        // 分组设置
        List<SalaryStatisticsDimensionSaveParam.Setting4RationGroupIndividual> groups = JsonUtil.parseList(dimension.getSetting(), SalaryStatisticsDimensionSaveParam.Setting4RationGroupIndividual.class);
        Map<Long, String> empIdYearMap = new HashMap<>();
        Map<Long, String> lastEmpIdYearMap = new HashMap<>();
        Map<Long, String> sameEmpIdYearMap = new HashMap<>();

        String groupBelong;
        if (StringUtils.isEmpty(dimension.getDimCode())) {
            groupBelong = SalaryStatisticsReportBO.G_NO_ITEM;
        } else if (dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_AGE) || dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_WORK_YEAR) || dimension.getDimCode().equals(SalaryStatisticsDimensionConstant.DM_COMPANY_YEAR)) {
            groupBelong = SalaryStatisticsReportBO.G_YEAR;

            // 年份数据
            handle4GroupYear(dimension, empIdYearMap, lastEmpIdYearMap, sameEmpIdYearMap, data);
        } else {
            groupBelong = SalaryStatisticsReportBO.G_ITEM;
        }

        String dimensionValue = data.getDimensionValue();
        groups.forEach(k -> {
            if (dimensionValue == null) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, groupBelong, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> lastSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, groupBelong, dimension.getDimCode(), data.getLastList(), lastEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                List<SalaryAcctEmployeePO> sameSalaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, groupBelong, dimension.getDimCode(), data.getSameList(), sameEmpIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                Map<String, Object> temp = new HashMap<>();
                temp.put(DM, k.getValue());
                temp.putAll(SalaryStatisticsReportBO.calculateItem(salaryAcctEmployees, lastSalaryAcctEmployees, sameSalaryAcctEmployees, salaryAcctResultValueMap, data.getSalaryStatisticsItemList()));
                records.add(temp);
            } else if (StringUtils.equals(dimensionValue, k.getValue())) {
                List<SalaryAcctEmployeePO> salaryAcctEmployees = SalaryStatisticsReportBO.listAcctEmpByRationGroupIndividual(k, groupBelong, dimension.getDimCode(), data.getList(), empIdYearMap, salaryAcctResultValueMap, data.getSalaryStatisticsItemList());
                data.setListByDimensionValue(salaryAcctEmployees);
            }
        });

        result.setList(records);
        return result;
    }
}
