package cn.iocoder.yudao.module.pms.controller.admin.inspect.order;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.pms.controller.admin.inspect.order.vo.*;
import cn.iocoder.yudao.module.pms.controller.admin.stat.DeptUtil;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceSimple;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDetailDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectPlanDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectRouteDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDetailMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
import cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant;
import cn.iocoder.yudao.module.pms.service.IotDeviceService;
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectOrderDetailService;
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectOrderService;
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectPlanService;
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectRouteService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;


@Tag(name = "管理后台 - 巡检工单")
@RestController
@RequestMapping("/rq/iot-inspect-order")
@Validated
public class IotInspectOrderController {

    @Resource
    private IotInspectOrderService iotInspectOrderService;
    @Autowired
    private IotInspectOrderDetailMapper iotInspectOrderDetailMapper;
    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    private IotInspectPlanService iotInspectPlanService;
    @Autowired
    private IotInspectOrderDetailService iotInspectOrderDetailService;
    @Autowired
    private IotInspectRouteService iotInspectRouteService;
    @Autowired
    private DeptApi deptApi;
    @Autowired
    private IotDeviceMapper iotDeviceMapper;
    @Autowired
    private IotInspectOrderDeviceMapper iotInspectOrderDeviceMapper;
    @Autowired
    private DeptUtil deptUtil;
    @Autowired
    private DeptService deptService;
    @Autowired
    private IotInspectOrderMapper iotInspectOrderMapper;
    @Autowired
    private DictDataService dictDataService;

    @PostMapping("/create")
    @Operation(summary = "创建巡检工单")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:create')")
    public CommonResult<Long> createIotInspectOrder(@Valid @RequestBody IotInspectOrderSaveReqVO createReqVO) {
        return success(iotInspectOrderService.createIotInspectOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新巡检工单")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:update')")
    public CommonResult<Boolean> updateIotInspectOrder(@Valid @RequestBody IotInspectOrderSaveReqVO updateReqVO) {
        iotInspectOrderService.updateIotInspectOrder(updateReqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除巡检工单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:delete')")
    public CommonResult<Boolean> deleteIotInspectOrder(@RequestParam("id") Long id) {
        iotInspectOrderService.deleteIotInspectOrder(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得巡检工单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<IotInspectOrderRespVO> getIotInspectOrder(@RequestParam("id") Long id) {
        IotInspectOrderDO iotInspectOrder = iotInspectOrderService.getIotInspectOrder(id);
        IotInspectOrderRespVO bean = BeanUtils.toBean(iotInspectOrder, IotInspectOrderRespVO.class);
        List<IotInspectOrderDetailDO> orderId = iotInspectOrderDetailMapper.selectList("order_id", iotInspectOrder.getId());
        Map<Long, List<IotInspectOrderDetailDO>> collect = orderId.stream().collect(Collectors.groupingBy(IotInspectOrderDetailDO::getDeviceId));
        List<OrderDetail> orderDetails = new ArrayList<>();
        collect.forEach((k, v) -> {
            IotDeviceDO iotDevice = iotDeviceService.getIotDevice(k);
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setDeviceId(k);
            if (CollUtil.isNotEmpty(v)) {
                long normal = v.stream().filter(e -> Objects.nonNull(e.getIfNormal())&&e.getIfNormal()).count();
                long exception = v.stream().filter(e -> Objects.nonNull(e.getIfNormal())&&!e.getIfNormal()).count();
                long count = v.stream().filter(e -> Objects.isNull(e.getIfNormal())).count();
                orderDetail.setItemNormal(normal);
                orderDetail.setItemException(exception);
                orderDetail.setItemNeed(count);
                orderDetail.setRouteIndex(v.get(0).getRouteIndex());

            }
            if (Objects.nonNull(iotDevice)) {
                orderDetail.setDeviceName(iotDevice.getDeviceCode() + iotDevice.getDeviceName());
                orderDetail.setDeviceCode(iotDevice.getDeviceCode());
                orderDetail.setOrderDetails(v);
                orderDetails.add(orderDetail);
            }
        });

        if (CollUtil.isEmpty(orderDetails)) {
            throw new ServiceException(ErrorCodeConstant.INSPECT_DEVICE_CHANGE);
        }
        bean.setDetails(orderDetails.stream().sorted(Comparator.comparing(OrderDetail::getRouteIndex)).collect(Collectors.toList()));
        return success(bean);
    }

    @GetMapping("/get/details")
    @Operation(summary = "获得巡检工单详情")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<List<OrderDetail>> getIotInspectOrderDetails(@RequestParam("id") Long id) {
        List<IotInspectOrderDetailDO> orderId = iotInspectOrderDetailMapper.selectList("order_id", id);
        Map<Long, List<IotInspectOrderDetailDO>> collect = orderId.stream().collect(Collectors.groupingBy(IotInspectOrderDetailDO::getDeviceId));
        List<OrderDetail> orderDetails = new ArrayList<>();
        collect.forEach((k, v) -> {
            IotDeviceDO iotDevice = iotDeviceService.getIotDevice(k);
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setDeviceId(k);
            if (CollUtil.isNotEmpty(v)) {
                orderDetail.setRouteIndex(v.get(0).getRouteIndex());
                Long routeId = v.get(0).getRouteId();
                if (Objects.nonNull(routeId)) {
                    IotInspectRouteDO iotInspectRoute = iotInspectRouteService.getIotInspectRoute(routeId);
                    if (Objects.nonNull(iotInspectRoute)) {
                        orderDetail.setRouteDesc(iotInspectRoute.getRouteDesc());
                        orderDetail.setRouteName(iotInspectRoute.getRouteName());
                    }
                }
            }
            if (Objects.nonNull(iotDevice)) {
                orderDetail.setDeviceName(iotDevice.getDeviceCode()+iotDevice.getDeviceName());
                orderDetail.setOrderDetails(v);
                orderDetails.add(orderDetail);
            }
        });
        if (CollUtil.isEmpty(orderDetails)) {
            throw new ServiceException(ErrorCodeConstant.INSPECT_DEVICE_CHANGE);
        }
        return success(orderDetails.stream().sorted(Comparator.comparing(OrderDetail::getRouteIndex)).collect(Collectors.toList()));
    }

    @Data
    public static class OrderDetail {
        private Long deviceId;
        private String deviceName;
        private String deviceCode;
        private Long routeIndex;
        private List<IotInspectOrderDetailDO> orderDetails;
        private String ifException;
        private Long itemNormal;
        private Long itemException;
        private Long itemNeed;
        private String routeDesc;
        private String routeName;
    }

    @GetMapping("/page")
    @Operation(summary = "获得巡检工单分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<PageResult<IotInspectOrderRespVO>> getIotInspectOrderPage(@Valid IotInspectOrderPageReqVO pageReqVO) {
        PageResult<IotInspectOrderDO> pageResult = iotInspectOrderService.getIotInspectOrderPage(pageReqVO);
//        List<IotInspectOrderRespVO> collect = pageResult.getList().stream().map(e -> {
            //            BeanUtils.copyProperties(e, iotInspectOrderRespVO);
//            List<IotInspectOrderDetailDO> details = iotInspectOrderDetailMapper.selectList("order_id", e.getId());
//            long deviceCount = details.stream().map(IotInspectOrderDetailDO::getDeviceId).distinct().count();
//            long exceptionCount = details.stream().filter(f -> Objects.nonNull(f.getIfNormal()) && !f.getIfNormal()).map(IotInspectOrderDetailDO::getDeviceId).distinct().count();
//            Map<Long, List<IotInspectOrderDetailDO>> collect1 = details.stream().collect(Collectors.groupingBy(IotInspectOrderDetailDO::getDeviceId));
//            AtomicInteger needDevice = new AtomicInteger();
//            collect1.forEach((k, v) -> {
//                if (v.stream().anyMatch(gg -> Objects.isNull(gg.getIfNormal()))){
//                    needDevice.getAndIncrement();
//                }
//            });
//            iotInspectOrderRespVO.setDeviceCount(deviceCount);
//            iotInspectOrderRespVO.setExceptionCount(exceptionCount);
//            iotInspectOrderRespVO.setNeedDevice(needDevice.get());
//            return new IotInspectOrderRespVO();
//        }).collect(Collectors.toList());
        return success(BeanUtils.toBean(pageResult, IotInspectOrderRespVO.class));
    }

    @GetMapping("/page/app")
    @Operation(summary = "获得巡检工单分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<PageResult<IotInspectOrderRespVO>> getIotInspectOrderPageApp(@Valid IotInspectOrderPageReqVO pageReqVO) {
        PageResult<IotInspectOrderDO> pageResult = iotInspectOrderService.getIotInspectOrderPageApp(pageReqVO);
        List<IotInspectOrderRespVO> collect = pageResult.getList().stream().map(e -> {
            IotInspectOrderRespVO iotInspectOrderRespVO = new IotInspectOrderRespVO();
            BeanUtils.copyProperties(e, iotInspectOrderRespVO);
            List<IotInspectOrderDetailDO> details = iotInspectOrderDetailMapper.selectList("order_id", e.getId());
            long deviceCount = details.stream().map(IotInspectOrderDetailDO::getDeviceId).distinct().count();
            long exceptionCount = details.stream().filter(f -> Objects.nonNull(f.getIfNormal()) && !f.getIfNormal()).map(IotInspectOrderDetailDO::getDeviceId).distinct().count();
            Map<Long, List<IotInspectOrderDetailDO>> collect1 = details.stream().collect(Collectors.groupingBy(IotInspectOrderDetailDO::getDeviceId));
            AtomicInteger needDevice = new AtomicInteger();
            collect1.forEach((k, v) -> {
                if (v.stream().anyMatch(gg -> Objects.isNull(gg.getIfNormal()))){
                    needDevice.getAndIncrement();
                }
            });
            iotInspectOrderRespVO.setDeviceCount(deviceCount);
            iotInspectOrderRespVO.setExceptionCount(exceptionCount);
            iotInspectOrderRespVO.setNeedDevice(needDevice.get());
            return iotInspectOrderRespVO;
        }).collect(Collectors.toList());
        return success(new PageResult<>(collect, pageResult.getTotal()));
    }

    @GetMapping("/device/page")
    @Operation(summary = "获得设备的巡检工单信息")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<PageResult<IotInspectOrderRespVO>> getDeviceIotInspectOrderPage(@Valid IotInspectOrderPageReqVO pageReqVO) {
        Set<Long> orderIds = iotInspectOrderDetailMapper.selectList("device_id", pageReqVO.getDeviceIds()).stream().map(IotInspectOrderDetailDO::getOrderId).collect(Collectors.toSet());
        if (CollUtil.isEmpty(orderIds)) {
            return success(new PageResult<>(0L));
        }
        pageReqVO.setIdList(orderIds);
        pageReqVO.setDeviceIds(null);
        PageResult<IotInspectOrderDO> pageResult = iotInspectOrderService.getIotInspectOrderPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, IotInspectOrderRespVO.class));
    }

    @Data
    public static class IgnoreOrder{
        private Long id;
        private String reason;
    }

    @PostMapping("/ignore")
    @Operation(summary = "忽略")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> ignoreOrder(@Valid IgnoreOrder ignoreOrder) {
        List<IotInspectOrderDetailDO> details = iotInspectOrderDetailMapper.selectList("order_id", ignoreOrder.getId());
        long count = details.stream().filter(e -> Objects.nonNull(e.getIfNormal())).count();
        if (count > 0) {
            throw new ServiceException(new ErrorCode(133, "该工单已填写巡检项，无法忽略"));
        }
        details.forEach(e ->{
            e.setIgnoreReason(true);
            iotInspectOrderDetailMapper.updateById(e);
        });
        IotInspectOrderDO iotInspectOrder = iotInspectOrderService.getIotInspectOrder(ignoreOrder.getId());
        IotInspectOrderSaveReqVO iotInspectOrderSaveReqVO = new IotInspectOrderSaveReqVO();
        BeanUtils.copyProperties(iotInspectOrder, iotInspectOrderSaveReqVO);
        iotInspectOrderSaveReqVO.setReason(ignoreOrder.getReason());
        iotInspectOrderSaveReqVO.setStatus("ignore");
        iotInspectOrderService.updateIotInspectOrder(iotInspectOrderSaveReqVO);
        return success("完成");
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出巡检工单 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotInspectOrderExcel(@Valid IotInspectOrderPageReqVO pageReqVO, @RequestHeader("Lang") String lang,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotInspectOrderDO> list = iotInspectOrderService.getIotInspectOrderPage(pageReqVO).getList();
        List<IotInspectOrderRespVO> bean = BeanUtils.toBean(list, IotInspectOrderRespVO.class);
        List<DeptRespDTO> deptList = deptApi.getDeptList();
        List<DictDataDO> pmsDeviceStatus = dictDataService.getDictDataListByDictType("pms_inspect_order_status");
        bean.forEach(e -> {
            if (e.getInspectOrderTitle().contains("~~")){
                String[] split = e.getInspectOrderTitle().split("~~");
                if ("zh-CN".equals(lang)) {
                    e.setInspectOrderTitle(split[0]);
                }else if ("en".equalsIgnoreCase(lang)) {
                    if (split[1]!=null&&StringUtils.isNotBlank(split[1])){
                        e.setInspectOrderTitle(split[1].replaceAll(Pattern.quote("en**"), ""));
                    }
                }
            }
            deptList.stream().filter(f -> f.getId().equals(e.getDeptId())).findFirst().ifPresent(f -> e.setDeptName(f.getName()));
            pmsDeviceStatus.stream().filter(f -> f.getValue().equals(e.getStatus())).findFirst().ifPresent(f -> e.setStatus(f.getLabel()));
        });
        // 导出 Excel
        ExcelUtils.write(response, "巡检工单.xls", "数据", IotInspectOrderRespVO.class,
                        BeanUtils.toBean(bean, IotInspectOrderRespVO.class));
    }

    @PostMapping("/write/{orderId}")
    @Operation(summary = "导出巡检工单 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:create')")
    public CommonResult<String> updateItemProblem(@PathVariable("orderId") Long orderId, @RequestBody Map<String, String> requestMaps) {
        iotInspectOrderService.writeInspectOrderDetail(requestMaps, orderId);
        return CommonResult.success("成功");
    }

    @GetMapping("/test")
    @PermitAll
    @DataPermission(enable = false)
    @TenantIgnore
    public void test(){
        IotInspectPlanDO plan = iotInspectPlanService.getIotInspectPlan(38L);
        Date date = Date.from(
                plan.getLastCreateTime().atZone(ZoneId.systemDefault()) // 使用系统默认时区
                        .toInstant()                    // 转为 Instant（时间戳）
        );
        Date date1 = new Date();
        int i = Integer.parseInt(StringUtils.substringBeforeLast(String.valueOf(plan.getPlanCycle()), "."));
        DateTime dateTime = DateUtil.offsetHour(date, i);
        if (date1.compareTo(dateTime) > 0){
            System.out.println("-----------------");
        }
    }

    @GetMapping("/device")
    public CommonResult<PageResult<IotInspectDeviceVo>> getDeviceStatus(IotInspectOrderDetailPageReqVO pageReqVO){
        PageResult<IotInspectDeviceVo> deviceStatus = iotInspectOrderDetailService.getDeviceStatus(pageReqVO);
        return success(deviceStatus);
    }


    @GetMapping("/report/stat")
    @Operation(summary = "获得巡检工单分页")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order:query')")
    public CommonResult<PageResult<IotInspectOrderRespVO>> getIotInspectOrderPageReport(@Valid IotInspectOrderPageReqVO pageReqVO) {
        PageResult<IotInspectOrderDO> pageResult = iotInspectOrderService.getIotInspectOrderPage(pageReqVO);
//        List<IotDeviceDO> iotDeviceDOS = iotDeviceMapper.selectList();
        List<IotInspectOrderRespVO> collect = pageResult.getList().stream().map(e -> {
            IotInspectOrderRespVO iotInspectOrderRespVO = new IotInspectOrderRespVO();
            BeanUtils.copyProperties(e, iotInspectOrderRespVO);
            List<IotInspectOrderDetailDO> details = iotInspectOrderDetailMapper.selectList("order_id", e.getId());
            long exceptionCount = details.stream().filter(f -> Objects.nonNull(f.getIfNormal()) && !f.getIfNormal()).map(IotInspectOrderDetailDO::getDeviceId).distinct().count();
            iotInspectOrderRespVO.setExceptionCount(exceptionCount);
            //设置组织
            DeptRespDTO dept = deptApi.getDept(e.getDeptId());
            if (Objects.nonNull(dept)) {
                if ("1".equals(dept.getType())) {
                    iotInspectOrderRespVO.setCompany(dept.getName());
                } else if ("2".equals(dept.getType())) {
                    iotInspectOrderRespVO.setProject(dept.getName());
                    DeptRespDTO dept1 = deptApi.getDept(dept.getParentId());
                    if (Objects.nonNull(dept1)) {
                        iotInspectOrderRespVO.setCompany(dept1.getName());
                    }
                } else if ("3".equals(dept.getType())) {
                    iotInspectOrderRespVO.setDeptName(dept.getName());
                    DeptRespDTO dept1 = deptApi.getDept(dept.getParentId());
                    if (Objects.nonNull(dept1)) {
                        iotInspectOrderRespVO.setProject(dept1.getName());
                        DeptRespDTO dept2 = deptApi.getDept(dept1.getParentId());
                        if (Objects.nonNull(dept2)) {
                            iotInspectOrderRespVO.setCompany(dept2.getName());
                        }
                    }
                }
            }
            String deviceInfo = iotInspectOrderDeviceMapper.getDeviceInfo(e.getId());
            iotInspectOrderRespVO.setDeviceInfo(deviceInfo);
            return iotInspectOrderRespVO;
        }).collect(Collectors.toList());
        return success(new PageResult<>(collect, pageResult.getTotal()));
    }


    @GetMapping("/report/exception/item/export-excel")
    @Operation(summary = "导出巡检工单巡检异常点 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order-detail:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportReportExceptionItem(@Valid IotInspectOrderDetailPageReqVO pageReqVO,@RequestHeader("Lang") String lang,
                                          HttpServletResponse response) throws IOException {
        Set<Long> ids = new HashSet<>();
        String companyCode;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            companyCode = deptUtil.getCompanyCode(pageReqVO.getDeptId());
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        Set<Long> deviceIds = new HashSet<>();
        if (StringUtils.isNotBlank(pageReqVO.getDeviceCode())) {
            IotDevicePageReqVO devicePageReqVO = new IotDevicePageReqVO();
            devicePageReqVO.setDeviceCode(pageReqVO.getDeviceCode());
            deviceIds = iotDeviceMapper.selectList(devicePageReqVO).stream().map(IotDeviceDO::getId).collect(Collectors.toSet());
        }
        Set<Long> orderIds = new HashSet<>();
        if (StringUtils.isNotBlank(pageReqVO.getOrderName())) {
            IotInspectOrderPageReqVO iotInspectOrderPageReqVO = new IotInspectOrderPageReqVO();
            iotInspectOrderPageReqVO.setInspectOrderTitle(pageReqVO.getOrderName());
            orderIds = iotInspectOrderMapper.selectList(iotInspectOrderPageReqVO).stream().map(IotInspectOrderDO::getId).collect(Collectors.toSet());
        }
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        pageReqVO.setIfNormal(false);
        List<IotInspectOrderDetailDO> list = iotInspectOrderDetailMapper.selectItemPage(pageReqVO, ids, deviceIds, orderIds).getList();
        List<IotInspectOrderDetailRespVO> bean = BeanUtils.toBean(list, IotInspectOrderDetailRespVO.class);
        bean.forEach(e -> {
            if (Objects.nonNull(e.getDeviceId())) {
                IotDeviceDO iotDevice = iotDeviceService.getIotDevice(e.getDeviceId());
                if (Objects.nonNull(iotDevice)) {
                    e.setDeviceCode(iotDevice.getDeviceCode());
                    e.setDeviceName(iotDevice.getDeviceName());
                }
            }
            if (Objects.nonNull(e.getOrderId())) {
                IotInspectOrderDO iotInspectOrder = iotInspectOrderService.getIotInspectOrder(e.getOrderId());
                if (Objects.nonNull(iotInspectOrder)) {
                    if (iotInspectOrder.getInspectOrderTitle().contains("~~")){
                        String[] split = iotInspectOrder.getInspectOrderTitle().split("~~");
                        if ("zh-CN".equals(lang)) {
                            e.setOrderName(split[0]);
                        }else if ("en".equalsIgnoreCase(lang)) {
                            if (split[1]!=null&&StringUtils.isNotBlank(split[1])){
                                e.setOrderName(split[1].replaceAll(Pattern.quote("en**"), ""));
                            }
                        } else {
                            e.setOrderName(iotInspectOrder.getInspectOrderTitle());
                        }
                    }
                    e.setCharge(iotInspectOrder.getChargeName());
                }
            }
            e.setResult(e.getIfNormal()?"正常":"异常");
        });
        // 导出 Excel
        ExcelUtils.write(response, "巡检工单异常点统计.xls", "数据", IotInspectOrderDetailRespVO.class,
                BeanUtils.toBean(bean, IotInspectOrderDetailRespVO.class));
    }
    @GetMapping("/exception/device")
    public CommonResult<PageResult<IotDeviceSimple>> getExceptionDevice(@Valid IotInspectOrderPageReqVO pageReqVO) {
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        IPage<IotDeviceSimple> exceptionDevicePage = iotInspectOrderDetailMapper.getExceptionDevicePage(new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        PageResult<IotDeviceSimple> result = new PageResult<>(exceptionDevicePage.getRecords(), exceptionDevicePage.getTotal());
        return success(result);
    }


    @GetMapping("/report/export-excel")
    @Operation(summary = "导出巡检工单巡检异常点 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order-detail:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportReport(@Valid IotInspectOrderPageReqVO pageReqVO,@RequestHeader("Lang") String lang,
                                          HttpServletResponse response) throws IOException {
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
            ids.add(pageReqVO.getDeptId());
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        List<IotInspectOrderRespVO> bean = iotInspectOrderMapper.selectExport(pageReqVO);
        List<IotReportInspectOrderRespVO> list = BeanUtils.toBean(bean, IotReportInspectOrderRespVO.class);
        list.forEach(e ->{
            if (e.getInspectOrderTitle().contains("~~")){
                String[] split = e.getInspectOrderTitle().split("~~");
                if ("zh-CN".equals(lang)) {
                    e.setInspectOrderTitle(split[0]);
                }else if ("en".equalsIgnoreCase(lang)) {
                    if (split[1]!=null&&StringUtils.isNotBlank(split[1])){
                        e.setInspectOrderTitle(split[1].replaceAll(Pattern.quote("en**"), ""));
                    }
                }
            }
        });
        // 导出 Excel
        ExcelUtils.write(response, "巡检报表统计.xls", "数据", IotReportInspectOrderRespVO.class, list);
    }

    @GetMapping("/report/exception/device/export-excel")
    @Operation(summary = "导出巡检工单巡检异常点 Excel")
    @PreAuthorize("@ss.hasPermission('rq:iot-inspect-order-detail:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportReportExceptionDevice(@Valid IotInspectOrderPageReqVO pageReqVO,
                             HttpServletResponse response) throws IOException {
        Set<Long> ids;
        if (Objects.isNull(pageReqVO.getDeptId())){
            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
            String companyCode = deptUtil.getCompanyCode(loginUserDeptId);
            ids = deptUtil.getDeptIds(companyCode);
        } else {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        pageReqVO.setDeptIds(ids);
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotDeviceSimple> records = iotInspectOrderDetailMapper.getExceptionDevicePage(new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO).getRecords();
        // 导出 Excel
        ExcelUtils.write(response, "巡检异常设备统计.xls", "数据", IotDeviceSimple.class, records);
    }

}
