package com.tofly.gpsboot.service.statement.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.api.DepartmentClient;
import com.tofly.api.UserClent;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.es.GpsUpload;
import com.tofly.es.PdaDeviceUpload;
import com.tofly.es.dto.EsQueryDto;
import com.tofly.gpsboot.common.CalendarHelper;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.business.DateTypeEnum;
import com.tofly.gpsboot.common.system.*;
import com.tofly.gpsboot.mapper.maintain.RepairtypeMapper;
import com.tofly.gpsboot.mapper.plan.PlanMapper;
import com.tofly.gpsboot.service.build.BuildService;
import com.tofly.gpsboot.service.es.IGpsUploadService;
import com.tofly.gpsboot.service.es.IPdaDeviceService;
import com.tofly.gpsboot.service.paln.PlanchildtypeService;
import com.tofly.gpsboot.service.paln.PlantypeService;
import com.tofly.pojo.build.Build;
import com.tofly.pojo.statement.StatementAssess;
import com.tofly.pojo.statement.dto.StatementDto;
import com.tofly.pojo.statement.vo.*;
import com.tofly.pojo.trouble.vo.TroubleVo;
import com.tofly.gpsboot.mapper.trouble.TroubleMapper;
import com.tofly.gpsboot.service.config.InspectgroupService;
import com.tofly.gpsboot.service.maintain.*;
import com.tofly.gpsboot.service.paln.GpscalculateService;
import com.tofly.gpsboot.service.paln.GroupuserService;
import com.tofly.gpsboot.service.paln.task.PlanService;
import com.tofly.gpsboot.service.paln.task.PlanchildService;
import com.tofly.gpsboot.service.statement.IStatementService;
import com.tofly.gpsboot.service.trouble.ToubleplanService;
import com.tofly.gpsboot.service.trouble.ToubletypeService;
import com.tofly.gpsboot.service.trouble.TroubleService;
import com.tofly.gpsboot.util.DateTimeUtil;
import com.tofly.pojo.User;
import com.tofly.pojo.maintain.*;
import com.tofly.pojo.plan.*;
import com.tofly.pojo.trouble.Toubleplan;
import com.tofly.pojo.trouble.Trouble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 报表相关服务实现类
 *
 * @author BZ-DJJ
 */
@Service("statementService")
public class StatementServiceImpl implements IStatementService {

    @Autowired
    private RepairorderService repairorderService;

    @Autowired
    private RepairuserService repairuserService;

    @Autowired
    private RepairtypeService repairtypeService;

    @Autowired
    private UserClent userClent;

    @Autowired
    private PlanService planService;
    @Autowired
    private PlanchildService planchildService;

    @Autowired
    private TroubleService troubleService;


    @Autowired
    private DepartmentClient departmentClient;

    @Autowired
    private ToubleplanService toubleplanService;

    @Autowired
    private ToubletypeService toubletypeService;

    @Autowired
    private GroupuserService groupuserService;

    @Autowired
    private GpscalculateService gpscalculateService;

    @Autowired
    private TroubleMapper troubleMapper;

    @Autowired
    private InspectgroupService inspectgroupService;
    @Autowired
    private IPdaDeviceService iPdaDeviceService;
    @Autowired
    private PlantypeService plantypeService;
    @Autowired
    private PlanchildtypeService planchildtypeService;
    @Autowired
    private BuildService buildService;

    @Autowired
    private RepairtypeMapper repairtypeMapper;

    @Autowired
    private RepairgoodsService repairGoodsService;

    @Autowired
    private RepairmaterialService repairmaterialService;

    @Autowired
    private RepairrecordService repairrecordService;

    @Autowired
    private PipeMfRecordService pipeMfRecordService;

    @Autowired
    private IGpsUploadService iGpsUploadService;

    @Override
    public List<MaintenanceStatisticsVo> getMaintenanceStatistics(StatementDto dto) {
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        String regionCodeList = dto.getRegionCodeList();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> deptUserIdList = this.getDeptUserIdList(deptId, userId);
        List<Long> list = null;
        // 是否对应片区且状态为已完成
        if (StringUtils.isEmpty(regionCodeList)) {
            list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().in(Repairuser::getRespUser, deptUserIdList).ge(Repairuser::getCreateTime, startDate).le(Repairuser::getCreateTime, endDate).eq(Repairuser::getState, OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode())).stream().map(Repairuser::getRepairId).collect(Collectors.toList());
        } else {
            List<String> codeList = Arrays.stream(regionCodeList.split(Constant.CSV))
                    .collect(Collectors.toList());
            list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().in(Repairuser::getRespUser, deptUserIdList).ge(Repairuser::getCreateTime, startDate).le(Repairuser::getCreateTime, endDate).eq(Repairuser::getState, OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode()).in(Repairuser::getRegionCode, codeList)).stream().map(Repairuser::getRepairId).collect(Collectors.toList());
        }
        if (list.size() > 0) {
            List<Repairorder> repairOrderList = repairorderService.list(new QueryWrapper<Repairorder>().lambda().in(Repairorder::getId, list));
            // 类型id - 月份+数量
            Map<Long, Map<String, Long>> longMapMap = repairOrderList.stream().collect(Collectors.groupingBy(Repairorder::getTypeId, Collectors.groupingBy(order -> String.valueOf(DateTimeUtil.fromLong2LocalDateTime(order.getOverTime().getTime()).getYear()) + "-" + DateTimeUtil.fromLong2LocalDateTime(order.getOverTime().getTime()).getMonthValue(), Collectors.counting())));
            Map<String, List<MaintenanceStatisticsDetailVo>> map = new HashMap<>(12);
            longMapMap.forEach((k, v) -> {
                Repairtype repairtype = repairtypeService.getById(k);
                String groupName = repairtype.getGroupName();
                String name = repairtype.getName();
                String unit = repairtype.getUnit();
                if (map.containsKey(groupName)) {
                    List<MaintenanceStatisticsDetailVo> detailVos = map.get(groupName);
                    MaintenanceStatisticsDetailVo vo = new MaintenanceStatisticsDetailVo();
                    vo.setUnit(unit);
                    vo.setTypeName(name);
                    vo.setMonthNumMap(v);
                    detailVos.add(vo);
                    map.put(groupName, detailVos);
                } else {
                    List<MaintenanceStatisticsDetailVo> voList = new ArrayList<>();
                    MaintenanceStatisticsDetailVo vo = new MaintenanceStatisticsDetailVo();
                    vo.setUnit(unit);
                    vo.setTypeName(name);
                    vo.setMonthNumMap(v);
                    voList.add(vo);
                    map.put(groupName, voList);
                }

            });
            return map.entrySet().stream().map(e -> new MaintenanceStatisticsVo(e.getKey(), e.getValue())).collect(Collectors.toList());

        } else {
            return new ArrayList<>();
        }


    }

    @Override
    public List<MaintenanceWorkVo> getMaintenanceWork(StatementDto dto) {
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        List<Repairuser> list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().ge(Repairuser::getCreateTime, startDate).le(Repairuser::getCreateTime, endDate).in(Repairuser::getRespUser, userIdList));
        List<MaintenanceWorkVo> voList = new ArrayList<>();
        if (list.size() > 0) {
            Map<Long, List<Repairuser>> map = list.stream().collect(Collectors.groupingBy(Repairuser::getRespUser, Collectors.toList()));
            Map<Long, String> userMap = new HashMap<>(12);
            Map<Long, String> deptMap = new HashMap<>(12);
            list.forEach(info -> {
                userMap.put(info.getRespUser(), info.getRespUserName());
                deptMap.put(info.getRespUser(), info.getDeptName());
            });
            map.forEach((k, v) -> {
                MaintenanceWorkVo vo = new MaintenanceWorkVo();
                vo.setUserName(userMap.get(k));
                vo.setDeptName(deptMap.get(k));
                // vo.setRepairOrderNum(v.stream().mapToLong(Repairuser::getPlanNum).sum());
                vo.setRepairOrderNum(v.stream().count());
                vo.setRatifyTime(v.stream().filter(i -> null != i.getRatifyTime()).mapToDouble(Repairuser::getRatifyTime).sum());
                double realTimeSum = v.stream().filter(i -> null != i.getRealTime()).mapToDouble(Repairuser::getRealTime).sum();
                vo.setAverageTime(BigDecimal.valueOf(realTimeSum).divide(BigDecimal.valueOf(vo.getRepairOrderNum()), BigDecimal.ROUND_HALF_UP).doubleValue());
                List<Build> buildList = buildService.list(new QueryWrapper<Build>().lambda().ge(Build::getCreateTime, startDate).le(Build::getCreateTime, endDate).eq(Build::getCreateUser, k));
                if (null != buildList && buildList.size() > 0) {
                    vo.setFindBuildNum((long) buildList.size());
                } else {
                    vo.setFindBuildNum(BigDecimal.ZERO.longValue());
                }
                List<Trouble> troubleList = troubleService.list(new QueryWrapper<Trouble>().lambda().ge(Trouble::getCreateTime, startDate).le(Trouble::getCreateTime, endDate).eq(Trouble::getCreateUser, k));
                if (null != troubleList && troubleList.size() > 0) {
                    vo.setFindTroubleNum((long) troubleList.size());
                } else {
                    vo.setFindTroubleNum(BigDecimal.ZERO.longValue());
                }

                vo.setFindPlanNum(this.getFindPlanNum(k, startDate, endDate));
                vo.setTypeDetails(this.getTypeDetails(v.stream().map(Repairuser::getRepairId).collect(Collectors.toSet())));
                voList.add(vo);
            });
        }

        return voList;
    }


    @Override
    public List<MaintenanceTypeStatisticsVo> getMaintenanceTypeStatistics(StatementDto dto) {

        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        String regionCodeList = dto.getRegionCodeList();
        List<MaintenanceTypeStatisticsVo> voList = new ArrayList<>();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        List<Long> list = null;
        // 是否对应片区且状态为已完成
        if (StringUtils.isEmpty(regionCodeList)) {
            list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().in(Repairuser::getRespUser, userIdList).ge(Repairuser::getCreateTime, startDate).le(Repairuser::getCreateTime, endDate).eq(Repairuser::getState, OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode())).stream().map(Repairuser::getRepairId).collect(Collectors.toList());
        } else {
            List<String> codeList = Arrays.stream(regionCodeList.split(Constant.CSV))
                    .collect(Collectors.toList());
            list = repairuserService.list(new QueryWrapper<Repairuser>().lambda().in(Repairuser::getRespUser, userIdList).ge(Repairuser::getCreateTime, startDate).le(Repairuser::getCreateTime, endDate).eq(Repairuser::getState, OrderStateEnum.ORDER_STATE_PROCESSING_COMPLETE.getCode()).in(Repairuser::getRegionCode, codeList)).stream().map(Repairuser::getRepairId).collect(Collectors.toList());
        }
        if (list.size() > 0) {
            List<Repairorder> repairorderList = repairorderService.list(new QueryWrapper<Repairorder>().lambda().in(Repairorder::getId, list));
            // 根据维修类型分组
            Map<Long, List<Repairorder>> collect = repairorderList.stream().collect(Collectors.groupingBy(Repairorder::getTypeId, Collectors.toList()));
            collect.forEach((k, v) -> {
                MaintenanceTypeStatisticsVo vo = new MaintenanceTypeStatisticsVo();
                Repairtype byId = repairtypeService.getById(k);
                vo.setTypeId(k);
                vo.setTypeName(byId.getName());
                vo.setTypeNum(v.stream().mapToLong(Repairorder::getNum).sum());
                vo.setUnit(byId.getUnit());
                voList.add(vo);
            });
        }
        return voList;
    }


    /**
     * 获取用户巡检计划数量
     *
     * @param userId
     * @param startDate
     * @param endDate
     * @return
     */
    private Long getFindPlanNum(Long userId, Date startDate, Date endDate) {
        List<Long> planIdList = planService.list(new QueryWrapper<Plan>().lambda().ge(Plan::getPlanBegindate, startDate).le(Plan::getPlanEnddate, endDate)).stream().map(Plan::getId).collect(Collectors.toList());
        if (planIdList.size() > 0) {
            List<Planchild> planChildList = planchildService.list(new QueryWrapper<Planchild>().lambda().in(Planchild::getPlanId, planIdList).eq(Planchild::getRespUser, userId));
            if (null != planChildList && planChildList.size() > 0) {
                return (long) planChildList.size();
            }
        }
        return 0L;
    }


    /**
     * 获取用户下维修类型占比数量
     *
     * @param orderIdList
     * @return
     */
    private Map<String, Long> getTypeDetails(Set<Long> orderIdList) {
        // 根据子计划id列表获取对应的维修类型id列表
        List<Long> typeIdList = repairorderService.list(new QueryWrapper<Repairorder>().lambda().in(Repairorder::getId, orderIdList)).stream().map(Repairorder::getTypeId).collect(Collectors.toList());
        return repairtypeService.list(new QueryWrapper<Repairtype>().lambda().in(Repairtype::getId, typeIdList)).stream().collect(Collectors.groupingBy(Repairtype::getName, Collectors.counting()));
    }

    @Override
    public List<TroubleTypeAnalysisVo> getTroubleTypeAnalysis(StatementDto dto) {
        String deptId = dto.getDeptId();
        String userId = dto.getUserId();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        List<TroubleTypeAnalysisVo> voList = new ArrayList<>();
        // 计划表和隐患计划关联表
        Set<Long> toublePlanIdList = toubleplanService.list().stream().map(Toubleplan::getPlanId).collect(Collectors.toSet());
        if (toublePlanIdList.size() > 0) {
            Set<Long> meetPlanIdList = planService.list(new QueryWrapper<Plan>().lambda().in(Plan::getId, toublePlanIdList).ge(Plan::getPlanBegindate, startDate).le(Plan::getPlanEnddate, endDate)).stream().map(Plan::getId).collect(Collectors.toSet());
            // 获取用户列表
            Set<Long> troubleUserIdList = this.getDeptUserIdList(deptId, userId);
            Set<Long> collect = planchildService.list(new QueryWrapper<Planchild>().lambda().in(Planchild::getPlanId, meetPlanIdList).in(Planchild::getRespUser, troubleUserIdList)).stream().map(Planchild::getPlanId).collect(Collectors.toSet());
            Set<Long> intersectionTroubleIdList = new HashSet<>();
            toublePlanIdList.forEach(toublePlanId -> {
                if (collect.contains(toublePlanId)) {
                    intersectionTroubleIdList.add(toublePlanId);
                }
            });
            // 查询对应隐患计划
            List<Trouble> troubleList = troubleService.list(new QueryWrapper<Trouble>().lambda().in(Trouble::getId, intersectionTroubleIdList));
            Map<Long, Map<String, Long>> mapMap = troubleList.stream().collect(Collectors.groupingBy(Trouble::getTypeId, Collectors.groupingBy(Trouble::getLocation, Collectors.counting())));

            mapMap.forEach((k, v) -> {
                TroubleTypeAnalysisVo vo = new TroubleTypeAnalysisVo();
                vo.setTroubleTypeName(toubletypeService.getById(k).getName());
                // 总数量
                long sum = v.values().stream().mapToLong(Long::byteValue).sum();
                v.forEach((ck, cv) -> {
                    vo.setLocation(ck);
                    int intValue = cv.intValue();
                    vo.setNum(intValue);
                    vo.setProportion(BigDecimal.valueOf(intValue).divide(BigDecimal.valueOf(sum), BigDecimal.ROUND_HALF_UP));
                    voList.add(vo);
                });
            });
        }

        return voList;
    }

    @Override
    public List<TroubleCauseVo> getTroubleCause(StatementDto dto) {
        List<TroubleCauseVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 多个片区
        String regionCodeList = dto.getRegionCodeList();
        QueryWrapper<Trouble> dtoQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(regionCodeList)) {
            List<String> regionIdList = Arrays.stream(regionCodeList.split(Constant.CSV))
                    .collect(Collectors.toList());
            dtoQueryWrapper.in("REGION_ID", regionIdList);
        }
        dtoQueryWrapper.ge("CREATE_TIME", startDate);
        dtoQueryWrapper.le("CREATE_TIME", endDate);

        List<Trouble> troubleVoList = troubleService.list(dtoQueryWrapper);
        if (null != troubleVoList && troubleVoList.size() > 0) {
            // 根据隐患类型分组对应数量
            Map<String, Long> counting = troubleVoList.stream()
                    .collect(Collectors.groupingBy(Trouble::getTypeIdName, Collectors.counting()));
            // 总数量/总比例
            long sum = counting.values().stream().mapToLong(Long::longValue).sum();
            counting.forEach((k, v) -> {
                TroubleCauseVo vo = new TroubleCauseVo();
                vo.setTroubleType(k);
                vo.setTroubleNum(v);
                vo.setRate(BigDecimal.valueOf(v).divide(BigDecimal.valueOf(sum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
                voList.add(vo);
            });
        }


        return voList;
    }

    @Override
    public List<TroubleTrendAnalysisVo> getTroubleTrendAnalysis(StatementDto dto) {
        List<TroubleTrendAnalysisVo> voList = new ArrayList<>();
        // 片区列表/隐患原因/时间类型,0年,1月/起始范围/终止范围
        String regionCodeList = dto.getRegionCodeList();
        String toubleType = dto.getToubleType();
        String dateType = dto.getDateType();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        QueryWrapper<Trouble> dtoQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(regionCodeList)) {
            List<String> regionIdList = Arrays.stream(regionCodeList.split(Constant.CSV))
                    .collect(Collectors.toList());
            dtoQueryWrapper.in("REGION_ID", regionIdList);
        }
        if (!StringUtils.isEmpty(toubleType)) {
            List<String> toubleTypeList = Arrays.stream(toubleType.split(Constant.CSV))
                    .collect(Collectors.toList());
            dtoQueryWrapper.in("TYPE_ID", toubleTypeList);
        }
        dtoQueryWrapper.ge("CREATE_TIME", startDate);
        dtoQueryWrapper.le("CREATE_TIME", endDate);
        List<Trouble> troubleVoList = troubleService.list(dtoQueryWrapper);

        Map<String, List<Trouble>> listMap = new HashMap<>(12);
        if (Constant.YEAR.equals(dateType)) {
            // 按照年分组
            listMap = troubleVoList.stream().collect(Collectors.groupingBy(t -> DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(t.getCreateTime().getTime()), DateTimeUtil.YEARS_FORMAT)));
        } else {
            // 按照月分组
            listMap = troubleVoList.stream().collect(Collectors.groupingBy(t -> DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(t.getCreateTime().getTime()), DateTimeUtil.FULL_MONTH_FORMAT)));
        }

        listMap.forEach((k, v) -> {
            int totalNum = v.size();
            // 按照类型分组
            Map<String, List<Trouble>> stringListMap = v.stream().collect(Collectors.groupingBy(Trouble::getTypeIdName, Collectors.toList()));
            stringListMap.forEach((z, m) -> {
                TroubleTrendAnalysisVo vo = new TroubleTrendAnalysisVo();
                vo.setAnalysisDate(k);
                vo.setTroubleTypeName(z);
                int size = m.size();
                vo.setNum((long) size);
                vo.setRate(BigDecimal.valueOf(size).divide(BigDecimal.valueOf(totalNum), 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
                voList.add(vo);
            });

        });
        return voList;
    }

    @Override
    public Page<TroubleRecordLedgerVo> getTroubleRecordLedger(Page page, StatementDto dto) {
        // 查询条件分组 人员 片区 状态 日期范围
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        String regionCodeList = dto.getRegionCodeList();
        String troubleState = dto.getTroubleState();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        QueryWrapper<StatementDto> dtoQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(regionCodeList)) {
            List<String> regionIdList = Arrays.stream(regionCodeList.split(Constant.CSV))
                    .collect(Collectors.toList());
            dtoQueryWrapper.in("p.REGION_ID", regionIdList);
        }
        if (!StringUtils.isEmpty(troubleState)) {
            List<Long> troubleStateList = Arrays.stream(troubleState.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            dtoQueryWrapper.in("p.STATE", troubleStateList);
        }
        dtoQueryWrapper.ge("p.CREATE_TIME", startDate);
        dtoQueryWrapper.le("p.CREATE_TIME", endDate);
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            dtoQueryWrapper.in("p.CREATE_USER", groupUserIdList);
        }

        Page infoPageList = troubleMapper.searchWeeklyPage(page, dtoQueryWrapper);
        // 转换前端显示对象
        infoPageList.setRecords(troubleRecordLedgerViewConversion(infoPageList.getRecords()));
        return infoPageList;
    }

    @Override
    public List<InspectionDayVo> getInspectionDay(StatementDto dto) {
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        List<InspectionDayVo> voList = new ArrayList<>();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            // 获取当前统计的数据 当前用户列表下/对应时间范围
            List<Gpscalculate> gpsCalulateList = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda().in(Gpscalculate::getUserId, groupUserIdList).ge(Gpscalculate::getGpsDate, startDate).lt(Gpscalculate::getGpsDate, endDate));
            // 按天查询
            long aLong = DateTimeUtil.differDays(DateTimeUtil.fromLong2LocalDateTime(startDate.getTime()), DateTimeUtil.fromLong2LocalDateTime(endDate.getTime()));
            Map<String, Map<Long, List<WorkCompletionVo>>> mapMap = new HashMap<>(12);
            for (int i = 0; i < aLong; i++) {

                LocalDateTime beginTime = DateTimeUtil.getAssignTodayBeginTime(DateTimeUtil.fromLong2LocalDateTime(startDate.getTime()));
                LocalDateTime localDateTime = beginTime.plusDays(i);
                Date startTime = DateTimeUtil.convertLDTToDate(localDateTime);
                Date endTime = DateTimeUtil.convertLDTToDate(beginTime.plusDays(i + 1));
                Map<Long, List<WorkCompletionVo>> workCompletion = this.getWorkCompletion(groupUserIdList, startTime, endTime);
                mapMap.put(DateTimeUtil.getLocalDateTime(localDateTime, DateTimeUtil.FULL_FORMAT), workCompletion);
            }


            gpsCalulateList.forEach(info -> {
                InspectionDayVo vo = new InspectionDayVo();
                vo.setDeptName(info.getDeptName());
                vo.setUserName(info.getUserName());
                vo.setInspectionDate(info.getGpsDate());
                vo.setPlanTotalDistance(BigDecimal.valueOf(info.getPlanTotalDistance()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setVaildTotalDistance(info.getVaildTotalDistance());
                vo.setFindTroubleNum(info.getFindTroubleNum());
                vo.setBuildingsitefinded(info.getBuildingsitefinded());
                vo.setPlanNum(info.getPlanNum());
                if (mapMap.size() > 0) {
                    String localDateTime = DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(info.getGpsDate().getTime()), DateTimeUtil.FULL_FORMAT);
                    if (mapMap.containsKey(localDateTime)) {
                        vo.setWorkCompletionVoList(mapMap.get(localDateTime).get(info.getUserId()));
                    }

                }

                voList.add(vo);
            });


            voList.sort(Comparator.comparing(InspectionDayVo::getInspectionDate).reversed());
        }

        return voList;

    }


    @Override
    public List<InspectionMonthVo> getInspectionMonth(StatementDto dto) {
        List<InspectionMonthVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            // 按照月份分组
            Map<String, List<Gpscalculate>> monthDataMap = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda().in(Gpscalculate::getUserId, groupUserIdList).ge(Gpscalculate::getGpsDate, startDate).lt(Gpscalculate::getGpsDate, endDate)).stream().collect(Collectors.groupingBy(g -> DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(g.getGpsDate().getTime()), DateTimeUtil.FULL_MONTH_FORMAT), Collectors.toList()));
            monthDataMap.forEach((k, v) -> {
                // 分组用户
                Map<Long, List<Gpscalculate>> listMap = v.stream().collect(Collectors.groupingBy(Gpscalculate::getUserId, Collectors.toList()));
                // key->用户id key->用户名称
                Map<Long, String> userIdNameMap = v.stream().
                        collect(Collectors.
                                toMap(Gpscalculate::getUserId, Gpscalculate::getUserName, (item1, item2) -> item1));
                Map<Long, String> deptNameMap = v.stream().
                        collect(Collectors.
                                toMap(Gpscalculate::getUserId, Gpscalculate::getDeptName, (item1, item2) -> item1));
                Date gpsDate = v.stream().min(Comparator.comparing(Gpscalculate::getGpsDate)).get().getGpsDate();
                LocalDateTime localDateTime = DateTimeUtil.fromLong2LocalDateTime(gpsDate.getTime());
                LocalDate startMonth = DateTimeUtil.getFirstDayOfCurrentSpecifiedMonth(localDateTime);
                LocalDate endMonth = DateTimeUtil.getLastDayOfCurrentSpecifiedMonth(localDateTime);
                Date startTime = DateTimeUtil.localDateToDate(startMonth);
                Date endTime = DateTimeUtil.localDateToDate(endMonth);
                Map<Long, List<WorkCompletionVo>> workCompletion = this.getWorkCompletion(groupUserIdList, startTime, endTime);

                listMap.forEach((z, x) -> {
                    InspectionMonthVo vo = new InspectionMonthVo();
                    vo.setMonth(k);
                    vo.setDeptName(deptNameMap.get(z));
                    vo.setUserName(userIdNameMap.get(z));
                    vo.setInspectionDateMonth(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(startTime.getTime()), DateTimeUtil.DAY_FORMAT) + " ~ " + DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(endTime.getTime()), DateTimeUtil.DAY_FORMAT));
                    vo.setFindTroubleNum(x.stream().mapToLong(Gpscalculate::getFindTroubleNum).sum());
                    vo.setBuildingsitefinded(x.stream().mapToLong(Gpscalculate::getBuildingsitefinded).sum());
                    vo.setPlanTotalDistance(BigDecimal.valueOf(x.stream().mapToDouble(Gpscalculate::getPlanTotalDistance).sum()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    vo.setVaildSpeed(x.stream().mapToDouble(Gpscalculate::getVaildSpeed).sum());
                    vo.setPlanNum(x.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get().getPlanNum());
                    vo.setWorkCompletionVoList(workCompletion.get(z));

                    voList.add(vo);
                });

            });
            voList.sort(Comparator.comparing(InspectionMonthVo::getMonth).reversed());
        }

        return voList;
    }

    @Override
    public List<InspectionStatisticsVo> getInspectionStatistics(StatementDto dto) {
        List<InspectionStatisticsVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            List<Gpscalculate> gpscalculateList = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda().in(Gpscalculate::getUserId, groupUserIdList).ge(Gpscalculate::getGpsDate, startDate).lt(Gpscalculate::getGpsDate, endDate));
            // 按照用户分组
            Map<Long, List<Gpscalculate>> listMap = gpscalculateList.stream().collect(Collectors.groupingBy(Gpscalculate::getUserId, Collectors.toList()));
            // key->用户id key->用户名称
            Map<Long, String> userIdNameMap = gpscalculateList.stream().
                    collect(Collectors.
                            toMap(Gpscalculate::getUserId, Gpscalculate::getUserName, (item1, item2) -> item1));
            Map<Long, String> deptNameMap = gpscalculateList.stream().
                    collect(Collectors.
                            toMap(Gpscalculate::getUserId, Gpscalculate::getDeptName, (item1, item2) -> item1));
            Map<Long, List<WorkCompletionVo>> workCompletion = this.getWorkCompletion(groupUserIdList, startDate, endDate);
            listMap.forEach((k, v) -> {
                InspectionStatisticsVo vo = new InspectionStatisticsVo();
                List<Groupuser> list = groupuserService.list(new QueryWrapper<Groupuser>().lambda().eq(Groupuser::getUserId, k));
                if (null != list && list.size() > 0) {
                    String groupId = list.get(0).getGroupId();
                    Inspectgroup byId = inspectgroupService.getById(groupId);
                    if (null != byId) {
                        vo.setGroupName(byId.getName());
                    }

                }

                vo.setUserName(userIdNameMap.get(k));
                vo.setDeptName(deptNameMap.get(k));
                vo.setFindTroubleNum(v.stream().mapToLong(Gpscalculate::getFindTroubleNum).sum());
                vo.setBuildingsitefinded(v.stream().mapToLong(Gpscalculate::getBuildingsitefinded).sum());
                vo.setPlanTotalDistance(BigDecimal.valueOf(v.stream().mapToDouble(Gpscalculate::getPlanTotalDistance).sum()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                vo.setVaildSpeed(v.stream().mapToDouble(Gpscalculate::getVaildSpeed).sum());
                vo.setPlanNum(v.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get().getPlanNum());
                vo.setWorkCompletionVoList(workCompletion.get(k));

                voList.add(vo);
            });
        }

        return voList;
    }

    @Override
    public List<AttendanceRecordsVo> getAttendanceRecords(StatementDto dto) {
        List<AttendanceRecordsVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        // 获取当前时间范围内的计划id列表
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            List<Gpscalculate> gpscalculateList = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda().in(Gpscalculate::getUserId, groupUserIdList).ge(Gpscalculate::getGpsDate, startDate).le(Gpscalculate::getGpsDate, endDate));
            Map<Long, List<Gpscalculate>> collect = gpscalculateList.stream().collect(Collectors.groupingBy(Gpscalculate::getUserId));
            // key->用户id key->用户名称
            Map<Long, String> userIdNameMap = gpscalculateList.stream().
                    collect(Collectors.
                            toMap(Gpscalculate::getUserId, Gpscalculate::getUserName, (item1, item2) -> item1));
            Map<Long, String> deptNameMap = gpscalculateList.stream().
                    collect(Collectors.
                            toMap(Gpscalculate::getUserId, Gpscalculate::getDeptName, (item1, item2) -> item1));
            collect.forEach((k, v) -> {
                AttendanceRecordsVo vo = new AttendanceRecordsVo();
                List<Groupuser> list = groupuserService.list(new QueryWrapper<Groupuser>().lambda().eq(Groupuser::getUserId, k));
                if (null != list && list.size() > 0) {
                    String groupId = list.get(0).getGroupId();
                    Inspectgroup byId = inspectgroupService.getById(groupId);
                    if (null != byId) {
                        vo.setGroupName(byId.getName());
                    }

                }
                vo.setUserName(userIdNameMap.get(k));
                vo.setDeptName(deptNameMap.get(k));
                vo.setWorkHours(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(startDate.getTime()), DateTimeUtil.FULL_FORMAT) + " ~ " + DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(endDate.getTime()), DateTimeUtil.FULL_FORMAT));
                vo.setFindTroubleNum(v.stream().mapToLong(Gpscalculate::getFindTroubleNum).sum());
                vo.setBuildingsitefinded(v.stream().mapToLong(Gpscalculate::getBuildingsitefinded).sum());
                vo.setPlanTotalDistance(v.stream().mapToDouble(Gpscalculate::getPlanTotalDistance).sum());
                vo.setVaildSpeed(v.stream().mapToDouble(Gpscalculate::getVaildSpeed).sum());
                vo.setPlanNum(v.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get().getPlanNum());
                long pointpatroled = v.stream().mapToLong(Gpscalculate::getPointpatroled).sum();
                BigDecimal pathpatroled = v.stream().map(Gpscalculate::getPathpatroled).reduce(BigDecimal.ZERO, BigDecimal::add);
                long completeOrderNum = v.stream().mapToLong(Gpscalculate::getCompleteOrderNum).sum();
                long orderNum = v.stream().mapToLong(Gpscalculate::getRepairOrderNum).sum();
                // 获取统计时间最大的数据作为 最新数据

                Gpscalculate gpscalculate = v.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get();
                vo.setInspectNode("" + "计划巡检点个数: " + gpscalculate.getPointinplan() + ",实际巡检点个数: " + pointpatroled + ",计划巡检线长度: " + gpscalculate.getPathinplan() + ",实际巡检线长度: " + pathpatroled);
                vo.setMaintainNode("" + "计划工单个数: " + orderNum + ",实际完成工单个数: " + completeOrderNum);
                voList.add(vo);
            });

            voList.sort(Comparator.comparing(AttendanceRecordsVo::getWorkHours).reversed());


        }

        return voList;
    }

    @Override
    public List<SchedulingVo> getScheduling(StatementDto dto) {
        List<SchedulingVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            // 根据用户列表 时间范围获取统计数据
            List<Gpscalculate> gpscalculateList = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda().
                    in(Gpscalculate::getUserId, groupUserIdList)
                    .ge(Gpscalculate::getGpsDate, startDate)
                    .le(Gpscalculate::getGpsDate, endDate)
                    .isNotNull(Gpscalculate::getUserId));

            Map<Long, List<Gpscalculate>> collect = gpscalculateList.stream().filter(a -> StringUtil.isNotEmpty(a.getUserName())).collect(Collectors.groupingBy(Gpscalculate::getUserId));
            // key->用户id key->用户名称
            Map<Long, String> userIdNameMap = gpscalculateList.stream().
                    collect(Collectors.
                            toMap(Gpscalculate::getUserId, Gpscalculate::getUserName, (item1, item2) -> item1));

            collect.forEach((k, v) -> {
                SchedulingVo vo = new SchedulingVo();
                vo.setTime(DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(startDate.getTime()), DateTimeUtil.FULL_FORMAT) + " ~ " + DateTimeUtil.getLocalDateTime(DateTimeUtil.fromLong2LocalDateTime(endDate.getTime()), DateTimeUtil.FULL_FORMAT));
                vo.setUserName(userIdNameMap.get(k));
                long findNum = v.stream().mapToLong(Gpscalculate::getFindTroubleNum).sum();
                long buNum = v.stream().mapToLong(Gpscalculate::getBuildingsitefinded).sum();
                Gpscalculate gpscalculate = v.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get();
                vo.setNode("" + "计划巡检点个数: " + gpscalculate.getPointinplan() + ",计划巡检线长度: " + gpscalculate.getPathinplan() + ",隐患发现数: " + buNum + ",工地发现数: " + findNum);
                voList.add(vo);
            });
            voList.sort(Comparator.comparing(SchedulingVo::getTime).reversed());
        }

        return voList;
    }

    @Override
    public Page<List<PdaDeviceUpload>> getTerminalRecord(Page page, StatementDto dto, String exportFlag) {
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        EsQueryDto esQueryDto = new EsQueryDto();
        esQueryDto.setStartDate(startDate);
        esQueryDto.setEndDate(endDate);
        esQueryDto.setIsExport(exportFlag);
        StringBuilder stringBuilder = new StringBuilder("");
        userIdList.forEach(info -> {
            stringBuilder.append(info).append(Constant.CSV);
        });
        if (stringBuilder.length() > 0) {
            esQueryDto.setUserIds(stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString());
        }
        return iPdaDeviceService.getPageGpsInfo(page, esQueryDto);
    }

    @Override
    public List<InspectionStatisticsVo> getInspectionStatement(StatementDto dto) {
        String dateType = dto.getDateType();
        // 判断时间类型,(0年,1月,2季)
        List<InspectionStatisticsVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        // 获取查询的用户列表
        Set<Long> groupUserIdList = this.getGroupUserIdList(dto.getDeptId(), dto.getGroupId(), dto.getUserId());
        if (null != groupUserIdList && groupUserIdList.size() > 0) {
            Map<LocalDateTime, LocalDateTime> dateDateMap = new HashMap<>(12);
            // 将日期按照时间类型拆分
            LocalDateTime starTime = DateTimeUtil.fromLong2LocalDateTime(startDate.getTime());
            LocalDateTime endTime = DateTimeUtil.fromLong2LocalDateTime(endDate.getTime());
            if (DateTypeEnum.YEAR.getCode().equals(dateType)) {
                LocalDateTime yearTime = LocalDateTime.of(DateTimeUtil.UDateToLocalDate(startDate).with(TemporalAdjusters.firstDayOfYear()), LocalTime.MIN);
                int starYear = starTime.getYear();
                int endYear = endTime.getYear();
                int y = endYear - starYear;
                for (int i = 0; i <= y; i++) {
                    LocalDateTime localDateTime = yearTime.plusYears(1);
                    dateDateMap.put(yearTime, localDateTime);
                    yearTime = localDateTime;
                }
            } else if (DateTypeEnum.MONTH.getCode().equals(dateType)) {
                LocalDateTime monthTime = LocalDateTime.of(DateTimeUtil.UDateToLocalDate(startDate).with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
                int startMonth = starTime.getMonthValue();
                int endMonth = endTime.getMonthValue();
                int m = endMonth - startMonth;
                for (int i = 0; i <= m; i++) {
                    LocalDateTime localDateTime = monthTime.plusMonths(1);
                    dateDateMap.put(monthTime, localDateTime);
                    monthTime = localDateTime;
                }
            } else if (DateTypeEnum.QUARTER.getCode().equals(dateType)) {
                LocalDateTime quarterStartTime = DateTimeUtil.quarterStartTime(DateTimeUtil.UDateToLocalDate(startDate));
                int startMonth = starTime.getMonthValue();
                int endMonth = endTime.getMonthValue();
                int m = (endMonth - startMonth) / 3;
                for (int i = 0; i <= m; i++) {
                    LocalDateTime localDateTime = quarterStartTime.plusMonths(2);
                    dateDateMap.put(quarterStartTime, localDateTime);
                    quarterStartTime = localDateTime;
                }
            }

            dateDateMap.forEach((s, e) -> {
                Date starConvert = DateTimeUtil.convert(s);
                Date endconvert = DateTimeUtil.convert(e);
                List<Gpscalculate> gpscalculateList = gpscalculateService.list(new QueryWrapper<Gpscalculate>().lambda()
                        .in(Gpscalculate::getUserId, groupUserIdList)
                        .ge(Gpscalculate::getGpsDate, starConvert)
                        .lt(Gpscalculate::getGpsDate, endconvert));
                Map<String, List<Gpscalculate>> collect = new HashMap<>(12);
                if (DateTypeEnum.YEAR.getCode().equals(dateType)) {
                    collect = gpscalculateList.stream().collect(Collectors.groupingBy(g -> DateTimeUtil.getLocalDateTime(
                            DateTimeUtil.fromLong2LocalDateTime(g.getGpsDate().getTime()), DateTimeUtil.YEARS_FORMAT)));
                } else if (DateTypeEnum.QUARTER.getCode().equals(dateType)) {
                    collect = gpscalculateList.stream().collect(Collectors.groupingBy(g -> DateTimeUtil.quarterStartTimeInt(DateTimeUtil.UDateToLocalDate(g.getGpsDate()))));

                } else {
                    collect = gpscalculateList.stream().collect(Collectors.groupingBy(g -> DateTimeUtil.getLocalDateTime(
                            DateTimeUtil.fromLong2LocalDateTime(g.getGpsDate().getTime()), DateTimeUtil.FULL_MONTH_FORMAT)));
                }

                collect.forEach((k, v) -> {
                    // 分组用户
                    Map<Long, List<Gpscalculate>> listMap = v.stream().collect(Collectors.groupingBy(Gpscalculate::getUserId, Collectors.toList()));
                    // key->用户id key->用户名称
                    Map<Long, String> userIdNameMap = v.stream().
                            collect(Collectors.
                                    toMap(Gpscalculate::getUserId, Gpscalculate::getUserName, (item1, item2) -> item1));
                    Map<Long, String> deptNameMap = v.stream().
                            collect(Collectors.
                                    toMap(Gpscalculate::getUserId, Gpscalculate::getDeptName, (item1, item2) -> item1));
                    Map<Long, List<WorkCompletionVo>> workCompletion = this.getWorkCompletion(groupUserIdList, starConvert, endconvert);

                    listMap.forEach((z, x) -> {
                        InspectionStatisticsVo vo = new InspectionStatisticsVo();
                        vo.setStatisticDate(k);
                        vo.setDeptName(deptNameMap.get(k));
                        vo.setUserId(z);
                        vo.setUserName(userIdNameMap.get(z));
                        vo.setFindTroubleNum(x.stream().mapToLong(Gpscalculate::getFindTroubleNum).sum());
                        vo.setBuildingsitefinded(x.stream().mapToLong(Gpscalculate::getBuildingsitefinded).sum());
                        vo.setPlanTotalDistance(BigDecimal.valueOf(x.stream().mapToDouble(Gpscalculate::getPlanTotalDistance).sum()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                        vo.setVaildSpeed(x.stream().mapToDouble(Gpscalculate::getVaildSpeed).sum());
                        vo.setPlanNum(x.stream().max(Comparator.comparing(Gpscalculate::getGpsDate)).get().getPlanNum());
                        vo.setWorkCompletionVoList(workCompletion.get(z));

                        voList.add(vo);
                    });
                });

            });

            voList.sort(Comparator.comparing(InspectionStatisticsVo::getStatisticDate).reversed());
        }

        return voList;
    }

    /**
     * 获取任务执行情况map
     *
     * @param userIds
     * @param stateTime
     * @param endTimeF
     * @return
     */
    private Map<Long, List<WorkCompletionVo>> getWorkCompletion(Set<Long> userIds, Date stateTime, Date endTime) {
        // 数据封装
        Map<Long, List<WorkCompletionVo>> voMap = new HashMap<>(12);
        // 获取满足时间范围的主计划 ,排除巡检计划未作废的数据
        Set<Long> planIdMainList = planService.list(new QueryWrapper<Plan>().lambda()
                .ne(Plan::getPlanState,"10")
                .ge(Plan::getPlanBegindate, stateTime).le(Plan::getPlanEnddate, endTime)
                .or().le(Plan::getPlanBegindate, stateTime).ge(Plan::getPlanEnddate, endTime)).stream().map(Plan::getId).collect(Collectors.toSet());

        if (planIdMainList.size() > 0) {
            // 获取对应用户下的子计划
            List<Planchild> planChildList = planchildService.list(new QueryWrapper<Planchild>().lambda().in(Planchild::getPlanId, planIdMainList).in(Planchild::getRespUser, userIds));
            if (null != planChildList && planChildList.size() > 0) {
                Map<Long, List<Planchild>> collect = planChildList.stream().collect(Collectors.groupingBy(Planchild::getRespUser));
                collect.forEach((e, r) -> {
                    // 获取子计划id列表
                    Set<Long> planChildIdList = r.stream().map(Planchild::getId).collect(Collectors.toSet());
                    Set<Long> planIdList = r.stream().map(Planchild::getPlanId).collect(Collectors.toSet());
                    // 主 类型分组
                    Map<String, List<Plantype>> typeMap = plantypeService.list(new QueryWrapper<Plantype>().lambda().in(Plantype::getPlanId, planIdList)).stream().filter(i -> null != i.getTypeName())
                            .collect(Collectors.groupingBy(item -> item.getTypeId() + "@" + item.getTypeName() + "@" + item.getMaintenanceFlag()));
                    // 子 用户分组
                    Map<Long, List<Planchildtype>> longListMap = planchildtypeService.list(new QueryWrapper<Planchildtype>().lambda().in(Planchildtype::getPlanChildId, planChildIdList)).stream().collect(Collectors.groupingBy(Planchildtype::getUserId));
                    List<WorkCompletionVo> voList = new ArrayList<>();
                    typeMap.forEach((z, x) -> {
                        BigDecimal totalCount = x.stream().map(Plantype::getTotalCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal totalLen = x.stream().map(Plantype::getTotalLength).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal overCount = x.stream().map(Plantype::getOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal overLen = x.stream().map(Plantype::getOverLength).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal totalCountRate = overCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                        BigDecimal totalLenRate = BigDecimal.ZERO;
                        if (null != totalLen && !totalLen.equals(BigDecimal.ZERO)) {
                            totalLenRate = overLen.multiply(BigDecimal.valueOf(100)).divide(totalLen, 2, BigDecimal.ROUND_HALF_UP);
                        }
                        BigDecimal finalTotalLenRate = totalLenRate;
                        WorkCompletionVo vo = new WorkCompletionVo();
                        vo.setTypeName(z);
                        if (z.split("@").length == 3) {
                            vo.setTypeId(Long.valueOf(z.split("@")[0]));
                            vo.setTypeName(z.split("@")[1]);
                            vo.setMaintenanceFlag(z.split("@")[2]);
                        }
                        StringBuilder builder = new StringBuilder("");

                        builder.append("总点数: ")
                                .append(totalCount)
                                .append(",总完成点数: ")
                                .append(overCount)
                                .append(",总点比例: ")
                                .append(totalCountRate)
                                .append("%")

                                .append(",总线长度: ")
                                .append(totalLen)
                                .append(",总完成线长度: ")
                                .append(overLen)
                                .append(",总线比例: ")
                                .append(finalTotalLenRate)
                                .append("%");

                        vo.setTotalCount(totalCount);
                        vo.setTotalOverCount(overCount);
                        vo.setTotalOverCountRate(totalCountRate);
                        vo.setTotalLenth(totalLen);
                        vo.setTotalOverLenth(overLen);
                        vo.setUserOverLenthRate(finalTotalLenRate);
                        List<Planchildtype> planchildtypes = longListMap.get(e);
                        if (null != planchildtypes && planchildtypes.size() > 0) {
                            Map<String, List<Planchildtype>> planChildTypeMap = planchildtypes.stream().filter(i -> null != i.getTypeName()).collect(Collectors.groupingBy(Planchildtype::getTypeName));
                            List<Planchildtype> v = planChildTypeMap.get(z.split("@")[1]);
                            BigDecimal userCount = BigDecimal.ZERO;
                            BigDecimal userLen = BigDecimal.ZERO;

                            if (null != v) {

                                userCount = v.stream().map(Planchildtype::getOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                                userLen = v.stream().map(Planchildtype::getOverLength).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                            }
                            BigDecimal lenRate = BigDecimal.ZERO;
                            if (null != totalLen && !totalLen.equals(BigDecimal.ZERO)) {
                                lenRate = userLen.multiply(BigDecimal.valueOf(100)).divide(totalLen, 2, BigDecimal.ROUND_HALF_UP);
                            }
                            BigDecimal countRate = userCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                            builder.append(",个人完成点个数: ")
                                    .append(userCount)
                                    .append(",个人完成点比例: ")
                                    .append(countRate)
                                    .append("%")
                                    .append(",个人完成线长度: ")
                                    .append(userLen)
                                    .append(",个人完成线比例: ")
                                    .append(lenRate)
                                    .append("%");
                            vo.setUserOverCount(userCount);
                            vo.setUserOverCountRate(countRate);
                            vo.setUserOverLenth(userLen);
                            vo.setUserOverLenthRate(lenRate);
                            vo.setLenRate(lenRate);
                            vo.setPointRate(countRate);
                        }
                        vo.setNode(builder.toString());
                        voList.add(vo);
                    });
                    voMap.put(e, voList);
                });


            }
        }


        return voMap;

    }


    private List<TroubleRecordLedgerVo> troubleRecordLedgerViewConversion(List<TroubleRecordLedgerVo> voList) {
        voList.forEach(info -> {
            // 转换隐患部位 隐患原因 是否进入工地 隐患是否消除 上报人名称
            info.setLocation(TroublePartEnum.getCodeForValue(info.getLocation()));
            String typeId = info.getTroubleTypeId();
            if (!StringUtils.isEmpty(typeId)) {
                info.setTroubleTypeName(toubletypeService.getById(typeId).getName());
            }
            info.setIsBuild(IsBuildEnum.getCodeForValue(info.getIsBuild()));
            info.setIsSuggest(IsBuildEnum.getCodeForValue(info.getIsSuggest()));
            Long submitUser = info.getSubmitUserid();
            if (null != submitUser && 0 != submitUser) {
                User userAudit = userClent.getById(submitUser).getResult();
                if (null != userAudit) {
                    info.setSubmitUserName(userAudit.getRealName());
                }

            }

        });
        return voList;
    }


    /**
     * 根据分组id,用户id (不传则默认当前部门下所有用户)获取查询用户id列表
     *
     * @param deptId
     * @param groupId
     * @param userId
     * @return
     */
    private Set<Long> getGroupUserIdList(String deptId, String groupId, String userId) {
        Set<Long> groupUserIdList = new HashSet<>();

        if (!StringUtils.isEmpty(deptId)) {
            groupUserIdList = departmentClient.getDeptUserList(Long.valueOf(deptId)).getResult().stream().map(User::getId).collect(Collectors.toSet());
        } else if (StringUtils.isEmpty(groupId)) {
            // 当前登录用户部门id
            Long departmentId = SecurityUtils.getUser().getDepartmentId();
            groupUserIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());
        }
        if (!StringUtils.isEmpty(groupId)) {
            groupUserIdList.clear();
            groupUserIdList = groupuserService.list(new QueryWrapper<Groupuser>().lambda().eq(Groupuser::getGroupId, groupId)).stream().map(g -> Long.valueOf(g.getUserId())).collect(Collectors.toSet());
        }
        if (!StringUtils.isEmpty(userId)) {
            groupUserIdList.clear();
            List<Long> ids = Arrays.stream(userId.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            groupUserIdList.addAll(ids);
        }
        return groupUserIdList;
    }

    private Set<Long> getDeptUserIdList(String deptId, String userId) {
        Set<Long> deptUserIdList;
        if (!StringUtils.isEmpty(deptId)) {
            deptUserIdList = departmentClient.getDeptUserList(Long.valueOf(deptId)).getResult().stream().map(User::getId).collect(Collectors.toSet());
        } else {
            // 当前登录用户部门id
            Long departmentId = SecurityUtils.getUser().getDepartmentId();
            deptUserIdList = departmentClient.getDeptUserList(departmentId).getResult().stream().map(User::getId).collect(Collectors.toSet());
        }

        if (!StringUtils.isEmpty(userId)) {
            deptUserIdList.clear();
            List<Long> ids = Arrays.stream(userId.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            deptUserIdList.addAll(ids);
        }
        return deptUserIdList;
    }


    @Override
    public Page<MaintenanceLogLedgerVo> getMaintenanceLogLedger(Page page, StatementDto dto) {
        QueryWrapper<Repairorder> queryWrapper = new QueryWrapper<>();
        String likeSel = dto.getLikeSel();
        String typeId = dto.getTypeId();
        String startBore = dto.getStartBore();
        String endBore = dto.getEndBore();
        if (!StringUtils.isEmpty(typeId)) {
            List<Long> typeIdList = Arrays.stream(typeId.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            queryWrapper.in("a.TYPE_ID", typeIdList);
        }

        queryWrapper.ge("d.CREATE_TIME", dto.getStartDate());
        queryWrapper.lt("d.CREATE_TIME", dto.getEndDate());
        // 处理记录有效,不是保养类型
        queryWrapper.eq("e.FLAG", "1");
        queryWrapper.eq("a.MAINTENANCE_FLAG", "0");
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        queryWrapper.in("a.DISPATCHING_ID", userIdList);

        if (!StringUtils.isEmpty(startBore)) {
            queryWrapper.ge("e.BORE", startBore);
        }
        if (!StringUtils.isEmpty(endBore)) {
            queryWrapper.le("e.BORE", endBore);
        }
        if(StringUtil.isNotEmpty(dto.getOrderCode())){
            queryWrapper.like("a.ORDER_CODE",dto.getOrderCode());
        }
        if(StringUtil.isNotEmpty(dto.getAddress())){
            queryWrapper.like("e.ADDRESS",dto.getAddress());
        }
        if (!StringUtils.isEmpty(likeSel)) {
            queryWrapper.and(r -> r.like("a.ORDER_CODE", likeSel).or()
                    .like("e.ADDRESS", likeSel).or()
                    .like("a.NOTES", likeSel));
//            queryWrapper
//                    .like("a.ORDER_CODE", likeSel).or()
//                    .like("e.ADDRESS", likeSel).or()
//                    .like("a.NOTES", likeSel);
        }
        // 对应时间范围内
        return (Page<MaintenanceLogLedgerVo>) repairtypeMapper.getPageMaintenanceTypeStatisticsInfo(page, queryWrapper);
    }

    @Override
    public Page<MaintenanceMaintainVo> getMaintenanceMaintain(Page page, StatementDto dto) {
        QueryWrapper<Repairorder> queryWrapper = new QueryWrapper<>();
        String likeSel = dto.getLikeSel();
        String typeId = dto.getTypeId();
        String startBore = dto.getStartBore();
        String endBore = dto.getEndBore();
        if (!StringUtils.isEmpty(typeId)) {
            List<Long> typeIdList = Arrays.stream(typeId.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            queryWrapper.in("a.TYPE_ID", typeIdList);
        }
        if(dto.getStartDate()!=null){
           queryWrapper.ge("d.CREATE_TIME", dto.getStartDate());
        }
        if(dto.getEndDate()!=null){
            queryWrapper.lt("d.CREATE_TIME", dto.getEndDate());
        }

        // 处理记录有效,是保养类型
        queryWrapper.eq("e.FLAG", "1");
        queryWrapper.eq("a.MAINTENANCE_FLAG", "1");
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        queryWrapper.in("a.DISPATCHING_ID", userIdList);
        if (!StringUtils.isEmpty(startBore)) {
            queryWrapper.ge("e.FACILITIES_CALIBER", startBore);
        }
        if (!StringUtils.isEmpty(endBore)) {
            queryWrapper.le("e.FACILITIES_CALIBER", endBore);
        }
        if (!StringUtils.isEmpty(likeSel)) {
            queryWrapper
                    .like("a.ORDER_CODE", likeSel).or()
                    .like("a.NOTES", likeSel);
        }
        // 对应时间范围内
        return (Page<MaintenanceMaintainVo>) repairtypeMapper.getMaintenanceMaintain(page, queryWrapper);
    }

    @Override
    public List<MaterialConditionsVo> getMaterialConditions(StatementDto dto) {
        List<MaterialConditionsVo> voList = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        //String productName = dto.getProductName();
        //String specification = dto.getSpecification();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        // 获取抢维修耗材记录列表
        List<Repairgoods> list = repairGoodsService.list(new QueryWrapper<Repairgoods>().lambda()
                .in(Repairgoods::getCreateUser, userIdList)
                .ge(Repairgoods::getCreateTime, startDate)
                .le(Repairgoods::getCreateTime, endDate));
        if (null != list && list.size() > 0) {
            // 按照材料类型id分组
            Map<Long, List<Repairgoods>> collect = list.stream().collect(Collectors.groupingBy(Repairgoods::getMaterialType));
            // 计算出对应id维修材料数量
            Map<Long, Long> goodsTypeNumMap = new HashMap<>(12);
            collect.forEach((k, v) -> {
                long sum = v.stream().mapToLong(Repairgoods::getNum).sum();
                goodsTypeNumMap.put(k, sum);
            });

            // 根据已有材料类型查询维修材料类型信息
            Set<Long> longSet = collect.keySet();
            List<String> productNameList = null;
            List<String> specificationList = null;
            if (CollUtil.isNotEmpty(dto.getProductName())) {
                productNameList = dto.getProductName();
//                Arrays.stream(productName.split(Constant.CSV))
//                        .collect(Collectors.toList());
            }
            if (CollUtil.isNotEmpty(dto.getSpecification())) {
                specificationList = dto.getSpecification();
//                Arrays.stream(specification.split(Constant.CSV))
//                        .collect(Collectors.toList());
            }
            List<Repairmaterial> repairMaterialList = repairmaterialService.list(new QueryWrapper<Repairmaterial>().lambda()
                    .in(Repairmaterial::getId, longSet)
                    .in(null != productNameList, Repairmaterial::getName, productNameList)
                    .in(null != specificationList, Repairmaterial::getSpecification, specificationList));

            // 按照产品名称分组
            Map<String, List<Repairmaterial>> reMap = repairMaterialList.stream().collect(Collectors.groupingBy(Repairmaterial::getName));

            reMap.forEach((k, v) -> {
                MaterialConditionsVo vo = new MaterialConditionsVo();
                vo.setMaterialTypeName(k);
                List<MaterialConditionsChildVo> childVoList = new ArrayList<>();
                v.forEach(i -> {
                    MaterialConditionsChildVo childVo = new MaterialConditionsChildVo();
                    childVo.setSpecification(i.getSpecification());
                    childVo.setUnit(i.getUnit());
                    childVo.setNum(goodsTypeNumMap.get(i.getId()));
                    childVoList.add(childVo);
                });
                vo.setChildVoList(childVoList);
                voList.add(vo);
            });
        }


        return voList;
    }

    @Override
    public List<MaintenanceClassificationVo> getMaintenanceClassification(List<StatementDto> dtoList) {
        List<MaintenanceClassificationVo> voList = new ArrayList<>();
        dtoList.forEach(dto -> {
            // 维修类型
            String typeId = dto.getTypeId();
            Date startDate = dto.getStartDate();
            Date endDate = dto.getEndDate();
            String startBore = dto.getStartBore();
            String endBore = dto.getEndBore();
            MaintenanceClassificationVo vo = new MaintenanceClassificationVo();
            vo.setConditions(repairtypeService.getById(typeId).getName() + "(" + startBore + "-" + endBore + "mm)");
            vo.setOrderNum(0);
            vo.setMfNum(0);
            vo.setStartBore(startBore);
            vo.setEndBore(endBore);
            vo.setTypeId(typeId);
            String userId = dto.getUserId();
            String deptId = dto.getDeptId();
            // 获取用户列表
            Set<Long> deptUserIdList = this.getDeptUserIdList(deptId, userId);
            // 对应维修类型/巡检时间范围
            Set<Long> repairOrderIdList = repairorderService.list(new QueryWrapper<Repairorder>().lambda().in(Repairorder::getDispatchingId, deptUserIdList).ge(Repairorder::getStartTime, startDate).le(Repairorder::getEndTime, endDate).eq(Repairorder::getTypeId, Long.valueOf(typeId))).stream().map(Repairorder::getId).collect(Collectors.toSet());
            if (repairOrderIdList.size() > 0) {
                // 获取对应个人任务id
                Set<Long> userIdList = repairuserService.list(new QueryWrapper<Repairuser>().lambda().in(Repairuser::getRepairId, repairOrderIdList)).stream().map(Repairuser::getId).collect(Collectors.toSet());
                if (userIdList.size() > 0) {
                    // 查询条件->在个人任务id列表中/口径范围
                    List<Repairrecord> list = repairrecordService.list(new QueryWrapper<Repairrecord>().lambda().eq(Repairrecord::getFlag, "1").in(Repairrecord::getRepairUserid, userIdList));
                    if (null != list && list.size() > 0) {
                        AtomicInteger size = new AtomicInteger(0);
                        double s = Double.parseDouble(startBore);
                        double e = Double.parseDouble(endBore);
                        list.forEach(info -> {
                            double i = Double.parseDouble(info.getBore());
                            if (null != info.getBore() && i >= s && i <= e) {
                                size.addAndGet(1);
                            }
                        });
                        vo.setOrderNum(size.get());
                    }
                    // 养护数据 查询条件->在个人任务id列表中/口径范围
                    List<PipeMfRecord> list1 = pipeMfRecordService.list(new QueryWrapper<PipeMfRecord>().lambda().in(PipeMfRecord::getRepairUserId, userIdList));
                    if (null != list1 && list1.size() > 0) {
                        AtomicInteger size = new AtomicInteger(0);
                        double s = Double.parseDouble(startBore);
                        double e = Double.parseDouble(endBore);
                        list1.forEach(info -> {
                            if (null != info.getFacilitiesCaliber()) {
                                double i = Double.parseDouble(info.getFacilitiesCaliber());
                                if (i >= s && i <= e) {
                                    size.addAndGet(1);
                                }
                            }
                        });
                        vo.setMfNum(size.get());
                    }
                }
            }
            voList.add(vo);
        });

        return voList;
    }

    @Override
    public List<PlanDisplayStatisticalVo> getPlanDisplayStatistical(StatementDto dto) {
        // 存放对应用户的统计数据
        List<PlanDisplayStatisticalVo> list = new ArrayList<>();
        Date startDate = dto.getStartDate();
        Date endDate = dto.getEndDate();
        String userId = dto.getUserId();
        String deptId = dto.getDeptId();
        // 获取用户列表
        Set<Long> userIdList = this.getDeptUserIdList(deptId, userId);
        // 获取巡检计划 相关统计内容
        QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryBuildWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryTroubleWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryMaintainWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryOrderOverWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryOrderUndoneWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryQualityTimeScopeWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryQualityzjrzOverWrapper = new QueryWrapper<>();
        QueryWrapper<Plan> queryQualityzjzgOverWrapper = new QueryWrapper<>();
        if (null != startDate && null != endDate) {
            queryWrapper.ge("t1.PLAN_BEGINDATE", startDate).le("t1.PLAN_ENDDATE", endDate).or()
                    .le("t1.PLAN_BEGINDATE", startDate).ge("t1.PLAN_ENDDATE", endDate);
            queryBuildWrapper.ge("CREATE_TIME", startDate).le("CREATE_TIME", endDate);
            queryTroubleWrapper.ge("CREATE_TIME", startDate).le("CREATE_TIME", endDate);
            queryMaintainWrapper.ge("t1.START_TIME", startDate).le("t1.END_TIME", endDate).or()
                    .le("t1.START_TIME", startDate).ge("t1.END_TIME", endDate);
            queryQualityTimeScopeWrapper.ge("DISPATCH_TIME", startDate).le("DISPATCH_TIME", endDate);
        }
        if (userIdList.size() > 0) {
            queryWrapper.in("t2.RESP_USER", userIdList);
            queryBuildWrapper.in("CREATE_USER", userIdList);
            queryTroubleWrapper.in("CREATE_USER", userIdList);
            queryMaintainWrapper.in("t2.RESP_USER", userIdList);
            queryOrderOverWrapper.in("p.userId", userIdList);
            queryOrderUndoneWrapper.in("p.userId", userIdList);
            queryQualityzjrzOverWrapper.in("p.userId", userIdList);
            queryQualityzjzgOverWrapper.in("p.userId", userIdList);
        }
        // 巡检内容
        List<PlanDisplayStatisticalVo> planStatistical = repairtypeMapper.getPlanStatistical(queryWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> planStatisticalMap = planStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));

        // 获取工地 相关统计内容
        List<PlanDisplayStatisticalVo> planBuildStatistical = repairtypeMapper.getPlanBuildStatistical(queryBuildWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> planBuildStatisticalMap = planBuildStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 获取隐患 相关统计内容
        List<PlanDisplayStatisticalVo> planTroubleStatistical = repairtypeMapper.getPlanTroubleStatistical(queryTroubleWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> planTroubleStatisticalMap = planTroubleStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 获取抢维修 相关统计内容
        List<PlanDisplayStatisticalVo> maintainStatistical = repairtypeMapper.getMaintainStatistical(queryMaintainWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> maintainMap = maintainStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 获取业务工单 相关统计内容
        // 分别获取归档工单数 和 未归档工单数
        // 已归档
        queryOrderOverWrapper.eq("p.lcjd", 45);
        List<PlanDisplayStatisticalVo> orderOverStatistical = repairtypeMapper.getOrderStatistical(startDate, endDate, queryOrderOverWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> orderOverStatisticalMap = orderOverStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 未归档
        queryOrderUndoneWrapper.ne("p.lcjd", 45);

        List<PlanDisplayStatisticalVo> orderUndoneStatistical = repairtypeMapper.getOrderStatistical(startDate, endDate, queryOrderUndoneWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> orderUndoneStatisticalMap = orderUndoneStatistical.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 获取质检工单 相关统计内容
        // 1.获取时间范围内的质检工单id列表及大小
        List<Long> qualityIdTimeScopeList = repairtypeMapper.getQualityIdTimeScopeList(queryQualityTimeScopeWrapper);
        // 2.分别获取已归档质检认证数 和 已归档质检整改数
        // 质检认证数 已归档
        queryQualityzjrzOverWrapper.eq("p.CERTIFICATION_STATUS", "3");
        List<PlanDisplayStatisticalVo> qualityOverZlrz = repairtypeMapper.getQualityOverZlrz(startDate, endDate, queryQualityzjrzOverWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> qualityOverZlrzMap = qualityOverZlrz.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 质检整改数 已归档
        queryQualityzjzgOverWrapper.eq("p.VALIDATE_STATUS", "3");
        List<PlanDisplayStatisticalVo> qualityOverZlzg = repairtypeMapper.getQualityOverZlzg(startDate, endDate, queryQualityzjzgOverWrapper);
        Map<Long, List<PlanDisplayStatisticalVo>> qualityOverZlzgMap = qualityOverZlzg.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        // 获取当前时间范围内 用户 实际巡检里程
        Map<Long, BigDecimal> totalMileageUser = new HashMap<>(12);
        StringBuilder stringBuilder = new StringBuilder();
        userIdList.forEach(info -> {
            stringBuilder.append(info).append(Constant.CSV);
        });
        EsQueryDto pram = new EsQueryDto();
        pram.setStartDate(startDate);
        pram.setEndDate(endDate);
        pram.setUserIds(stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString());
        List<GpsUpload> all = iGpsUploadService.getAll(pram);
        // 用户分组
        Map<Long, List<GpsUpload>> collect = all.stream().collect(Collectors.groupingBy(GpsUpload::getUserId));
        collect.forEach((k, v) -> {
            // 计算个人巡检里程
            BigDecimal totalMileage = v.stream().map(GpsUpload::getDistance).reduce(BigDecimal.ZERO, BigDecimal::add).divide(BigDecimal.valueOf(1000), 4, BigDecimal.ROUND_HALF_UP);
            totalMileageUser.put(k, totalMileage);
        });
        // 用户转义
        List<PlanDisplayStatisticalVo> userNameAndDeptNameList = repairtypeMapper.getUserNameAndDeptName();
        Map<Long, List<PlanDisplayStatisticalVo>> userMap = userNameAndDeptNameList.stream().collect(Collectors.groupingBy(PlanDisplayStatisticalVo::getUserId));
        userIdList.forEach(id -> {
            PlanDisplayStatisticalVo vo = new PlanDisplayStatisticalVo();
            BigDecimal zero = BigDecimal.ZERO;
            // 合计相关变量初始化
            BigDecimal sumTotal = zero;
            BigDecimal sumOverNum = zero;
            BigDecimal sumUndoneNum = zero;
            BigDecimal sumOverRate = zero;
            // 用户名称,部门等转义
            PlanDisplayStatisticalVo userDept = userMap.get(id).get(0);
            vo.setUserId(id);
            vo.setUserName(userDept.getUserName());
            vo.setDeptId(userDept.getDeptId());
            vo.setDeptName(userDept.getDeptName());
            // 工地 相关统计赋值
            List<PlanDisplayStatisticalVo> buildList = planBuildStatisticalMap.get(id);
            if (null != buildList && buildList.size() > 0) {
                PlanDisplayStatisticalVo planDisplayStatisticalVo = buildList.get(0);
                BigDecimal buildNum = planDisplayStatisticalVo.getBuildNum();
                vo.setBuildNum(buildNum == null ? zero : buildNum);
            } else {
                vo.setBuildNum(zero);
            }
            // 隐患 相关统计赋值
            List<PlanDisplayStatisticalVo> troubleList = planTroubleStatisticalMap.get(id);
            if (null != troubleList && troubleList.size() > 0) {
                PlanDisplayStatisticalVo planDisplayStatisticalVo = troubleList.get(0);
                BigDecimal troubleNum = planDisplayStatisticalVo.getTroubleNum();
                vo.setTroubleNum(troubleNum == null ? zero : troubleNum);
            } else {
                vo.setTroubleNum(zero);
            }
            // 巡检内容赋值
            List<PlanDisplayStatisticalVo> planVos1 = planStatisticalMap.get(id);
            if (null != planVos1 && planVos1.size() > 0) {
                PlanDisplayStatisticalVo vo1 = planVos1.get(0);
                vo.setPlanTotal(vo1.getPlanTotal());
                vo.setPlanOverNum(vo1.getPlanOverNum());
                vo.setExecuteNum(vo1.getPlanOverNum());
                vo.setPlanUndoneNum(vo1.getPlanUndoneNum());
                vo.setPlanOverRate(vo1.getPlanOverRate());
                sumTotal = sumTotal.add(vo1.getPlanTotal());
                sumOverNum = sumOverNum.add(vo1.getPlanOverNum());
                sumUndoneNum = sumUndoneNum.add(vo1.getPlanUndoneNum());
                // 巡检完成个数大于0 则表示有巡检轨迹
                if (vo1.getPlanOverNum().compareTo(zero) > 0) {
                    BigDecimal totalMileage = totalMileageUser.get(id) == null ? BigDecimal.ZERO : totalMileageUser.get(id);
                    vo.setExecuteMileage(totalMileage);
                } else {
                    vo.setExecuteMileage(zero);
                }
            } else {
                vo.setPlanTotal(zero);
                vo.setPlanOverNum(zero);
                vo.setExecuteNum(zero);
                vo.setPlanUndoneNum(zero);
                vo.setPlanOverRate(zero);
                vo.setExecuteMileage(zero);
            }

            // 抢维修 相关统计赋值
            List<PlanDisplayStatisticalVo> planVos2 = maintainMap.get(id);
            if (null != planVos2 && planVos2.size() > 0) {
                PlanDisplayStatisticalVo vo2 = planVos2.get(0);
                vo.setRepairTotal(vo2.getRepairTotal());
                vo.setRepairOverNum(vo2.getRepairOverNum());
                vo.setRepairUndoneNum(vo2.getRepairUndoneNum());
                vo.setRepairOverRate(vo2.getRepairOverRate());
                sumTotal = sumTotal.add(vo2.getRepairTotal());
                sumOverNum = sumOverNum.add(vo2.getRepairOverNum());
                sumUndoneNum = sumUndoneNum.add(vo2.getRepairUndoneNum());
            } else {
                vo.setRepairTotal(zero);
                vo.setRepairOverNum(zero);
                vo.setRepairUndoneNum(zero);
                vo.setRepairOverRate(zero);
                sumTotal = sumTotal.add(zero);
            }
            // 业务工单 相关统计赋值
            BigDecimal orderOverNum = zero;
            BigDecimal orderUndoneNum = zero;
            List<PlanDisplayStatisticalVo> orderOverList = orderOverStatisticalMap.get(id);
            if (null != orderOverList && orderOverList.size() > 0) {
                PlanDisplayStatisticalVo orderOver = orderOverList.get(0);
                orderOverNum = orderOver.getOrderOverNum();
            }
            List<PlanDisplayStatisticalVo> orderUndoneList = orderUndoneStatisticalMap.get(id);
            if (null != orderUndoneList && orderUndoneList.size() > 0) {
                PlanDisplayStatisticalVo orderUndone = orderUndoneList.get(0);
                // sql 同一个值赋值
                orderUndoneNum = orderUndone.getOrderOverNum();
            }
            vo.setOrderOverNum(orderOverNum);
            vo.setOrderUndoneNum(orderUndoneNum);
            BigDecimal orderTotal = orderOverNum.add(orderUndoneNum);
            vo.setOrderTotal(orderTotal);
            if (0 == orderOverNum.compareTo(zero)) {
                vo.setOrderOverRate(zero);
            } else {
                vo.setOrderOverRate(orderOverNum.divide(orderTotal, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100L)));
            }

            sumTotal = sumTotal.add(orderTotal);
            sumOverNum = sumOverNum.add(orderOverNum);
            sumUndoneNum = sumUndoneNum.add(orderUndoneNum);
            // 质量工单 相关统计赋值
            int size = qualityIdTimeScopeList.size();
            if (size > 0) {
                BigDecimal qualityOverZlrzNum = zero;
                BigDecimal qualityOverZlzgNum = zero;
                List<PlanDisplayStatisticalVo> qualityOverZlrzList = qualityOverZlrzMap.get(id);
                if (null != qualityOverZlrzList && qualityOverZlrzList.size() > 0) {
                    PlanDisplayStatisticalVo overZlrz = qualityOverZlrzList.get(0);
                    qualityOverZlrzNum = overZlrz.getQualityOverNum();
                }
                List<PlanDisplayStatisticalVo> qualityOverZlzgList = qualityOverZlzgMap.get(id);
                if (null != qualityOverZlzgList && qualityOverZlzgList.size() > 0) {
                    PlanDisplayStatisticalVo overZlzg = qualityOverZlzgList.get(0);
                    // sql 同一个值赋值
                    qualityOverZlzgNum = overZlzg.getQualityOverNum();
                }
                BigDecimal qualityTotal = BigDecimal.valueOf(size);
                vo.setQualityTotal(qualityTotal);
                BigDecimal add = qualityOverZlrzNum.add(qualityOverZlzgNum);
                vo.setQualityOverNum(add);
                BigDecimal subtract = qualityTotal.subtract(add);
                vo.setQualityUndoneNum(subtract);
                if (0 == zero.compareTo(add)) {
                    vo.setQualityOverRate(zero);
                } else {
                    vo.setQualityOverRate(add.divide(qualityTotal, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100L)));
                }
                sumTotal = sumTotal.add(qualityTotal);
                sumOverNum = sumOverNum.add(add);
                sumUndoneNum = sumUndoneNum.add(subtract);
            } else {
                vo.setQualityTotal(zero);
                vo.setQualityOverNum(zero);
                vo.setQualityUndoneNum(zero);
                vo.setQualityOverRate(zero);
            }
            if (sumOverNum.compareTo(zero) > 0) {
                sumOverRate = sumOverNum.divide(sumTotal, 4, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100L));
            }

            vo.setSumTotal(sumTotal);
            vo.setSumOverNum(sumOverNum);
            vo.setSumUndoneNum(sumUndoneNum);
            vo.setSumOverRate(sumOverRate);
            list.add(vo);
        });

        return list;
    }

    @Override
    public Object getRepairOrderStatement(String startMonth, String endMonth) {
        List<String> listDate= CalendarHelper.getMonthBetweenDate(startMonth,endMonth,"");
        List<Map<String,Object>> list=new ArrayList<>();
        listDate.forEach(yearAndMonth->{
            Map<String,Object> map=repairorderService.getRepairOrderReport(yearAndMonth);
            if(map==null){
                map=new HashMap<>();
                map.put("finishNum",null);
                map.put("dealNum",null);
                map.put("totalNum",null);
            }
            map.put("month",yearAndMonth);
            list.add(map);
        });
        return list;
    }

    @Override
    public Object getPlanReportStatement(String startMonth, String endMonth) {
        List<String> listDate= CalendarHelper.getMonthBetweenDate(startMonth,endMonth,"");
        List<Map<String,Object>> list=new ArrayList<>();
        listDate.forEach(yearAndMonth->{
            Map<String,Object> map=planService.getPlanPipeReportStatement(yearAndMonth);

            if(map==null){
                map=new HashMap<>();
                map.put("overLength",null);
                map.put("totalLength",null);
            }
            map.put("month",yearAndMonth);
            list.add(map);
        });
        return list;
    }

    @Override
    public Object getPlanDeviceReportStatement(Integer month) {
        return planService.getPlanDeviceReportStatement(month);
    }

    @Override
    public Object getPlanReginReportStatement(String reginIds) {
        return planService.getPlanReginReportStatement(reginIds);
    }

}
