Quellcode durchsuchen

工单完成情况导出接口

Zimo vor 3 Stunden
Ursprung
Commit
dd297b710f

+ 135 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/stat/IotReportOrderController.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotprojecttask.vo.IotProjectTaskPageReqVO;
@@ -46,7 +47,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.security.PermitAll;
+import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
@@ -440,4 +443,136 @@ public class IotReportOrderController {
         return success(new PageResult<>(collect, allOrder.getTotal()));
 
     }
+
+    @GetMapping("/export-excel")
+    public void downloadExcelByStringHeader(@Valid IotMaintainPageReqVO 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);
+        List<AllOrderResp> allOrder = iotMaintainMapper.getAllOrderNoPage(pageReqVO);
+//        PageResult<AllOrderResp> result = new PageResult<>(allOrder.getRecords(), allOrder.getTotal());
+        Map<Long, String> orderPair = new HashMap<>();
+        Map<Long, Long> orderDeviceIdPair = new HashMap<>();
+        Map<Long, String> devicePair = new HashMap<>();
+        // 任务列表
+        Set<Long> taskIds = new HashSet<>();
+        // 设备id列表
+        Set<Long> totalDeviceIds = new HashSet<>();
+        // 日报设备列表 key设备id   value设备信息
+        Map<Long, String> reportDevicePair = new HashMap<>();
+        // 日报设备列表 key任务id   value多个设备信息列表
+        Map<Long, Set<Long>> taskDevicesPair = new HashMap<>();
+        // 日报设备列表 key任务id   value多个设备信息 分号分隔
+        Map<Long,String> taskDevicesStrPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(allOrder)) {
+            Set<Long> orderIds = new HashSet<>();
+            allOrder.forEach(order -> {
+                if ("保养工单".equals(order.getType())) {
+                    orderIds.add(order.getId());
+                }
+                if ("瑞都日报".equals(order.getType()) || "瑞鹰日报".equals(order.getType()) || "瑞恒日报".equals(order.getType())) {
+                    taskIds.add(order.getTaskId());
+                }
+            });
+            if (CollUtil.isNotEmpty(taskIds)) {
+                IotProjectTaskPageReqVO reqVO = new IotProjectTaskPageReqVO();
+                reqVO.setTaskIds(new ArrayList<>(taskIds));
+                List<IotProjectTaskDO> tasks = iotProjectTaskMapper.selectList(reqVO);
+                if (CollUtil.isNotEmpty(tasks)) {
+                    tasks.forEach(task -> {
+                        Set<Long> deviceIds = task.getDeviceIds();
+                        if (CollUtil.isNotEmpty(deviceIds)) {
+                            totalDeviceIds.addAll(deviceIds);
+                            taskDevicesPair.put(task.getId(), task.getDeviceIds());
+                        }
+                    });
+                }
+                // 查询所有设备信息
+                IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+                deviceReqVO.setDeviceIds(new ArrayList<>(totalDeviceIds));
+                List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
+                if (CollUtil.isNotEmpty(devices)) {
+                    devices.forEach(device -> {
+                        reportDevicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
+                    });
+                }
+                // 建立日报关联的任务id 与 任务下所有设备 编码名称 的对应关系
+                if (CollUtil.isNotEmpty(taskDevicesPair) && CollUtil.isNotEmpty(reportDevicePair)) {
+                    for (Map.Entry<Long, Set<Long>> entry : taskDevicesPair.entrySet()) {
+                        Long taskId = entry.getKey();
+                        Set<Long> deviceIds = entry.getValue();
+
+                        // 使用流处理获取设备名称,并用分号连接
+                        String deviceStr = deviceIds.stream()
+                                .map(reportDevicePair::get)  // 从 reportDevicePair 获取设备字符串
+                                .filter(StrUtil::isNotBlank)  // 过滤掉空值
+                                .collect(Collectors.joining(";"));  // 用分号连接
+
+                        if (StrUtil.isNotBlank(deviceStr)) {
+                            taskDevicesStrPair.put(taskId, deviceStr);
+                        }
+                    }
+                }
+            }
+            if (CollUtil.isNotEmpty(orderIds)) {
+                Set<Long> deviceIds = new HashSet<>();
+                // 查询所有保养工单的设备名称
+                IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
+                bomReqVO.setWorkOrderIds(new ArrayList<>(orderIds));
+                List<IotMainWorkOrderBomDO> orderBoms = iotMainWorkOrderBomMapper.selectList(bomReqVO);
+                if (CollUtil.isNotEmpty(orderBoms)) {
+                    orderBoms.forEach(bom -> {
+                        deviceIds.add(bom.getDeviceId());
+                        orderDeviceIdPair.put(bom.getWorkOrderId(), bom.getDeviceId());
+                    });
+                    // 查询所有设备的编码 名称
+                    IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
+                    deviceReqVO.setDeviceIds(new ArrayList<>(deviceIds));
+                    List<IotDeviceDO> devices = iotDeviceMapper.selectListAlone(deviceReqVO);
+                    if (CollUtil.isNotEmpty(devices)) {
+                        devices.forEach(device -> {
+                            devicePair.put(device.getId(), StrUtil.join("|", device.getDeviceCode(), device.getDeviceName()));
+                        });
+                    }
+                    orderDeviceIdPair.forEach((orderId, deviceId) -> {
+                        if (devicePair.containsKey(deviceId)) {
+                            orderPair.put(orderId, devicePair.get(deviceId));
+                        }
+                    });
+                }
+            }
+        }
+//        List<AllOrderResp> collect = allOrder.stream().map(e -> {
+//            if ("巡检工单".equals(e.getType())){
+//                String deviceInfo = iotInspectOrderDeviceMapper.getDeviceInfo(e.getId());
+//                e.setDevice(deviceInfo);
+//            } else if ("运行记录".equals(e.getType())) {
+//                List<IotOpeationFillDO> orderId = iotOpeationFillMapper.getListByOrderId(e.getId());
+//                StringJoiner joiner = new StringJoiner(", ");
+//                for (IotOpeationFillDO fillDO : orderId) {
+//                    joiner.add(fillDO.getDeviceCode() + "/" + fillDO.getDeviceName());
+//                }
+//                e.setDevice(joiner.toString());
+//            }  else if ("保养工单".equals(e.getType())) {
+//                if (orderPair.containsKey(e.getId())) {
+//                    e.setDevice(orderPair.get(e.getId()));
+//                }
+//            } else if ("瑞都日报".equals(e.getType()) || "瑞鹰日报".equals(e.getType()) || "瑞恒日报".equals(e.getType())) {
+//                // 设置日报的设备信息
+//                if (taskDevicesStrPair.containsKey(e.getTaskId())) {
+//                    e.setDevice(taskDevicesStrPair.get(e.getTaskId()));
+//                }
+//            }
+//            return e;
+//        }).collect(Collectors.toList());
+        ExcelUtils.write(response, "工单完成情况.xls", "数据", AllOrderResp.class, allOrder);
+    }
 }

+ 14 - 3
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/stat/vo/AllOrderResp.java

@@ -1,21 +1,32 @@
 package cn.iocoder.yudao.module.pms.controller.admin.stat.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
 import lombok.Data;
 
 @Data
+@ExcelIgnoreUnannotated
 public class AllOrderResp {
     private Long id;
     private Long taskId;
+    @ExcelProperty("工单类别")
+    private String type;
     private String title;
-    private String status;
     private String person;
-    private String type;
+    @ExcelProperty("生成日期")
     private String createTime;
+    @ExcelProperty("公司")
     private String company;
+    @ExcelProperty("项目部")
     private String project;
+    @ExcelProperty("队伍")
+    private String deptName;
+    @ExcelProperty("状态")
+    private String status;
+    @ExcelProperty("设备")
     private String deviceInfo;
     private Long deptId;
-    private String deptName;
+
     private String device;
     private Long num;
 }

+ 2 - 7
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/maintain/IotMaintainMapper.java

@@ -4,18 +4,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
-import cn.iocoder.yudao.module.pms.controller.admin.inspect.item.vo.IotInspectItemPageReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder.vo.IotMainWorkOrderPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.AllOrderResp;
 import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.OrderVo;
 import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.ReportCost;
-import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.failure.IotFailureReportDO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectItemDO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.material.IotMaintainMaterialDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.commons.lang3.StringUtils;
@@ -101,6 +94,8 @@ public interface IotMaintainMapper extends BaseMapperX<IotMaintainDO> {
     List<AllOrderResp> selectStatusNumber(@Param("reqVO") IotMaintainPageReqVO reqVO);
     @TenantIgnore
     IPage<AllOrderResp> getAllOrder(IPage<IotMaintainPageReqVO> page, @Param("reqVO") IotMaintainPageReqVO reqVO);
+    @TenantIgnore
+    List<AllOrderResp> getAllOrderNoPage(@Param("reqVO") IotMaintainPageReqVO reqVO);
 
     BigDecimal getMaintainFee(@Param("reqVO") IotMaintainPageReqVO reqVO);
     BigDecimal getMaintainFeeIn(@Param("reqVO") IotMaintainPageReqVO reqVO);

+ 363 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotMaintainMapper.xml

@@ -143,6 +143,369 @@
 
         group by status
     </select>
+    <select id="getAllOrderNoPage" parameterType="cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO"
+            resultType="cn.iocoder.yudao.module.pms.controller.admin.stat.vo.AllOrderResp">
+        select * from (
+        select a.id,'维修工单' as type,
+        '' as taskId,
+        a.create_time as createTime,
+        CASE
+        WHEN a.status = 'todo' THEN '未完成'
+        WHEN a.status = 'finished' THEN '已完成'
+        WHEN a.status = 'ignore' THEN '忽略'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status,concat(a.device_code,'|',a.device_name) as device, a.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_maintain a
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON a.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            a.deleted=0
+            <if test="reqVO.createTime[0] != null">
+                AND a.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND a.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND a.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+        UNION ALL
+        select b.id,'巡检工单' as type,
+        '' as taskId,
+        b.create_time as createTime,
+        CASE
+        WHEN b.status = 'todo' THEN '未完成'
+        WHEN b.status = 'finished' THEN '已完成'
+        WHEN b.status = 'ignore' THEN '忽略'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status, '' as device,b.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_inspect_order b
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON b.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            b.deleted=0
+            <if test="reqVO.createTime[0] != null">
+                AND b.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND b.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND b.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+
+        UNION ALL
+
+        SELECT
+        c.id,'运行记录' AS type,
+        '' AS taskId,
+        c.create_time AS createTime,
+        -- 核心优化:status 数值转中文描述
+        CASE
+        WHEN c.order_status = 0 THEN '未完成'
+        WHEN c.order_status = 1 THEN '已完成'
+        WHEN c.order_status = 2 THEN '填写中'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status,
+        '' AS device,
+        c.dept_id AS deptId,
+        -- 按type规则填充company字段
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        FROM rq_iot_opeation_fill_order c
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON c.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            c.deleted=0
+            <if test="reqVO.createTime[0] != null">
+                AND c.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND c.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND c.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+        union all
+
+        select b.id,'保养工单' as type,
+        '' as taskId,
+        b.create_time as createTime,
+        CASE
+        WHEN b.result = 1 THEN '未完成'
+        WHEN b.result = 2 THEN '已完成'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status, '' as device,b.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_main_work_order b
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON b.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            b.deleted = 0
+            <if test="reqVO.createTime[0] != null">
+                AND b.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND b.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND b.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+
+        UNION ALL
+
+        select b.id,'瑞恒日报' as type,
+        b.task_id as taskId,
+        b.create_time as createTime,
+        CASE
+        WHEN b.status = 0 THEN '未完成'
+        WHEN b.status = 1 THEN '已完成'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status, '' as device,b.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_rh_daily_report b
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON b.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            b.deleted = 0
+            <if test="reqVO.createTime[0] != null">
+                AND b.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND b.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND b.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+
+        UNION ALL
+
+        select b.id,'瑞鹰日报' as type,
+        b.task_id taskId,
+        b.create_time as createTime,
+        CASE
+        WHEN b.status = 0 THEN '未完成'
+        WHEN b.status = 1 THEN '已完成'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status, '' as device,b.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_ry_daily_report b
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON b.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            b.deleted = 0
+            <if test="reqVO.createTime[0] != null">
+                AND b.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND b.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND b.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+
+        UNION ALL
+
+        select b.id,'瑞都日报' as type,
+        b.task_id as taskId,
+        b.create_time as createTime,
+        CASE
+        WHEN b.status = 0 THEN '未完成'
+        WHEN b.status = 1 THEN '已完成'
+        ELSE '' -- 兼容其他未知状态值
+        END AS status, '' as device,b.dept_id as deptId,
+        CASE
+        WHEN d.type = 1 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 2 THEN COALESCE(p1.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p2.`name`, '')
+        ELSE ''
+        END AS company,
+        -- 按type规则填充project字段
+        CASE
+        WHEN d.type = 2 THEN COALESCE(d.`name`, '')
+        WHEN d.type = 3 THEN COALESCE(p1.`name`, '')
+        ELSE ''
+        END AS project,
+        -- 按type规则填充deptName字段(仅type=3时有值)
+        CASE
+        WHEN d.type = 3 THEN COALESCE(d.`name`, '')
+        ELSE ''
+        END AS deptName
+        from rq_iot_rd_daily_report b
+        -- 左关联当前部门(避免主表数据丢失)
+        LEFT JOIN system_dept d ON b.dept_id = d.id
+        -- 左关联父级部门(type=2/3时用)
+        LEFT JOIN system_dept p1 ON d.parent_id = p1.id
+        -- 左关联祖父级部门(type=3时用)
+        LEFT JOIN system_dept p2 ON p1.parent_id = p2.id
+        <where>
+            b.deleted = 0
+            <if test="reqVO.createTime[0] != null">
+                AND b.create_time &gt;= #{reqVO.createTime[0]}
+            </if>
+            <if test="reqVO.createTime.length > 1 and reqVO.createTime[1] != null">
+                AND b.create_time &lt;= #{reqVO.createTime[1]}
+            </if>
+            <if test="reqVO.deptIds != null and reqVO.deptIds.size &gt; 0">
+                AND b.dept_id IN
+                <foreach collection="reqVO.deptIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+        </where>
+
+        ) fin
+        <where>
+            <if test="reqVO.type != null">
+                AND fin.type LIKE concat("%",#{reqVO.type},"%")
+            </if>
+        </where>
+    </select>
     <select id="getAllOrder" parameterType="cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO"
             resultType="cn.iocoder.yudao.module.pms.controller.admin.stat.vo.AllOrderResp">
 select * from (