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

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.oauth.util.SecurityUtils;
import com.tofly.es.PdaDeviceUpload;
import com.tofly.es.dto.EsQueryDto;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.system.IsBuildEnum;
import com.tofly.gpsboot.common.system.OrderStateEnum;
import com.tofly.gpsboot.common.system.TroublePartEnum;
import com.tofly.gpsboot.mapper.maintain.RepairtypeMapper;
import com.tofly.gpsboot.mapper.trouble.TroubleMapper;
import com.tofly.gpsboot.service.build.BuildService;
import com.tofly.gpsboot.service.config.InspectgroupService;
import com.tofly.gpsboot.service.es.IPdaDeviceService;
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.PlanchildtypeService;
import com.tofly.gpsboot.service.paln.PlantypeService;
import com.tofly.gpsboot.service.paln.task.PlanFactoryService;
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.plan.vo.PlanUserNumStatisticalVo;
import com.tofly.pojo.statement.dto.InspectionStatementDto;
import com.tofly.pojo.statement.dto.StatementDto;
import com.tofly.pojo.statement.vo.*;
import com.tofly.pojo.trouble.Toubleplan;
import com.tofly.pojo.trouble.Trouble;
import com.tofly.pojo.trouble.vo.TroubleVo;
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.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 BuildService buildService;

    @Autowired
    private RepairrecordService repairrecordService;

    @Autowired
    private RepairgoodsService repairGoodsService;

    @Autowired
    private RepairmaterialService repairmaterialService;

    @Autowired
    private RepairtypeMapper repairtypeMapper;

    @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 PipeMfRecordService pipeMfRecordService;
    @Autowired
    private PlantypeService plantypeService;
    @Autowired
    private PlanchildtypeService planchildtypeService;
    @Autowired
    private PlanFactoryService planFactoryService;

    @Override
    public Page<MaintenancePlanVo> getMaintenanceStatisticsPlan(Page page, InspectionStatementDto dto) {
        return planFactoryService.getMaintenanceStatisticsPlan(page,dto);
    }

    @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);
            list.forEach(info -> {
                userMap.put(info.getRespUser(), info.getRespUserName());
            });
            map.forEach((k, v) -> {
                MaintenanceWorkVo vo = new MaintenanceWorkVo();
                vo.setUserName(userMap.get(k));
                vo.setRepairOrderNum(v.stream().mapToLong(Repairuser::getPlanNum).sum());
                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<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));
            // 排除终止抢维修工单
            List<Repairorder> collect = repairOrderList.stream().filter(i -> null != i.getOverTime()).collect(Collectors.toList());
            // 类型id - 月份+数量
            Map<Long, Map<String, Long>> longMapMap = collect.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 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 (!StringUtils.isEmpty(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);
        }

        queryWrapper.ge("d.CREATE_TIME", dto.getStartDate());
        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<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;
    }

    @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 (!StringUtils.isEmpty(productName)) {
                productNameList = Arrays.stream(productName.split(Constant.CSV))
                        .collect(Collectors.toList());
            }
            if (!StringUtils.isEmpty(specification)) {
                specificationList = 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().in(Repairrecord::getRepairUserid, userIdList));
                    if (null != list && list.size() > 0) {
                        AtomicInteger size = new AtomicInteger(0);
                        long s = Long.parseLong(startBore);
                        long e = Long.parseLong(endBore);
                        list.forEach(info -> {
                            long i = Long.parseLong(info.getBore());
                            if (null != info.getBore() && i >= s && i <= e) {
                                size.getAndSet(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);
                        long s = Long.parseLong(startBore);
                        long e = Long.parseLong(endBore);
                        list1.forEach(info -> {
                            if (null != info.getFacilitiesCaliber()) {
                                long i = Long.parseLong(info.getFacilitiesCaliber());
                                if (i >= s && i <= e) {
                                    size.getAndSet(1);
                                }
                            }
                        });
                        vo.setMfNum(size.get());
                    }
                }
            }
            voList.add(vo);
        });

        return voList;
    }

    @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<TroubleVo> troubleVoList = troubleService.viewConversion(troubleService.list(dtoQueryWrapper));
        if (null != troubleVoList && troubleVoList.size() > 0) {
            // 根据隐患类型分组对应数量
            Map<String, Long> counting = troubleVoList.stream()
                    .collect(Collectors.groupingBy(TroubleVo::getTypeName, 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<TroubleVo> troubleVoList = troubleService.viewConversion(troubleService.list(dtoQueryWrapper));

        Map<String, List<TroubleVo>> 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<TroubleVo>> stringListMap = v.stream().collect(Collectors.groupingBy(TroubleVo::getTypeName, 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(localDateTime.plusDays(i + 1));
                Date endTime = DateTimeUtil.convertLDTToDate(DateTimeUtil.getAssignTodayEndTime(localDateTime));
                Map<Long, List<WorkCompletionVo>> workCompletion = this.getWorkCompletion(groupUserIdList, startTime, endTime);
                mapMap.put(DateTimeUtil.getLocalDateTime(localDateTime, DateTimeUtil.FULL_FORMAT), workCompletion);
            }
            // 获取各用户时间范围内执行的巡检计划数量
            Map<Long, Long> userPlanMap = repairtypeMapper.getUserPlanNumMap(startDate, endDate).stream().
                    collect(Collectors.
                            toMap(PlanUserNumStatisticalVo::getUserId, PlanUserNumStatisticalVo::getPlanNum, (item1, item2) -> item1));

            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(userPlanMap.get(info.getUserId()));
                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);
                // 获取各用户时间范围内执行的巡检计划数量
                Map<Long, Long> userPlanMap = repairtypeMapper.getUserPlanNumMap(startTime, endTime).stream().
                        collect(Collectors.
                                toMap(PlanUserNumStatisticalVo::getUserId, PlanUserNumStatisticalVo::getPlanNum, (item1, item2) -> item1));
                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(userPlanMap.get(z));
                    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);
            // 获取各用户时间范围内执行的巡检计划数量
            Map<Long, Long> userPlanMap = repairtypeMapper.getUserPlanNumMap(startDate, endDate).stream().
                    collect(Collectors.
                            toMap(PlanUserNumStatisticalVo::getUserId, PlanUserNumStatisticalVo::getPlanNum, (item1, item2) -> item1));
            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(userPlanMap.get(k));
                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));

            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.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());
                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));
            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));

            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) {
        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);
        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);
    }

    /**
     * 获取任务执行情况map
     *
     * @param userIds
     * @param stateTime
     * @param endTime
     * @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()
                .between(Plan::getPlanBegindate,stateTime,endTime)
                .between(Plan::getPlanBegindate, stateTime,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(Plantype::getTypeName));
                    // 子 用户分组
                    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.divide(totalCount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                        BigDecimal totalLenRate = BigDecimal.ZERO;
                        if (null != totalLen && !totalLen.equals(BigDecimal.ZERO) && totalLen.doubleValue() != 0) {
                            totalLenRate = overLen.divide(totalLen, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                        }
                        BigDecimal finalTotalLenRate = totalLenRate;
                        WorkCompletionVo vo = new WorkCompletionVo();
                        vo.setTypeName(z);
                        StringBuilder builder = new StringBuilder("");
                        builder.append("总点数: ")
                                .append(totalCount)
                                .append(",总长度: ")
                                .append(totalLen)
                                .append(",总完成点个数: ")
                                .append(overCount)
                                .append(",总完成线长度: ")
                                .append(overLen)
                                .append(",总完成率: ")
                                .append(totalCountRate)
                                .append("%")
                                .append(",总线比例: ")
                                .append(finalTotalLenRate)
                                .append("%");
                        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);
                            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) && totalLen.doubleValue() != 0) {
                                lenRate = userLen.divide(totalLen, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                            }
                            BigDecimal countRate = userCount.divide(totalCount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
                            builder.append(",个人完成点个数: ")
                                    .append(userCount)
                                    .append(",个人完成线长度: ")
                                    .append(userLen)
                                    .append(",个人完成率: ")
                                    .append(countRate)
                                    .append("%")
                                    .append(",个人线比例: ")
                                    .append(lenRate)
                                    .append("%");
                            vo.setLenRate(countRate);
                            vo.setPointRate(lenRate);
                        }
                        vo.setNode(builder.toString());
                        voList.add(vo);
                    });
                    voMap.put(e,voList);
                });


            }
        }


        return voMap;

    }

    private void senMonthStatisticsUserOver(List<WorkCompletionVo> voList, Map<Long, List<Pointtemp>> tempMap, Map<Long, Plan> planGroupPlanIdList) {
        List<InspectionMonthChildVo> list = new ArrayList<>();
        tempMap.forEach((k, v) -> {
            // 获取当前计划的信息
            Plan plan = planGroupPlanIdList.get(k);
            InspectionMonthChildVo childVo = new InspectionMonthChildVo();
            // 赋值当前静态数据
            childVo.setPlanId(plan.getId());
            childVo.setTotalCount(plan.getTotalCount());
            childVo.setTotalLength(plan.getTotalLength());
            AtomicReference<BigDecimal> overLen = new AtomicReference<>(BigDecimal.ZERO);
            v.forEach(pointTemp -> {
                overLen.getAndSet(pointTemp.getPipeLength() == null ? BigDecimal.ZERO : pointTemp.getPipeLength());
            });
            childVo.setOverCount(BigDecimal.valueOf(v.size()));
            childVo.setOverLength(overLen.get());
            list.add(childVo);
        });
        list.forEach(child -> {
            WorkCompletionVo vo = new WorkCompletionVo();
            AtomicReference<BigDecimal> totalCount = new AtomicReference<>(BigDecimal.ZERO);
            AtomicReference<BigDecimal> totalLen = new AtomicReference<>(BigDecimal.ZERO);
            AtomicReference<BigDecimal> overCount = new AtomicReference<>(BigDecimal.ZERO);
            AtomicReference<BigDecimal> overLen = new AtomicReference<>(BigDecimal.ZERO);
            BigDecimal countRate = BigDecimal.ZERO;
            BigDecimal lenRate = BigDecimal.ZERO;
            totalCount.getAndSet(child.getTotalCount());
            totalLen.getAndSet(child.getTotalLength());
            overCount.getAndSet(child.getOverCount());
            overLen.getAndSet(child.getOverLength());
            if (totalCount.get().compareTo(BigDecimal.ZERO) > 0) {
                countRate = overCount.get().divide(totalCount.get(), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
            }
            if (totalLen.get().compareTo(BigDecimal.ZERO) > 0) {
                lenRate = overLen.get().divide(totalLen.get(), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100));
            }

            vo.setNode("" + "总点数: " + totalCount.get() + ",总长度: " + totalLen.get() + ",完成率" + countRate + ",完成点数 " + overCount.get() + ",完成长度: " + overLen.get());
            vo.setPointRate(countRate);
            vo.setLenRate(lenRate);
            voList.add(vo);
        });
    }

    /**
     * 计算当前计划下今天完成的个数及线长度
     *
     * @param pointTempList
     * @param planchild
     * @param builder
     */
    private void senDayUserOver(List<Pointtemp> pointTempList, Planchild planchild, StringBuilder builder) {
        // 当日个人巡检完成线长度/当日个人巡检完成点个数
        AtomicReference<BigDecimal> overCount = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> overLen = new AtomicReference<>(BigDecimal.ZERO);
        // 获取当前子巡检完成的点列表
        String overIds = planchild.getOverIds();
        if (!StringUtils.isEmpty(overIds)) {
            List<Long> longList = Arrays.stream(overIds.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            pointTempList.forEach(info -> {
                if (longList.contains(info.getId())) {
                    overCount.getAndSet(BigDecimal.ONE);
                    overLen.getAndSet(info.getPipeLength() == null ? BigDecimal.ZERO : info.getPipeLength());
                }
            });
        }
        builder.append(",当日个人巡检完成点个数: ").append(overCount.get()).append(",当日个人巡检完成线长度: ").append(overLen.get());
    }

    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(deptId).getResult().stream().map(User::getId).collect(Collectors.toSet());
        } else if (StringUtils.isEmpty(groupId)) {
            // 当前登录用户部门id
            Long departmentId = SecurityUtils.getUser().getDepartmentId();
            groupUserIdList = departmentClient.getDeptUserList(String.valueOf(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(deptId).getResult().stream().map(User::getId).collect(Collectors.toSet());
        } else {
            // 当前登录用户部门id
            Long departmentId = SecurityUtils.getUser().getDepartmentId();
            deptUserIdList = departmentClient.getDeptUserList(String.valueOf(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;
    }

    /**
     * 获取用户巡检计划数量
     *
     * @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()));
    }

}
