package com.tofly.gpsboot.controller.statement;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.common.log.annotation.ToFlyAppLog;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.es.PdaDeviceUpload;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.common.business.ExcelExportFileTypeEnum;
import com.tofly.gpsboot.service.comm.StatementAssessService;
import com.tofly.gpsboot.util.ExcelUtil;
import com.tofly.pojo.emergency.EmergencyType;
import com.tofly.pojo.plan.Planchild;
import com.tofly.pojo.plan.Plantype;
import com.tofly.pojo.statement.StatementAssess;
import com.tofly.pojo.statement.dto.InspectionStatisticsDto;
import com.tofly.pojo.statement.dto.MaintenanceClassificationDto;
import com.tofly.pojo.statement.dto.StatementDto;
import com.tofly.pojo.statement.vo.*;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.service.statement.IStatementService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报表接口信息
 *
 * @author admin
 * @date Thu Mar 18 00:00:00 CST 2021
 */
@RestController
@RequestMapping("/statement")
@Api(tags = "报表接口信息")
@Slf4j
public class StatementController {
    @Autowired
    private IStatementService iStatementService;

    @Autowired
    private StatementAssessService statementAssessService;

    @ApiOperation(value = "获取人员工时统计信息")
    @PostMapping("/getMaintenanceWork")
    @ToFlyAppLog(title = "获取人员工时统计信息")
    public ResultRespone<Object> getMaintenanceWork(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<MaintenanceWorkVo> maintenanceWork = iStatementService.getMaintenanceWork(dto);
            rest.setResult(maintenanceWork);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @ApiOperation(value = "获取管网设施维护情况")
    @PostMapping("/getMaintenanceStatistics")
    @ToFlyAppLog(title = "获取管网设施维护情况")
    public ResultRespone<Object> getMaintenanceStatistics(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<MaintenanceStatisticsVo> maintenanceStatistics = iStatementService.getMaintenanceStatistics(dto);
            rest.setResult(maintenanceStatistics);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @ApiOperation(value = "获取维修记录台账数据")
    @PostMapping("/getMaintenanceLogLedger")
    @ToFlyAppLog(title = "获取维修记录台账数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportFlag", value = "不导出不传值,导出传1", dataType = "String"),
    })
    public ResultRespone<Page<MaintenanceLogLedgerVo>> getMaintenanceLogLedger(HttpServletResponse response, Page page, @ModelAttribute StatementDto dto, String exportFlag) {
        ResultRespone<Page<MaintenanceLogLedgerVo>> rest = new ResultRespone<>();
        try {
            Page<MaintenanceLogLedgerVo> maintenanceLogLedger = iStatementService.getMaintenanceLogLedger(page, dto);
            if(!StringUtils.isEmpty(exportFlag)){
                //将查询的结果转json字符串的格式，因为导出的时候只能传一个字符串
                // 从模型类型枚举根据templateServiceType获取策略对应模板数据
                Map<String, Object> dataMap = new HashMap<>(12);
                dataMap.put("list", maintenanceLogLedger.getRecords());
                ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.getExcelExportFileTypeEnum("statementService", "0");
                ExcelUtil.export(dataMap, excelExportFileTypeEnum, Constant.FILE_PATH_TEST_EXPORT_EXCEL, response);
                return null;
            }else {
                rest.setResult(maintenanceLogLedger);
            }

        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @ApiOperation(value = "获取维修保养记录台账数据")
    @PostMapping("/getMaintenanceMaintain")
    @ToFlyAppLog(title = "获取维修保养记录台账数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportFlag", value = "不导出不传值,导出传1", dataType = "String"),
    })
    public ResultRespone<Page<MaintenanceMaintainVo>> getMaintenanceMaintain(HttpServletResponse response,Page page, @ModelAttribute StatementDto dto, String exportFlag) {
        ResultRespone<Page<MaintenanceMaintainVo>> rest = new ResultRespone<>();
        try {
            Page<MaintenanceMaintainVo> maintenanceLogLedger = iStatementService.getMaintenanceMaintain(page, dto);
            if(!StringUtils.isEmpty(exportFlag)){
                //将查询的结果转json字符串的格式，因为导出的时候只能传一个字符串
                // 从模型类型枚举根据templateServiceType获取策略对应模板数据
                Map<String, Object> dataMap = new HashMap<>(12);
                dataMap.put("list", maintenanceLogLedger.getRecords());
                ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.getExcelExportFileTypeEnum("statementService", "1");
                ExcelUtil.export(dataMap, excelExportFileTypeEnum, Constant.FILE_PATH_TEST_EXPORT_EXCEL, response);
                return null;
            }else {
                rest.setResult(maintenanceLogLedger);
            }
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }



    @ApiOperation(value = "获取维修类型统计")
    @PostMapping("/getMaintenanceTypeStatistics")
    @ToFlyAppLog(title = "获取维修类型统计")
    public ResultRespone<Object> getMaintenanceTypeStatistics(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<MaintenanceTypeStatisticsVo> maintenanceTypeStatistics = iStatementService.getMaintenanceTypeStatistics(dto);
            rest.setResult(maintenanceTypeStatistics);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }

    @ApiOperation(value = "获取耗材情况")
    @PostMapping("/getMaterialConditions")
    @ToFlyAppLog(title = "获取耗材情况")
    public ResultRespone<Object> getMaterialConditions(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<MaterialConditionsVo> materialConditions = iStatementService.getMaterialConditions(dto);
            rest.setResult(materialConditions);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @ApiOperation(value = "维护分类统计")
    @PostMapping("/getMaintenanceClassification")
    @ToFlyAppLog(title = "维护分类统计")
    public ResultRespone<Object> getMaintenanceClassification(@RequestBody MaintenanceClassificationDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<MaintenanceClassificationVo> maintenanceClassification = iStatementService.getMaintenanceClassification(dto.getDtoList());
            rest.setResult(maintenanceClassification);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @ApiOperation(value = "隐患类型分析")
    @PostMapping("/getTroubleTypeAnalysis")
    @ToFlyAppLog(title = "隐患类型分析")
    public ResultRespone<Object> getTroubleTypeAnalysis(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<TroubleTypeAnalysisVo> troubleTypeAnalysis = iStatementService.getTroubleTypeAnalysis(dto);
            rest.setResult(troubleTypeAnalysis);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "隐患原因分析")
    @PostMapping("/getTroubleCause")
    @ToFlyAppLog(title = "隐患原因分析")
    public ResultRespone<Object> getTroubleCause(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<TroubleCauseVo> troubleCause = iStatementService.getTroubleCause(dto);
            rest.setResult(troubleCause);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "隐患趋势分析")
    @PostMapping("/getTroubleTrendAnalysis")
    @ToFlyAppLog(title = "隐患趋势分析")
    public ResultRespone<Object> getTroubleTrendAnalysis(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<TroubleTrendAnalysisVo> troubleTrendAnalysis = iStatementService.getTroubleTrendAnalysis(dto);
            rest.setResult(troubleTrendAnalysis);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }

    @ApiOperation(value = "隐患记录台账")
    @PostMapping("/getTroubleRecordLedger")
    @ToFlyAppLog(title = "隐患记录台账")
    public ResultRespone<Page> getTroubleRecordLedger(Page page, @ModelAttribute StatementDto dto) {
        ResultRespone<Page> rest = new ResultRespone<>();
        try {
            Page troubleRecordLedger = iStatementService.getTroubleRecordLedger(page, dto);
            rest.setResult(troubleRecordLedger);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "获取巡检日报")
    @PostMapping("/getInspectionDay")
    @ToFlyAppLog(title = "获取巡检日报")
    public ResultRespone<Object> getInspectionDay(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<InspectionDayVo> inspectionDay = iStatementService.getInspectionDay(dto);
            rest.setResult(inspectionDay);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "获取巡检月报")
    @PostMapping("/getInspectionMonth")
    @ToFlyAppLog(title = "获取巡检月报")
    public ResultRespone<Object> getInspectionMonth(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<InspectionMonthVo> inspectionMonth = iStatementService.getInspectionMonth(dto);
            rest.setResult(inspectionMonth);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "获取巡检统计")
    @PostMapping("/getInspectionStatistics")
    @ToFlyAppLog(title = "获取巡检统计")
    public ResultRespone<Object> getInspectionStatistics(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<InspectionStatisticsVo> inspectionStatistics = iStatementService.getInspectionStatistics(dto);
            rest.setResult(inspectionStatistics);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "考勤记录")
    @PostMapping("/getAttendanceRecords")
    @ToFlyAppLog(title = "考勤记录")
    public ResultRespone<Object> getAttendanceRecords(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<AttendanceRecordsVo> attendanceRecords = iStatementService.getAttendanceRecords(dto);
            rest.setResult(attendanceRecords);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }

    @ApiOperation(value = "排班计划")
    @PostMapping("/getScheduling")
    @ToFlyAppLog(title = "排班计划")
    public ResultRespone<Object> getScheduling(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<SchedulingVo> scheduling = iStatementService.getScheduling(dto);
            rest.setResult(scheduling);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }
    @ApiOperation(value = "获取终端记录台账")
    @PostMapping("/getTerminalRecord")
    @ToFlyAppLog(title = "获取终端记录台账")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "exportFlag", value = "不导出不传值,导出传1", dataType = "String"),
    })
    public ResultRespone<Page<List<PdaDeviceUpload>>> getTerminalRecord(HttpServletResponse response, Page page, @ModelAttribute StatementDto dto, String exportFlag) {
        ResultRespone<Page<List<PdaDeviceUpload>>> rest = new ResultRespone<>();
        try {
            //导出时采用升序排序导出
            Page<List<PdaDeviceUpload>> terminalRecord = iStatementService.getTerminalRecord(page, dto, exportFlag);
            if(!StringUtils.isEmpty(exportFlag)){
                //将查询的结果转json字符串的格式，因为导出的时候只能传一个字符串
                // 从模型类型枚举根据templateServiceType获取策略对应模板数据
                Map<String, Object> dataMap = new HashMap<>(12);
                dataMap.put("list", terminalRecord.getRecords());
                ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.getExcelExportFileTypeEnum("statementService", "2");
                ExcelUtil.export(dataMap, excelExportFileTypeEnum, Constant.FILE_PATH_TEST_EXPORT_EXCEL, response);
                return null;
            }else {
                rest.setResult(terminalRecord);
            }
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }


    @GetMapping("/assessPage" )
    @ApiOperation(value = "报表考核分页查询")
    public ResultRespone getAssessPage(Page page, @ModelAttribute StatementAssess statementAssess) {
        return ResultRespone.success(statementAssessService.page(page, Wrappers.query(statementAssess)));
    }
    @ApiOperation(value = "报表考核")
    @PostMapping("/addAssess")
    @ToFlyAppLog(title = "报表考核")
    @Transactional(rollbackFor = Exception.class)
    public ResultRespone<Object> addAssess(@RequestBody InspectionStatisticsDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            Long statisticalUserId = dto.getStatisticalUserId();
            String type = dto.getType();
            String year = dto.getYear();
            String quarter = dto.getQuarter();
            String month = dto.getMonth();
            Long user = null == dto.getAssessUserId() ? SecurityUtils.getUserId() : dto.getAssessUserId();
            // 查询是否存在该考核内容, 存在则删除
            List<StatementAssess> list = statementAssessService.list(new QueryWrapper<StatementAssess>().lambda()
                    .eq(StatementAssess::getType, type)
                    .eq(!StringUtils.isEmpty(year), StatementAssess::getYear, year)
                    .eq(!StringUtils.isEmpty(quarter), StatementAssess::getQuarter, quarter)
                    .eq(!StringUtils.isEmpty(month), StatementAssess::getMonth, month)
                    .eq(StatementAssess::getStatisticalUserId, statisticalUserId));
            if(null!=list && list.size()>0){
                Set<Long> collect = list.stream().map(StatementAssess::getId).collect(Collectors.toSet());
                statementAssessService.removeByIds(collect);
            }
            List<InspectionStatisticsVo> voList = dto.getVoList();
            voList.forEach(info->{

                StatementAssess vo = new StatementAssess();
                vo.setStatisticalUserId(statisticalUserId);

                vo.setType(type);
                vo.setYear(year);
                vo.setQuarter(quarter);
                vo.setMonth(month);
                vo.setAssessUserId(user);
                vo.setAssessTime(null==dto.getAssessTime()?new Date():dto.getAssessTime());
                vo.setAssessNote(dto.getAssessNote());
                vo.setAssessScore(dto.getAssessScore());
                vo.setVaildSpeed(BigDecimal.valueOf(info.getVaildSpeed()));
                vo.setFindTroubleNum(info.getFindTroubleNum());
                vo.setBuildingsitefinded(info.getBuildingsitefinded());
                vo.setPlanNum(info.getPlanNum());
                vo.setTotalLenth(BigDecimal.valueOf(info.getPlanTotalDistance()));
                vo.setTotalOverLenth(BigDecimal.valueOf(info.getPlanTotalDistance()));
                List<WorkCompletionVo> workCompletionVoList = info.getWorkCompletionVoList();
                //区分巡检和保养；
                //0表示巡线，1表示设备维护
                //巡线完成率==个人巡线总完成点数%巡线总点数
                //设备完成数==设备个人完成点数之和
                //设备完成率==设备个人完成点数之和%设备总点数
                //总漏检率==1-设备完成率
                //总完成率==所有类型个人完成点数之和%所有类型总点数

                if(null!=workCompletionVoList && workCompletionVoList.size()>0){
                    Map<String, List<WorkCompletionVo>> collect = workCompletionVoList.stream().collect(Collectors.groupingBy(WorkCompletionVo::getMaintenanceFlag));
                     //线统计

                    collect.forEach((e, x) -> {

                        if(e.equals("0")){
                             //巡线
                             //总点数
                              BigDecimal totalCount = x.stream().map(WorkCompletionVo::getTotalCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                              BigDecimal totalOverCount = x.stream().map(WorkCompletionVo::getTotalOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                            //个人完成总点数
                              BigDecimal totalUserOverCount = x.stream().map(WorkCompletionVo::getUserOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                           //个人完成率
                            BigDecimal userOverCountRate = BigDecimal.ZERO;
                            if (null != totalUserOverCount && !totalUserOverCount.equals(BigDecimal.ZERO)) {
                                userOverCountRate = totalUserOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                            }
                            //总完成率
                            BigDecimal overCountRate = BigDecimal.ZERO;
                            if (null != totalUserOverCount && !totalUserOverCount.equals(BigDecimal.ZERO)) {
                                overCountRate = totalOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                            }



                            //线统计计算
                            BigDecimal totalLength = x.stream().map(WorkCompletionVo::getTotalLenth).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                            BigDecimal totalOverLength = x.stream().map(WorkCompletionVo::getTotalOverLenth).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                            BigDecimal userOverLength = x.stream().map(WorkCompletionVo::getUserOverLenth).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                            BigDecimal totalOverLengthRate = BigDecimal.ZERO;
                            if (null != totalOverLength && !totalOverLength.equals(BigDecimal.ZERO)) {
                                totalOverLengthRate = totalOverLength.multiply(BigDecimal.valueOf(100)).divide(totalLength, 2, BigDecimal.ROUND_HALF_UP);
                            }
                            BigDecimal userOverLengthRate = BigDecimal.ZERO;
                            if (null != userOverLengthRate && !userOverLengthRate.equals(BigDecimal.ZERO)) {
                                userOverLengthRate = userOverLengthRate.multiply(BigDecimal.valueOf(100)).divide(totalLength, 2, BigDecimal.ROUND_HALF_UP);
                            }

                            //vo.setTotalLenth(totalLength);
                           // vo.setTotalOverLenth(totalOverLength); //用对应点来计算完成率
                            vo.setUserOverLenth(userOverLength);
                            vo.setTotalOverLenthRate(overCountRate);
                            vo.setUserOverLenthRate(userOverCountRate);


                        }
                        else{
                            //设备
                            //总点数
                            BigDecimal totalCount = x.stream().map(WorkCompletionVo::getTotalCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                            BigDecimal totalOverCount = x.stream().map(WorkCompletionVo::getTotalOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                            //个人完成总点数
                            BigDecimal totalUserOverCount = x.stream().map(WorkCompletionVo::getUserOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                            //个人完成率
                            BigDecimal userOverCountRate = BigDecimal.ZERO;
                            if (null != totalUserOverCount && !totalUserOverCount.equals(BigDecimal.ZERO)) {
                                userOverCountRate = totalUserOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                            }
                            //总完成率
                            BigDecimal overCountRate = BigDecimal.ZERO;
                            if (null != totalUserOverCount && !totalUserOverCount.equals(BigDecimal.ZERO)) {
                                overCountRate = totalOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                            }
                           //设备完成数量
                            vo.setTotalOverEtCount(totalOverCount);
                            vo.setTotalOverEtCountRate(overCountRate);
                            vo.setUserOverEtCountRate(userOverCountRate);
                            vo.setUserOverEtCount(totalUserOverCount);
                            //漏检率
                            vo.setTotalEtLossRate(BigDecimal.valueOf(100).subtract(userOverCountRate));
                            vo.setTotalLossRate(BigDecimal.valueOf(100).subtract(userOverCountRate));
                           if(totalCount.compareTo(BigDecimal.ZERO)==0){
                               vo.setTotalEtLossRate(BigDecimal.ZERO);
                               vo.setTotalLossRate(BigDecimal.ZERO);
                           }
                        }

                    });

                  //点统计计算
                    BigDecimal totalCount = workCompletionVoList.stream().map(WorkCompletionVo::getTotalCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                    BigDecimal totalOverCount= workCompletionVoList.stream().map(WorkCompletionVo::getTotalOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                    BigDecimal userOverCount= workCompletionVoList.stream().map(WorkCompletionVo::getUserOverCount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);

                    BigDecimal overCountRate = BigDecimal.ZERO;
                    if (null != totalOverCount && !totalOverCount.equals(BigDecimal.ZERO)) {
                        overCountRate = totalOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                    }
                    BigDecimal userOverCountRate = BigDecimal.ZERO;
                    if (null != userOverCount && !userOverCount.equals(BigDecimal.ZERO)) {
                        userOverCountRate = userOverCount.multiply(BigDecimal.valueOf(100)).divide(totalCount, 2, BigDecimal.ROUND_HALF_UP);
                    }

                    vo.setTotalCount(totalCount);
                    vo.setTotalOverCount(totalOverCount);
                    vo.setTotalOverCountRate(overCountRate);
                    vo.setUserOverCount(userOverCount);
                    vo.setUserOverCountRate(userOverCountRate);

                 /*  List<WorkCompletionVo> collect = workCompletionVoList.stream().filter(i -> statisticalUserId.equals(i.getStatisticalUserId())).collect(Collectors.toList());
                    collect.forEach(base->{
                        vo.setTotalCount(base.getTotalCount());
                        vo.setTotalLenth(base.getTotalLenth());
                        vo.setTotalOverCount(base.getTotalOverCount());
                        vo.setTotalOverLenth(base.getTotalOverLenth());
                        vo.setTotalOverEtCount(base.getTotalOverEtCount());
                        vo.setTotalOverCountRate(base.getTotalOverCountRate());
                        vo.setTotalOverLenthRate(base.getTotalOverLenthRate());
                        vo.setTotalOverEtCountRate(base.getTotalOverEtCountRate());
                        vo.setTotalLossRate(base.getTotalLossRate());
                        vo.setTotalEtLossRate(base.getTotalEtLossRate());
                        vo.setUserOverCount(base.getUserOverCount());
                        vo.setUserOverLenth(base.getUserOverLenth());
                        vo.setUserOverEtCount(base.getUserOverEtCount());
                        vo.setUserOverCountRate(base.getUserOverCountRate());
                        vo.setUserOverLenthRate(base.getUserOverLenthRate());
                        vo.setUserOverEtCountRate(base.getUserOverEtCountRate());

                        statementAssessService.save(vo);
                    });*/

                    statementAssessService.save(vo);
                }else {
                    statementAssessService.save(vo);
                }

            });

        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }

    @ApiOperation(value = "巡检 年/季/月报查询")
    @PostMapping("/getInspectionStatement")
    @ToFlyAppLog(title = "巡检 年/季/月报查询")
    public ResultRespone<Object> getInspectionStatement(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<InspectionStatisticsVo> inspectionStatement = iStatementService.getInspectionStatement(dto);
            rest.setResult(inspectionStatement);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        }
        return rest;
    }




    @ApiOperation(value = "获取综合展示各模块任务数统计信息")
    @PostMapping("/getPlanDisplayStatistical")
    @ToFlyAppLog(title = "获取综合展示各模块任务数统计信息")
    public ResultRespone<Object> getPlanDisplayStatistical(@RequestBody StatementDto dto) {
        ResultRespone<Object> rest = new ResultRespone<>();
        try {
            List<PlanDisplayStatisticalVo> planDisplayStatistical = iStatementService.getPlanDisplayStatistical(dto);
            rest.setResult(planDisplayStatistical);
        } catch (BusinessException e) {
            rest.setCode(e.getRetCd());
            rest.setMessage(e.getMsgDes());

        } catch (Exception e){
            e.printStackTrace();
            log.error("获取综合展示各模块任务数统计信息异常:{}",e.getMessage());
        }
        return rest;
    }

    @ApiOperation(value = "抢维修工单统计")
    @GetMapping("/getRepairOrderStatement")
    @ToFlyAppLog(title = "抢维修工单统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startMonth",value = "开始月份yyyyMM",required = true,dataType = "String"),
            @ApiImplicitParam(name = "endMonth",value = "结束月份yyyyMM",required = true,dataType = "String"),
    })
    public ResultRespone getRepairOrderStatement(String startMonth,String endMonth) {
        try {
            return ResultRespone.success(iStatementService.getRepairOrderStatement(startMonth, endMonth));
        }catch (Exception e){
            e.printStackTrace();
            return ResultRespone.failed(e.getMessage());
        }
    }

    @ApiOperation(value = "管网巡检统计")
    @GetMapping("/getPlanReportStatement")
    @ToFlyAppLog(title = "管网巡检统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startMonth",value = "开始月份yyyyMM",required = true,dataType = "String"),
            @ApiImplicitParam(name = "endMonth",value = "结束月份yyyyMM",required = true,dataType = "String"),

    })
    public ResultRespone getPlanReportStatement(String startMonth,String endMonth) {
        try {
            return ResultRespone.success(iStatementService.getPlanReportStatement(startMonth, endMonth));
        }catch (Exception e){
            e.printStackTrace();
            return ResultRespone.failed(e.getMessage());
        }
    }

    @ApiOperation(value = "附属设施巡检率统计")
    @GetMapping("/getPlanDeviceReportStatement")
    @ToFlyAppLog(title = "附属设施巡检率统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "month",value = "近多少月的数据，默认为12月",required = false,dataType = "Integer")
    })
    public ResultRespone getPlanDeviceReportStatement(Integer month) {
        try {
            if(month==null){
                month=12;
            }
            return ResultRespone.success(iStatementService.getPlanDeviceReportStatement(-month));
        }catch (Exception e){
            e.printStackTrace();
            return ResultRespone.failed(e.getMessage());
        }
    }


    @ApiOperation(value = "巡检片区完成率统计")
    @GetMapping("/getPlanReginReportStatement")
    @ToFlyAppLog(title = "巡检片区完成率统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reginIds",value = "片区ids,多个逗号分离",required = false,dataType = "String")
    })
    public ResultRespone getPlanReginReportStatement(String reginIds) {
        try {

            return ResultRespone.success(iStatementService.getPlanReginReportStatement(reginIds));
        }catch (Exception e){
            e.printStackTrace();
            return ResultRespone.failed(e.getMessage());
        }
    }

}
