package cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
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.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotattachment.vo.IotAttachmentPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder.vo.*;
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceExportRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotattachment.IotAttachmentDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
import cn.iocoder.yudao.module.pms.enums.AttachmentCategoryEnum;
import cn.iocoder.yudao.module.pms.enums.AttachmentTypeEnum;
import cn.iocoder.yudao.module.pms.service.iotattachment.IotAttachmentService;
import cn.iocoder.yudao.module.pms.service.iotdeviceperson.IotDevicePersonService;
import cn.iocoder.yudao.module.pms.service.iotmainworkorder.IotMainWorkOrderService;
import cn.iocoder.yudao.module.pms.service.iotmainworkorderbom.IotMainWorkOrderBomService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
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 io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
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.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;

@Tag(name = "管理后台 - 保养工单")
@RestController
@RequestMapping("/pms/iot-main-work-order")
@Validated
public class IotMainWorkOrderController {

    @Resource
    private IotMainWorkOrderService iotMainWorkOrderService;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private IotMainWorkOrderBomService iotMainWorkOrderBomService;
    @Resource
    private DeptService deptService;
    @Autowired
    private IotDevicePersonService iotDevicePersonService;
    @Resource
    private DictDataService dictDataService;
    @Resource
    private IotAttachmentService iotAttachmentService;

    @PostMapping("/create")
    @Operation(summary = "创建保养工单")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:create')")
    public CommonResult<Long> createIotMainWorkOrder(@Valid @RequestBody IotMainWorkOrderSaveReqVO createReqVO) {
        return success(iotMainWorkOrderService.createIotMainWorkOrder(createReqVO));
    }

    @PutMapping("/update")
    @Operation(summary = "更新保养工单")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:update')")
    public CommonResult<Boolean> updateIotMainWorkOrder(@Valid @RequestBody IotMainWorkOrderSaveReqVO updateReqVO) {
        iotMainWorkOrderService.updateIotMainWorkOrder(updateReqVO);
        return success(true);
    }

    @PutMapping("/fillWorkOrder")
    @Operation(summary = "填写保养工单")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:update')")
    public CommonResult<Boolean> fillWorkOrder(@Valid @RequestBody IotMainWorkOrderSaveVO saveVO) {
        iotMainWorkOrderService.fillWorkOrder(saveVO);
        return success(true);
    }

    @PutMapping("/hiWorkOrderAttachment")
    @Operation(summary = "历史保养工单 上传附件")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:update')")
    public CommonResult<Boolean> hiWorkOrderAttachment(@Valid @RequestBody IotMainWorkOrderSaveReqVO orderReqVO) {
        iotMainWorkOrderService.hiWorkOrderAttachment(orderReqVO);
        return success(true);
    }

    @PutMapping("/modifyWorkOrder")
    @Operation(summary = "修改退回的保养工单")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:update')")
    public CommonResult<Boolean> modifyWorkOrder(@Valid @RequestBody IotMainWorkOrderSaveVO saveVO) {
        iotMainWorkOrderService.modifyWorkOrder(saveVO);
        return success(true);
    }

    @PutMapping("/historyWorkOrderOutbound")
    @Operation(summary = "历史保养工单物料记录出库 初始化保养的出库记录")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:update')")
    public CommonResult<Boolean> historyWorkOrderOutbound() {
        iotMainWorkOrderService.historyWorkOrderOutbound();
        return success(true);
    }

    @PutMapping("/addWorkOrder")
    @Operation(summary = "手工新增保养工单")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:create')")
    public CommonResult<Boolean> addWorkOrder(@Valid @RequestBody IotMainWorkOrderSaveVO saveVO) {
        iotMainWorkOrderService.addWorkOrder(saveVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除保养工单")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:delete')")
    public CommonResult<Boolean> deleteIotMainWorkOrder(@RequestParam("id") Long id) {
        iotMainWorkOrderService.deleteIotMainWorkOrder(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获得保养工单")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<IotMainWorkOrderRespVO> getIotMainWorkOrder(@RequestParam("id") Long id) {
        IotMainWorkOrderDO iotMainWorkOrder = iotMainWorkOrderService.getIotMainWorkOrder(id);
        return success(buildWorkOrder(iotMainWorkOrder));
    }

    /**
     * 查询保养工单详情
     * @param iotMainWorkOrder
     * @return
     */
    private IotMainWorkOrderRespVO buildWorkOrder(IotMainWorkOrderDO iotMainWorkOrder) {
        if (ObjUtil.isEmpty(iotMainWorkOrder)) {
            return new IotMainWorkOrderRespVO();
        }
        IotMainWorkOrderRespVO workOrderVO = BeanUtils.toBean(iotMainWorkOrder, IotMainWorkOrderRespVO.class);
        // 查询当前工单关联的附件信息
        IotAttachmentPageReqVO reqVO = new IotAttachmentPageReqVO();
        reqVO.setBizId(workOrderVO.getId());
        reqVO.setCategory(AttachmentCategoryEnum.MAINTENANCE.getCode());
        reqVO.setType(AttachmentTypeEnum.MAINTENANCE_STANDARD.getCode());
        List<IotAttachmentDO> attachments = iotAttachmentService.getIotAttachments(reqVO);
        if (CollUtil.isNotEmpty(attachments)) {
            workOrderVO.setAttachments(attachments);
        }
        return workOrderVO;
    }

    @GetMapping("/deviceWorkOrder")
    @Operation(summary = "从设备台账查询保养工单 只关联当前设备明细")
    @Parameter(name = "workOrderId", description = "保养工单id", required = true, example = "1024")
    @Parameter(name = "deviceId", description = "设备id", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<IotMainWorkOrderRespVO> deviceWorkOrder(@RequestParam("workOrderId") Long workOrderId, @RequestParam("deviceId") Long deviceId) {
        IotMainWorkOrderRespVO iotMainWorkOrder = iotMainWorkOrderService.getDeviceMainWorkOrder(workOrderId, deviceId);
        return success(iotMainWorkOrder);
    }

    @GetMapping("/page")
    @Operation(summary = "获得保养工单分页")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<PageResult<IotMainWorkOrderRespVO>> getIotMainWorkOrderPage(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        PageResult<IotMainWorkOrderDO> pageResult = iotMainWorkOrderService.getIotMainWorkOrderPage(pageReqVO);
        return success(new PageResult<>(buildMainWorkOrderList(pageResult.getList()), pageResult.getTotal()));
    }

    @GetMapping("/sortedMainWorkOrderPage")
    @Operation(summary = "获得保养工单分页 按照保养项的最近保养排序")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<PageResult<IotMainWorkOrderRespVO>> sortedMainWorkOrderPage(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        PageResult<IotMainWorkOrderRespVO> pageResult = iotMainWorkOrderService.sortedMainWorkOrderPage(pageReqVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal()));
        }
        return success(new PageResult<>(buildSortedMainWorkOrders(pageResult.getList()), pageResult.getTotal()));
    }

    @GetMapping("/deviceMainDistances")
    @Operation(summary = "以设备为维度统计所有保养明细中最近的保养数据 里程/时间/自然日期")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<PageResult<IotDeviceRespVO>> deviceMainDistances(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        PageResult<IotDeviceRespVO> pageResult = iotMainWorkOrderService.deviceMainDistances(pageReqVO);
        return success(new PageResult<>(buildDeviceDistanceList(pageResult.getList()), pageResult.getTotal()));
    }

    @GetMapping("/deviceMainTimeoutList")
    @Operation(summary = "以公司为维度 统计所有超时保养的设备(保养里程 保养时长 保养自然日期) 统计报表明细")
    @PermitAll
    public CommonResult<List<IotDeviceRespVO>> deviceMainTimeoutList(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        List<IotDeviceRespVO> timeoutDevices = iotMainWorkOrderService.deviceMainTimeoutList(pageReqVO);
        return success(buildDeviceDistanceList(timeoutDevices));
    }

    @GetMapping("/timeoutDeviceMainDistances")
    @Operation(summary = "以公司为维度 统计所有超时保养的设备(保养里程 保养时长 保养自然日期)")
    @PermitAll
    public CommonResult<List<IotDeviceMainTimeoutVO>> timeoutDeviceMainDistances(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        List<IotDeviceMainTimeoutVO> deviceMainDistances = iotMainWorkOrderService.timeoutDeviceMainDistances(pageReqVO);
        return success(deviceMainDistances);
    }

    @GetMapping("/maintenanceSearch")
    @Operation(summary = "以设备为维度统计所有保养计划明细中最近的保养数据 里程/时间/自然日期 可能以设备BOM分组")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<PageResult<IotDeviceRespVO>> maintenanceSearch(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        PageResult<IotDeviceRespVO> pageResult = iotMainWorkOrderService.maintenanceSearch(pageReqVO);
        return success(new PageResult<>(buildDeviceDistanceList(pageResult.getList()), pageResult.getTotal()));
    }

    @GetMapping("/deviceOrderPage")
    @Operation(summary = "根据设备id获得保养工单分页")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<PageResult<IotMainWorkOrderRespVO>> deviceOrderPage(@Valid IotMainWorkOrderPageReqVO pageReqVO) {
        PageResult<IotMainWorkOrderRespVO> pageResult = iotMainWorkOrderService.deviceOrderPage(pageReqVO);
        List<IotMainWorkOrderDO> orders = BeanUtils.toBean(pageResult.getList(), IotMainWorkOrderDO.class);
        return success(new PageResult<>(buildMainWorkOrderList(orders), pageResult.getTotal()));
    }

    @GetMapping("/allWorkOrderCountByResult")
    @Operation(summary = "根据保养结果查询工单数量")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:query')")
    public CommonResult<List<Map<String, Integer>>> allWorkOrderCountByResult() {
        List<Map<String, Integer>> workOrderCount = iotMainWorkOrderService.allWorkOrderCountByResult();
        return success(CollectionUtil.isEmpty(workOrderCount) ? CollectionUtil.newArrayList() : workOrderCount);
    }

    /**
     * 组装 设备-bom 关联关系对象
     * @param devices
     * @return
     */
    private List<IotDeviceRespVO> buildDeviceDistanceList(List<IotDeviceRespVO> devices) {
        if (CollUtil.isEmpty(devices)) {
            return Collections.emptyList();
        }
        // 设备部门信息
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(
                convertList(devices, IotDeviceRespVO::getDeptId));
        Set<Long> deviceIds = new HashSet<>();
        devices.forEach(device -> {
            deviceIds.add(device.getId());
        });
        // 查询设备列表是否已经生成了工单 工单的状态
        IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
        bomReqVO.setDeviceIds(new ArrayList<>(deviceIds));
        bomReqVO.setStatus(0);  // 筛选出保养未完成的保养项
        // 查询当前页设备关联的保养工单明细
        List<IotMainWorkOrderBomDO> orderBoms = iotMainWorkOrderBomService.getIotMainWorkOrderBomList(bomReqVO);
        Set<Long> orderIds = new HashSet<>();
        // key设备id      value保养工单id
        Map<Long, Long> deviceOrderPair = new HashMap<>();
        // key设备id      value正在执行的保养工单id
        Map<Long, Long> deviceRunningOrderPair = new HashMap<>();
        // key设备状态数据字典value   value设备状态数据字典label
        Map<String, String> deviceStatusPair = new HashMap<>();

        // 施工状态 字典数据
        List<DictDataDO> deviceStatusData = dictDataService.getDictDataListByDictType("pms_device_status");
        if (CollUtil.isNotEmpty(deviceStatusData)) {
            deviceStatusData.forEach(data -> {
                deviceStatusPair.put(data.getValue(), data.getLabel());
            });
        }

        if (CollUtil.isNotEmpty(orderBoms)) {
            orderBoms.forEach(bom -> {
                orderIds.add(bom.getWorkOrderId());
                // 建立设备id与工单id的对应关系
                deviceOrderPair.put(bom.getDeviceId(), bom.getWorkOrderId());
            });
        }
        if (CollUtil.isNotEmpty(orderIds)) {
            // 查询当前页的设备关联的工单主表信息
            IotMainWorkOrderPageReqVO orderReqVO = new IotMainWorkOrderPageReqVO();
            orderReqVO.setWorkOrderIds(new ArrayList<>(orderIds));
            orderReqVO.setType(1);      // 筛选出计划生成的工单
            orderReqVO.setResult(1);    // 筛选出待执行的工单
            List<IotMainWorkOrderDO> workOrders = iotMainWorkOrderService.workOrders(orderReqVO);
            if (CollUtil.isNotEmpty(workOrders)) {
                workOrders.forEach(order -> {
                    if (CollUtil.isNotEmpty(deviceOrderPair)) {
                        deviceOrderPair.forEach((k,v) -> {
                            // key设备id      value保养工单id
                            if (order.getId().equals(v)) {
                                deviceRunningOrderPair.put(k,v);
                            }
                        });
                    }
                });
            }
        }
        // 查询设备关联的 负责人
        Map<Long, String> devicePersonNames = iotDevicePersonService.getIotDevicePerson(convertList(devices, IotDeviceRespVO::getId));
        // 2. 拼接数据
        return BeanUtils.toBean(devices, IotDeviceRespVO.class, (deviceVO) -> {
            // 2.1 拼接部门信息
            findAndThen(deptMap, deviceVO.getDeptId(), dept -> deviceVO.setDeptName(dept.getName()));
            // 2.2 设备关联的负责人姓名
            findAndThen(devicePersonNames, deviceVO.getId(), person -> deviceVO.setResponsibleNames(person));
            // 设置设备关联的保养工单标识
            if (deviceVO.isShouldWorkOrder()) {
                // 此时应该生成保养工单
                if (deviceRunningOrderPair.containsKey(deviceVO.getId())) {
                    deviceVO.setRunningWorkOrder(true);
                }
            }
        });
    }

    private List<IotMainWorkOrderRespVO> buildMainWorkOrderList(List<IotMainWorkOrderDO> orders) {
        if (CollUtil.isEmpty(orders)) {
            return Collections.emptyList();
        }
        // 筛选出 计划生成 待执行 的工单 计算其距离保养时间
        List<IotMainWorkOrderDO> distanceOrders = orders.stream()
                .filter(order -> order.getType() == 1 && order.getResult() == 1)
                .collect(Collectors.toList());
        // 查询保养计划 负责人
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(orders,
                order -> Stream.of(NumberUtils.parseLong(order.getResponsiblePerson()))));
        // 查询 各工单 明细保养项 的距离保养时间/里程/自然日期 包含多个保养项的 以最近到期时间为准
        IotMainWorkOrderBomPageReqVO reqVO = new IotMainWorkOrderBomPageReqVO();
        reqVO.setWorkOrderIds(convertListByFlatMap(distanceOrders, order -> Stream.of(order.getId())));
        Map<Long, String> nearestDistances = new HashMap<>();
        if (CollUtil.isNotEmpty(distanceOrders)) {
            nearestDistances = iotMainWorkOrderBomService.mainWorkOrderNearestDistance(reqVO);
        }
        // 2. 转换成 VO
        Map<Long, String> finalNearestDistances = nearestDistances;
        return BeanUtils.toBean(orders, IotMainWorkOrderRespVO.class, orderVO -> {
            // 设置创建人、负责人名称
            MapUtils.findAndThen(userMap, NumberUtils.parseLong(orderVO.getResponsiblePerson()),
                    user -> orderVO.setResponsiblePersonName(user.getNickname()));
            // 距离保养时间/公里数/自然日
            MapUtils.findAndThen(finalNearestDistances, orderVO.getId(),
                    distance -> orderVO.setMainDistance(distance));
        });
    }

    private List<IotMainWorkOrderRespVO> buildSortedMainWorkOrders(List<IotMainWorkOrderRespVO> orders) {
        if (CollUtil.isEmpty(orders)) {
            return Collections.emptyList();
        }
        // 返回工单所属部门
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(
                convertList(orders, IotMainWorkOrderRespVO::getDeptId));
        // 查询保养计划 负责人
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(orders,
                order -> Stream.of(NumberUtils.parseLong(order.getResponsiblePerson()))));
        return BeanUtils.toBean(orders, IotMainWorkOrderRespVO.class, orderVO -> {
            // 创建时间 格式化 yyyy-MM-dd
            if (ObjUtil.isNotEmpty(orderVO.getCreateTime())) {
                orderVO.setCreateTimeStr(LocalDateTimeUtil.format(orderVO.getCreateTime(), DatePattern.NORM_DATE_PATTERN));
            }
            // 创建时间 格式化 yyyy-MM-dd
            if (ObjUtil.isNotEmpty(orderVO.getUpdateTime())) {
                orderVO.setUpdateTimeStr(LocalDateTimeUtil.format(orderVO.getUpdateTime(), DatePattern.NORM_DATE_PATTERN));
            }
            // 2.1 拼接部门信息
            findAndThen(deptMap, orderVO.getDeptId(), dept -> orderVO.setDeptName(dept.getName()));
            // 设置创建人、负责人名称
            MapUtils.findAndThen(userMap, NumberUtils.parseLong(orderVO.getResponsiblePerson()),
                    user -> orderVO.setResponsiblePersonName(user.getNickname()));
        });
    }

    @GetMapping("/export-excel")
    @Operation(summary = "导出保养工单 Excel")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportIotMainWorkOrderExcel(@Valid IotMainWorkOrderPageReqVO pageReqVO,
              HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotMainWorkOrderDO> list = iotMainWorkOrderService.getIotMainWorkOrderPage(pageReqVO).getList();
        // 导出 Excel
        ExcelUtils.write(response, "保养工单.xls", "数据", IotMainWorkOrderRespVO.class,
                        BeanUtils.toBean(list, IotMainWorkOrderRespVO.class));
    }

    @GetMapping("/exportMaintenances")
    @Operation(summary = "导出保养查询列表 Excel")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportMaintenances(@Valid IotMainWorkOrderPageReqVO pageReqVO,
                                            HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        List<IotDeviceRespVO> maintenances = iotMainWorkOrderService.deviceMainDistances(pageReqVO).getList();
        // List<IotMainWorkOrderDO> list = iotMainWorkOrderService.getIotMainWorkOrderPage(pageReqVO).getList();
        // key设备状态数据字典value   value设备状态数据字典label
        Map<String, String> deviceStatusPair = new HashMap<>();

        // 施工状态 字典数据
        List<DictDataDO> deviceStatusData = dictDataService.getDictDataListByDictType("pms_device_status");
        if (CollUtil.isNotEmpty(deviceStatusData)) {
            deviceStatusData.forEach(data -> {
                deviceStatusPair.put(data.getValue(), data.getLabel());
            });
        }
        List<IotDeviceRespVO> deviceDistances = buildDeviceDistanceList(maintenances);
        List<IotDeviceExportRespVO> deviceDistancesResult = BeanUtils.toBean(deviceDistances, IotDeviceExportRespVO.class);
        if (CollUtil.isNotEmpty(deviceDistancesResult)) {
            deviceDistancesResult.forEach(distance -> {
                // 设置施工状态 label
                if (deviceStatusPair.containsKey(distance.getDeviceStatus())) {
                    String statusLabel = deviceStatusPair.get(distance.getDeviceStatus());
                    // 转换成默认语言 中文
                    if (StrUtil.isNotBlank(statusLabel) && statusLabel.contains("~~")) {
                        // 截取首次~~之前的部分
                        String processedName = statusLabel.substring(0, statusLabel.indexOf("~~"));
                        distance.setDeviceStatusLabel(processedName);
                    } else {
                        distance.setDeviceStatusLabel(statusLabel);
                    }
                }
                // 设置工单状态 未生成工单;已生成工单未执行
                if (distance.isShouldWorkOrder() && distance.isRunningWorkOrder()) {
                    distance.setOrderStatus("已生成工单未执行");
                }
                if (distance.isShouldWorkOrder() && !distance.isRunningWorkOrder()) {
                    distance.setOrderStatus("未生成工单");
                }
            });
        }
        // 导出 Excel
        ExcelUtils.write(response, "保养查询.xls", "保养查询", IotDeviceExportRespVO.class,
                deviceDistancesResult);
    }

    @GetMapping("/exportMaintenanceOrders")
    @Operation(summary = "导出保养查询列表 Excel")
    @PreAuthorize("@ss.hasPermission('pms:iot-main-work-order:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void exportMaintenanceOrders(@Valid IotMainWorkOrderPageReqVO pageReqVO,
                                   HttpServletResponse response) throws IOException {
        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
        // List<IotDeviceRespVO> maintenances = iotMainWorkOrderService.deviceMainDistances(pageReqVO).getList();
        List<IotMainWorkOrderRespVO> orders = iotMainWorkOrderService.sortedMainWorkOrderPage(pageReqVO).getList();
        // key设备状态数据字典value   value设备状态数据字典label
        Map<String, String> deviceStatusPair = new HashMap<>();

        // 施工状态 字典数据
        List<DictDataDO> deviceStatusData = dictDataService.getDictDataListByDictType("pms_device_status");
        if (CollUtil.isNotEmpty(deviceStatusData)) {
            deviceStatusData.forEach(data -> {
                deviceStatusPair.put(data.getValue(), data.getLabel());
            });
        }
        List<IotMainWorkOrderRespVO> sortedOrders = buildSortedMainWorkOrders(orders);
        if (CollUtil.isNotEmpty(sortedOrders)) {
            sortedOrders.forEach(order -> {
                // 工单名称 去掉多语言
                // 设备名称 去掉多语言标识
                String orderName = order.getName();
                if (StrUtil.isNotBlank(orderName) && orderName.contains("~~")) {
                    // 截取首次~~之前的部分
                    String processedName = orderName.substring(0, orderName.indexOf("~~"));
                    order.setName(processedName);
                }
                // 工单类型 label
                if (order.getType() == 1) {
                    order.setTypeName("计划生成");
                } else {
                    order.setTypeName("临时新建");
                }
                // 工单状态  待执行 已执行
                if (order.getResult() == 1) {
                    order.setResultName("待执行");
                } else {
                    order.setResultName("已执行");
                }
            });
        }
        // 导出 Excel
        ExcelUtils.write(response, "保养工单.xls", "保养工单", IotMainWorkOrderRespVO.class,
                sortedOrders);
    }

}