Переглянути джерело

pms 保养查询性能优化

zhangcl 1 день тому
батько
коміт
73a0e8605a
18 змінених файлів з 873 додано та 112 видалено
  1. 1 0
      yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstant.java
  2. 93 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/IotDeviceMaxRunLogController.java
  3. 79 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogPageReqVO.java
  4. 92 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogRespVO.java
  5. 67 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogSaveReqVO.java
  6. 2 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmaintenancebom/vo/IotMaintenanceBomPageReqVO.java
  7. 101 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotdevicemaxrunlog/IotDeviceMaxRunLogDO.java
  8. 4 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/IotDeviceMapper.java
  9. 41 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotdevicemaxrunlog/IotDeviceMaxRunLogMapper.java
  10. 7 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotdevicerunlog/IotDeviceRunLogMapper.java
  11. 11 2
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmaintenancebom/IotMaintenanceBomMapper.java
  12. 55 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicemaxrunlog/IotDeviceMaxRunLogService.java
  13. 71 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicemaxrunlog/IotDeviceMaxRunLogServiceImpl.java
  14. 50 1
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicerunlog/IotDeviceRunLogService.java
  15. 75 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicerunlog/IotDeviceRunLogServiceImpl.java
  16. 69 108
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorder/IotMainWorkOrderServiceImpl.java
  17. 35 0
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceMapper.xml
  18. 20 1
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceRunLogMapper.xml

+ 1 - 0
yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstant.java

@@ -108,4 +108,5 @@ public interface ErrorCodeConstant{
     ErrorCode IOT_OPERATION_MEETING_EXISTS = new ErrorCode(281, "当期生产运营会已经存在");
     ErrorCode IOT_OPERATION_MEETING_DETAIL_NOT_EXISTS = new ErrorCode(282, "生产运营会明细不存在");
     ErrorCode IOT_OPERATION_MEETING_ATTRS_NOT_EXISTS = new ErrorCode(284, "专业公司工作量扩展属性不存在");
+    ErrorCode IOT_DEVICE_MAX_RUN_LOG_NOT_EXISTS = new ErrorCode(285, "设备运行数据记录最大值不存在");
 }

+ 93 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/IotDeviceMaxRunLogController.java

@@ -0,0 +1,93 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog;
+
+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.object.BeanUtils;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicemaxrunlog.IotDeviceMaxRunLogDO;
+import cn.iocoder.yudao.module.pms.service.iotdevicemaxrunlog.IotDeviceMaxRunLogService;
+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.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+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("/pms/iot-device-max-run-log")
+@Validated
+public class IotDeviceMaxRunLogController {
+
+    @Resource
+    private IotDeviceMaxRunLogService iotDeviceMaxRunLogService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建设备运行数据记录最大值")
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:create')")
+    public CommonResult<Long> createIotDeviceMaxRunLog(@Valid @RequestBody IotDeviceMaxRunLogSaveReqVO createReqVO) {
+        return success(iotDeviceMaxRunLogService.createIotDeviceMaxRunLog(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新设备运行数据记录最大值")
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:update')")
+    public CommonResult<Boolean> updateIotDeviceMaxRunLog(@Valid @RequestBody IotDeviceMaxRunLogSaveReqVO updateReqVO) {
+        iotDeviceMaxRunLogService.updateIotDeviceMaxRunLog(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除设备运行数据记录最大值")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:delete')")
+    public CommonResult<Boolean> deleteIotDeviceMaxRunLog(@RequestParam("id") Long id) {
+        iotDeviceMaxRunLogService.deleteIotDeviceMaxRunLog(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得设备运行数据记录最大值")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:query')")
+    public CommonResult<IotDeviceMaxRunLogRespVO> getIotDeviceMaxRunLog(@RequestParam("id") Long id) {
+        IotDeviceMaxRunLogDO iotDeviceMaxRunLog = iotDeviceMaxRunLogService.getIotDeviceMaxRunLog(id);
+        return success(BeanUtils.toBean(iotDeviceMaxRunLog, IotDeviceMaxRunLogRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得设备运行数据记录最大值分页")
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:query')")
+    public CommonResult<PageResult<IotDeviceMaxRunLogRespVO>> getIotDeviceMaxRunLogPage(@Valid IotDeviceMaxRunLogPageReqVO pageReqVO) {
+        PageResult<IotDeviceMaxRunLogDO> pageResult = iotDeviceMaxRunLogService.getIotDeviceMaxRunLogPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, IotDeviceMaxRunLogRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出设备运行数据记录最大值 Excel")
+    @PreAuthorize("@ss.hasPermission('pms:iot-device-max-run-log:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIotDeviceMaxRunLogExcel(@Valid IotDeviceMaxRunLogPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IotDeviceMaxRunLogDO> list = iotDeviceMaxRunLogService.getIotDeviceMaxRunLogPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "设备运行数据记录最大值.xls", "数据", IotDeviceMaxRunLogRespVO.class,
+                        BeanUtils.toBean(list, IotDeviceMaxRunLogRespVO.class));
+    }
+
+}

+ 79 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogPageReqVO.java

@@ -0,0 +1,79 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 设备运行数据记录最大值分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class IotDeviceMaxRunLogPageReqVO extends PageParam {
+
+    @Schema(description = "部门id 所属小队", example = "20503")
+    private Long deptId;
+
+    @Schema(description = "设备id", example = "14276")
+    private Long deviceId;
+
+    @Schema(description = "设备编码")
+    private String deviceCode;
+
+    @Schema(description = "设备部件")
+    private String deviceComp;
+
+    @Schema(description = "采集点位 信息 code")
+    private String pointCode;
+
+    @Schema(description = "采集点位信息 名称", example = "张三")
+    private String pointName;
+
+    @Schema(description = "数据类型 1手动填报 2自动采集", example = "2")
+    private Integer type;
+
+    @Schema(description = "设备运行记录值 运行公里数km 运行公里数H")
+    private BigDecimal value;
+
+    @Schema(description = "填报时间 or 采集时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] time;
+
+    @Schema(description = "当日运行时间 H")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private BigDecimal[] dailyRunTime;
+
+    @Schema(description = "累计运行时间 H")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private BigDecimal[] totalRunTime;
+
+    @Schema(description = "当日运行里程 H")
+    private BigDecimal dailyMileage;
+
+    @Schema(description = "累计运行里程 H")
+    private BigDecimal totalMileage;
+
+    @Schema(description = "备注", example = "你说的对")
+    private String remark;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    @Schema(description = "填写内容")
+    private String fillContent;
+
+    @Schema(description = "累计属性id", example = "25336")
+    private Long sumId;
+
+    @Schema(description = "是否累计值")
+    private Integer isSum;
+
+}

+ 92 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogRespVO.java

@@ -0,0 +1,92 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 设备运行数据记录最大值 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotDeviceMaxRunLogRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9055")
+    @ExcelProperty("主键id")
+    private Long id;
+
+    @Schema(description = "部门id 所属小队", example = "20503")
+    @ExcelProperty("部门id 所属小队")
+    private Long deptId;
+
+    @Schema(description = "设备id", example = "14276")
+    @ExcelProperty("设备id")
+    private Long deviceId;
+
+    @Schema(description = "设备编码")
+    @ExcelProperty("设备编码")
+    private String deviceCode;
+
+    @Schema(description = "设备部件")
+    @ExcelProperty("设备部件")
+    private String deviceComp;
+
+    @Schema(description = "采集点位 信息 code")
+    @ExcelProperty("采集点位 信息 code")
+    private String pointCode;
+
+    @Schema(description = "采集点位信息 名称", example = "张三")
+    @ExcelProperty("采集点位信息 名称")
+    private String pointName;
+
+    @Schema(description = "数据类型 1手动填报 2自动采集", example = "2")
+    @ExcelProperty("数据类型 1手动填报 2自动采集")
+    private Integer type;
+
+    @Schema(description = "设备运行记录值 运行公里数km 运行公里数H")
+    @ExcelProperty("设备运行记录值 运行公里数km 运行公里数H")
+    private BigDecimal value;
+
+    @Schema(description = "填报时间 or 采集时间")
+    @ExcelProperty("填报时间 or 采集时间")
+    private LocalDateTime time;
+
+    @Schema(description = "当日运行时间 H")
+    @ExcelProperty("当日运行时间 H")
+    private BigDecimal dailyRunTime;
+
+    @Schema(description = "累计运行时间 H")
+    @ExcelProperty("累计运行时间 H")
+    private BigDecimal totalRunTime;
+
+    @Schema(description = "当日运行里程 H")
+    @ExcelProperty("当日运行里程 H")
+    private BigDecimal dailyMileage;
+
+    @Schema(description = "累计运行里程 H")
+    @ExcelProperty("累计运行里程 H")
+    private BigDecimal totalMileage;
+
+    @Schema(description = "备注", example = "你说的对")
+    @ExcelProperty("备注")
+    private String remark;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "填写内容")
+    @ExcelProperty("填写内容")
+    private String fillContent;
+
+    @Schema(description = "累计属性id", example = "25336")
+    @ExcelProperty("累计属性id")
+    private Long sumId;
+
+    @Schema(description = "是否累计值")
+    @ExcelProperty("是否累计值")
+    private Integer isSum;
+
+}

+ 67 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicemaxrunlog/vo/IotDeviceMaxRunLogSaveReqVO.java

@@ -0,0 +1,67 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 设备运行数据记录最大值新增/修改 Request VO")
+@Data
+public class IotDeviceMaxRunLogSaveReqVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9055")
+    private Long id;
+
+    @Schema(description = "部门id 所属小队", example = "20503")
+    private Long deptId;
+
+    @Schema(description = "设备id", example = "14276")
+    private Long deviceId;
+
+    @Schema(description = "设备编码")
+    private String deviceCode;
+
+    @Schema(description = "设备部件")
+    private String deviceComp;
+
+    @Schema(description = "采集点位 信息 code")
+    private String pointCode;
+
+    @Schema(description = "采集点位信息 名称", example = "张三")
+    private String pointName;
+
+    @Schema(description = "数据类型 1手动填报 2自动采集", example = "2")
+    private Integer type;
+
+    @Schema(description = "设备运行记录值 运行公里数km 运行公里数H")
+    private BigDecimal value;
+
+    @Schema(description = "填报时间 or 采集时间")
+    private LocalDateTime time;
+
+    @Schema(description = "当日运行时间 H")
+    private BigDecimal dailyRunTime;
+
+    @Schema(description = "累计运行时间 H")
+    private BigDecimal totalRunTime;
+
+    @Schema(description = "当日运行里程 H")
+    private BigDecimal dailyMileage;
+
+    @Schema(description = "累计运行里程 H")
+    private BigDecimal totalMileage;
+
+    @Schema(description = "备注", example = "你说的对")
+    private String remark;
+
+    @Schema(description = "填写内容")
+    private String fillContent;
+
+    @Schema(description = "累计属性id", example = "25336")
+    private Long sumId;
+
+    @Schema(description = "是否累计值")
+    private Integer isSum;
+
+}

+ 2 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmaintenancebom/vo/IotMaintenanceBomPageReqVO.java

@@ -127,6 +127,8 @@ public class IotMaintenanceBomPageReqVO extends PageParam {
     @Schema(description = "保养计划id 集合", example = "181,182")
     private Collection<Long> planIds;
 
+    @Schema(description = "多种累计属性名称集合", example = "累计运行时间H,底盘发动机累计公里数KM")
+    private Collection<String> codesOrTypes;
 
     @Schema(description = "保养计划查询条件")
     private Long deptId;

+ 101 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotdevicemaxrunlog/IotDeviceMaxRunLogDO.java

@@ -0,0 +1,101 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicemaxrunlog;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 设备运行数据记录最大值 DO
+ *
+ * @author ruiqi
+ */
+@TableName("rq_iot_device_max_run_log")
+@KeySequence("rq_iot_device_max_run_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotDeviceMaxRunLogDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long id;
+    /**
+     * 部门id 所属小队
+     */
+    private Long deptId;
+    /**
+     * 设备id
+     */
+    private Long deviceId;
+    /**
+     * 设备编码
+     */
+    private String deviceCode;
+    /**
+     * 设备部件
+     */
+    private String deviceComp;
+    /**
+     * 采集点位 信息 code
+     */
+    private String pointCode;
+    /**
+     * 采集点位信息 名称
+     */
+    private String pointName;
+    /**
+     * 数据类型 1手动填报 2自动采集
+     */
+    private Integer type;
+    /**
+     * 设备运行记录值 运行公里数km 运行公里数H
+     */
+    private BigDecimal value;
+    /**
+     * 填报时间 or 采集时间
+     */
+    private LocalDateTime time;
+    /**
+     * 当日运行时间 H
+     */
+    private BigDecimal dailyRunTime;
+    /**
+     * 累计运行时间 H
+     */
+    private BigDecimal totalRunTime;
+    /**
+     * 当日运行里程 H
+     */
+    private BigDecimal dailyMileage;
+    /**
+     * 累计运行里程 H
+     */
+    private BigDecimal totalMileage;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 填写内容
+     */
+    private String fillContent;
+    /**
+     * 累计属性id
+     */
+    private Long sumId;
+    /**
+     * 是否累计值
+     */
+    private Integer isSum;
+
+}

+ 4 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/IotDeviceMapper.java

@@ -355,6 +355,10 @@ public interface IotDeviceMapper extends BaseMapperX<IotDeviceDO> {
     List<IotDeviceRespVO> deviceAlarmDistances(@Param("sortedDeviceIds") Collection<Long> sortedDeviceIds,
                                            @Param("deviceIds") Collection<Long> deviceIds,
                                            @Param("mainBomDeviceIds") Collection<Long> mainBomDeviceIds);
+
+    List<IotDeviceRespVO> deviceAlarmDistancesSearch(@Param("sortedDeviceIds") Collection<Long> sortedDeviceIds,
+                                               @Param("mainBomDeviceIds") Collection<Long> mainBomDeviceIds);
+
     List<IotDeviceSimple> selectCodeAndNameList();
     List<IotDeviceSimple> selectTypeNumber(@Param("reqVO") IotDevicePageReqVO reqVO,@Param("products") List<Integer> products);
     List<IotDeviceRespVO> selectExport(@Param("reqVO") IotDevicePageReqVO reqVO);

+ 41 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotdevicemaxrunlog/IotDeviceMaxRunLogMapper.java

@@ -0,0 +1,41 @@
+package cn.iocoder.yudao.module.pms.dal.mysql.iotdevicemaxrunlog;
+
+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.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicemaxrunlog.IotDeviceMaxRunLogDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 设备运行数据记录最大值 Mapper
+ *
+ * @author ruiqi
+ */
+@Mapper
+public interface IotDeviceMaxRunLogMapper extends BaseMapperX<IotDeviceMaxRunLogDO> {
+
+    default PageResult<IotDeviceMaxRunLogDO> selectPage(IotDeviceMaxRunLogPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IotDeviceMaxRunLogDO>()
+                .eqIfPresent(IotDeviceMaxRunLogDO::getDeptId, reqVO.getDeptId())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getDeviceId, reqVO.getDeviceId())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getDeviceCode, reqVO.getDeviceCode())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getDeviceComp, reqVO.getDeviceComp())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getPointCode, reqVO.getPointCode())
+                .likeIfPresent(IotDeviceMaxRunLogDO::getPointName, reqVO.getPointName())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getType, reqVO.getType())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getValue, reqVO.getValue())
+                .betweenIfPresent(IotDeviceMaxRunLogDO::getTime, reqVO.getTime())
+                .betweenIfPresent(IotDeviceMaxRunLogDO::getDailyRunTime, reqVO.getDailyRunTime())
+                .betweenIfPresent(IotDeviceMaxRunLogDO::getTotalRunTime, reqVO.getTotalRunTime())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getDailyMileage, reqVO.getDailyMileage())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getTotalMileage, reqVO.getTotalMileage())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(IotDeviceMaxRunLogDO::getCreateTime, reqVO.getCreateTime())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getFillContent, reqVO.getFillContent())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getSumId, reqVO.getSumId())
+                .eqIfPresent(IotDeviceMaxRunLogDO::getIsSum, reqVO.getIsSum())
+                .orderByDesc(IotDeviceMaxRunLogDO::getId));
+    }
+
+}

+ 7 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotdevicerunlog/IotDeviceRunLogMapper.java

@@ -57,6 +57,13 @@ public interface IotDeviceRunLogMapper extends BaseMapperX<IotDeviceRunLogDO> {
                                                 @Param("deviceCategoryIds") Collection<Long> deviceCategoryIds,
                                                 @Param("actualStartTime") String actualStartTime);
 
+    /**
+     * 查询指定设备 运行记录模板属性对应的累计时长 累计里程
+     * @param deviceIds
+     * @return
+     */
+    List<IotDeviceRunLogRespVO> distinctDevicesSearch(@Param("deviceIds") Collection<Long> deviceIds);
+
     /**
      * 查询运行记录模板中正常的累积类型属性
      * @param deviceCategoryIds

+ 11 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmaintenancebom/IotMaintenanceBomMapper.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.dal.mysql.iotmaintenancebom;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
@@ -58,7 +59,7 @@ public interface IotMaintenanceBomMapper extends BaseMapperX<IotMaintenanceBomDO
     }
 
     default List<IotMaintenanceBomDO> selectList(IotMaintenanceBomPageReqVO reqVO) {
-        return selectList(new LambdaQueryWrapperX<IotMaintenanceBomDO>()
+        LambdaQueryWrapperX<IotMaintenanceBomDO> wrapper = new LambdaQueryWrapperX<IotMaintenanceBomDO>()
                 .eqIfPresent(IotMaintenanceBomDO::getPlanId, reqVO.getPlanId())
                 .inIfPresent(IotMaintenanceBomDO::getPlanId, reqVO.getPlanIds())
                 .neIfPresent(IotMaintenanceBomDO::getPlanId, reqVO.getNotPlanId())
@@ -86,7 +87,15 @@ public interface IotMaintenanceBomMapper extends BaseMapperX<IotMaintenanceBomDO
                 .eqIfPresent(IotMaintenanceBomDO::getStatus, reqVO.getStatus())
                 .eqIfPresent(IotMaintenanceBomDO::getRemark, reqVO.getRemark())
                 .eqIfPresent(IotMaintenanceBomDO::getVersion, reqVO.getVersion())
-                .betweenIfPresent(IotMaintenanceBomDO::getCreateTime, reqVO.getCreateTime()));
+                .betweenIfPresent(IotMaintenanceBomDO::getCreateTime, reqVO.getCreateTime());
+
+        if (CollUtil.isNotEmpty(reqVO.getCodesOrTypes())) {
+            wrapper.and(w -> w.in(IotMaintenanceBomDO::getType, reqVO.getCodesOrTypes())
+                    .or()
+                    .in(IotMaintenanceBomDO::getCode, reqVO.getCodesOrTypes()));
+        }
+
+        return selectList(wrapper);
     }
 
     default List<IotMaintenanceBomDO> selectAlarmList(IotMaintenanceBomPageReqVO reqVO) {

+ 55 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicemaxrunlog/IotDeviceMaxRunLogService.java

@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.pms.service.iotdevicemaxrunlog;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicemaxrunlog.IotDeviceMaxRunLogDO;
+
+import javax.validation.Valid;
+
+/**
+ * 设备运行数据记录最大值 Service 接口
+ *
+ * @author ruiqi
+ */
+public interface IotDeviceMaxRunLogService {
+
+    /**
+     * 创建设备运行数据记录最大值
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotDeviceMaxRunLog(@Valid IotDeviceMaxRunLogSaveReqVO createReqVO);
+
+    /**
+     * 更新设备运行数据记录最大值
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotDeviceMaxRunLog(@Valid IotDeviceMaxRunLogSaveReqVO updateReqVO);
+
+    /**
+     * 删除设备运行数据记录最大值
+     *
+     * @param id 编号
+     */
+    void deleteIotDeviceMaxRunLog(Long id);
+
+    /**
+     * 获得设备运行数据记录最大值
+     *
+     * @param id 编号
+     * @return 设备运行数据记录最大值
+     */
+    IotDeviceMaxRunLogDO getIotDeviceMaxRunLog(Long id);
+
+    /**
+     * 获得设备运行数据记录最大值分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 设备运行数据记录最大值分页
+     */
+    PageResult<IotDeviceMaxRunLogDO> getIotDeviceMaxRunLogPage(IotDeviceMaxRunLogPageReqVO pageReqVO);
+
+}

+ 71 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicemaxrunlog/IotDeviceMaxRunLogServiceImpl.java

@@ -0,0 +1,71 @@
+package cn.iocoder.yudao.module.pms.service.iotdevicemaxrunlog;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicemaxrunlog.vo.IotDeviceMaxRunLogSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicemaxrunlog.IotDeviceMaxRunLogDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicemaxrunlog.IotDeviceMaxRunLogMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_DEVICE_MAX_RUN_LOG_NOT_EXISTS;
+
+/**
+ * 设备运行数据记录最大值 Service 实现类
+ *
+ * @author ruiqi
+ */
+@Service
+@Validated
+public class IotDeviceMaxRunLogServiceImpl implements IotDeviceMaxRunLogService {
+
+    @Resource
+    private IotDeviceMaxRunLogMapper iotDeviceMaxRunLogMapper;
+
+    @Override
+    public Long createIotDeviceMaxRunLog(IotDeviceMaxRunLogSaveReqVO createReqVO) {
+        // 插入
+        IotDeviceMaxRunLogDO iotDeviceMaxRunLog = BeanUtils.toBean(createReqVO, IotDeviceMaxRunLogDO.class);
+        iotDeviceMaxRunLogMapper.insert(iotDeviceMaxRunLog);
+        // 返回
+        return iotDeviceMaxRunLog.getId();
+    }
+
+    @Override
+    public void updateIotDeviceMaxRunLog(IotDeviceMaxRunLogSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotDeviceMaxRunLogExists(updateReqVO.getId());
+        // 更新
+        IotDeviceMaxRunLogDO updateObj = BeanUtils.toBean(updateReqVO, IotDeviceMaxRunLogDO.class);
+        iotDeviceMaxRunLogMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotDeviceMaxRunLog(Long id) {
+        // 校验存在
+        validateIotDeviceMaxRunLogExists(id);
+        // 删除
+        iotDeviceMaxRunLogMapper.deleteById(id);
+    }
+
+    private void validateIotDeviceMaxRunLogExists(Long id) {
+        if (iotDeviceMaxRunLogMapper.selectById(id) == null) {
+            throw exception(IOT_DEVICE_MAX_RUN_LOG_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IotDeviceMaxRunLogDO getIotDeviceMaxRunLog(Long id) {
+        return iotDeviceMaxRunLogMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<IotDeviceMaxRunLogDO> getIotDeviceMaxRunLogPage(IotDeviceMaxRunLogPageReqVO pageReqVO) {
+        return iotDeviceMaxRunLogMapper.selectPage(pageReqVO);
+    }
+
+}

+ 50 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicerunlog/IotDeviceRunLogService.java

@@ -63,6 +63,13 @@ public interface IotDeviceRunLogService {
      */
     List<IotDeviceRunLogRespVO> distinctDevices(List<Long> ids, List<Long> deviceCategoryIds, Map<Long, Long> deviceCategoryPair, String actualStartTime);
 
+    /**
+     * 设备的运行记录信息 保养查询使用
+     *
+     * @return 设备运行数据记录
+     */
+    List<IotDeviceRunLogRespVO> distinctDevicesSearch(List<Long> ids, List<Long> deviceCategoryIds, Map<Long, Long> deviceCategoryPair, List<IotDeviceRunLogRespVO> runLogs);
+
     /**
      * 查询指定设备 运行记录模板属性对应的累计时长 累计里程
      * @param deviceIds
@@ -70,6 +77,13 @@ public interface IotDeviceRunLogService {
      */
     List<IotDeviceRunLogRespVO> multipleAccumulatedData(Collection<Long> deviceIds, Collection<String> attrNames, String actualStartTime);
 
+    /**
+     * 查询指定设备 运行记录模板属性对应的累计时长 累计里程 保养查询使用
+     * @param deviceIds
+     * @return
+     */
+    List<IotDeviceRunLogRespVO> deviceAttrRunLogsSearch(List<Long> deviceIds);
+
     /**
      * 根据设备id查询设备关联信息
      *
@@ -111,7 +125,7 @@ public interface IotDeviceRunLogService {
      * @return 设备bom 关联 列表
      */
     default Map<Long, IotDeviceRunLogRespVO> getDeviceRunLogMapAlone(List<Long> ids, List<Long> deviceCategoryIds,
-                                                                     Map<Long, Long> deviceCategoryPair, String actualStartTime){
+                                                                     Map<Long, Long> deviceCategoryPair, String actualStartTime) {
         List<IotDeviceRunLogRespVO> list = distinctDevices(ids, deviceCategoryIds, deviceCategoryPair, actualStartTime);
         // 删除集合中的NULL元素
         list.removeIf(deviceLog -> isAllFieldsNull(deviceLog));
@@ -139,6 +153,41 @@ public interface IotDeviceRunLogService {
         return CollectionUtils.convertMap(mergedList, IotDeviceRunLogRespVO::getDeviceId);
     }
 
+    /**
+     * 根据设备id查询设备关联信息
+     *
+     * @param ids 设备id集合
+     * @return 设备bom 关联 列表
+     */
+    default Map<Long, IotDeviceRunLogRespVO> getDeviceRunLogMapSearch(List<Long> ids, List<Long> deviceCategoryIds,
+                                                                     Map<Long, Long> deviceCategoryPair, List<IotDeviceRunLogRespVO> runLogs) {
+        List<IotDeviceRunLogRespVO> list = distinctDevicesSearch(ids, deviceCategoryIds, deviceCategoryPair, runLogs);
+        // 删除集合中的NULL元素
+        list.removeIf(deviceLog -> isAllFieldsNull(deviceLog));
+        // 暂时将查询出的2条记录设置为1条
+        // device_id	total_run_time	total_mileage	point_name				point_code
+        // 136			2444.00			0.00			台上发动机累计运转时长	    sc
+        // 136			0.00			16510.00		底盘发动机累计公里数	    gls
+        // 按 deviceId 分组并合并数据
+        Map<Long, IotDeviceRunLogRespVO> mergedMap = new HashMap<>();
+        for (IotDeviceRunLogRespVO log : list) {
+            Long deviceId = log.getDeviceId();
+            // 跳过无效设备ID
+            if (deviceId == null) continue;
+
+            if (mergedMap.containsKey(deviceId)) {
+                // 合并已有记录
+                IotDeviceRunLogRespVO existing = mergedMap.get(deviceId);
+                mergeLogRecords(existing, log);
+            } else {
+                // 首次遇到该设备ID,直接放入Map
+                mergedMap.put(deviceId, log);
+            }
+        }
+        List<IotDeviceRunLogRespVO> mergedList = new ArrayList<>(mergedMap.values());
+        return CollectionUtils.convertMap(mergedList, IotDeviceRunLogRespVO::getDeviceId);
+    }
+
     // 检查是否所有字段都为NULL的辅助方法
     default boolean isAllFieldsNull(IotDeviceRunLogRespVO deviceLog) {
         return ObjectUtil.isEmpty(deviceLog.getDeviceId());

+ 75 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicerunlog/IotDeviceRunLogServiceImpl.java

@@ -1,18 +1,21 @@
 package cn.iocoder.yudao.module.pms.service.iotdevicerunlog;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicerunlog.IotDeviceRunLogDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicemaxrunlog.IotDeviceMaxRunLogMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicerunlog.IotDeviceRunLogMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 
+import java.math.BigDecimal;
 import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -29,6 +32,8 @@ public class IotDeviceRunLogServiceImpl implements IotDeviceRunLogService {
 
     @Resource
     private IotDeviceRunLogMapper iotDeviceRunLogMapper;
+    @Resource
+    private IotDeviceMaxRunLogMapper iotDeviceMaxRunLogMapper;
 
     @Override
     public Long createIotDeviceRunLog(IotDeviceRunLogSaveReqVO createReqVO) {
@@ -97,9 +102,79 @@ public class IotDeviceRunLogServiceImpl implements IotDeviceRunLogService {
         return normalAttrDeviceRunLogs;
     }
 
+    @Override
+    public List<IotDeviceRunLogRespVO> distinctDevicesSearch(List<Long> ids, List<Long> deviceCategoryIds,
+                                                       Map<Long, Long> deviceCategoryPair, List<IotDeviceRunLogRespVO> runLogs) {
+        // 先根据设备分类集合查询出所有正常累积的 公里数 时长
+        List<IotDeviceRunLogRespVO> normalCumulativeAttrs = iotDeviceRunLogMapper.normalCumulativeAttrs(deviceCategoryIds);
+        Set<Long> categoryIds = new HashSet<>();
+        // key设备类别id   value单累计属性对象集合
+        Map<Long, List<IotDeviceRunLogRespVO>> deviceCategoryRunLogPair = new HashMap<>();
+        if (CollUtil.isNotEmpty(normalCumulativeAttrs)) {
+            normalCumulativeAttrs.forEach(attr -> {
+                categoryIds.add(attr.getDeviceCategoryId());
+                Long categoryId = attr.getDeviceCategoryId();
+                if (deviceCategoryRunLogPair.containsKey(categoryId)) {
+                    List<IotDeviceRunLogRespVO> tempRunLogs = deviceCategoryRunLogPair.get(categoryId);
+                    tempRunLogs.add(attr);
+                    deviceCategoryRunLogPair.put(categoryId, tempRunLogs);
+                } else {
+                    List<IotDeviceRunLogRespVO> tempRunLogs = new ArrayList<>();
+                    tempRunLogs.add(attr);
+                    deviceCategoryRunLogPair.put(categoryId, tempRunLogs);
+                }
+            });
+        }
+        List<IotDeviceRunLogRespVO> normalAttrDeviceRunLogs = new ArrayList<>();
+        if (CollUtil.isNotEmpty(runLogs)) {
+            runLogs.forEach(runLog -> {
+                if (deviceCategoryPair.containsKey(runLog.getDeviceId())) {
+                    Long deviceCategoryId = deviceCategoryPair.get(runLog.getDeviceId());
+                    if (categoryIds.contains(deviceCategoryId)) {
+                        if (deviceCategoryRunLogPair.containsKey(deviceCategoryId)) {
+                            List<IotDeviceRunLogRespVO> categoryRunLogs = deviceCategoryRunLogPair.get(deviceCategoryId);
+                            categoryRunLogs.forEach(log -> {
+                                if (("sc".equals(log.getPointCode()) || "gls".equals(log.getPointCode())) && runLog.getPointName().equals(log.getPointName())) {
+                                    IotDeviceRunLogRespVO tempLog = new IotDeviceRunLogRespVO();
+                                    tempLog.setDeviceId(runLog.getDeviceId());
+                                    tempLog.setPointName(runLog.getPointName());
+                                    if ("sc".equals(log.getPointCode())) {
+                                        // 累计时长 属性
+                                        tempLog.setTotalRunTime(runLog.getTotalRunTime());
+                                        tempLog.setPointCode("sc");
+                                    }
+                                    if ("gls".equals(log.getPointCode())) {
+                                        // 累计公里数 属性
+                                        tempLog.setTotalMileage(runLog.getTotalRunTime());
+                                        tempLog.setPointCode("gls");
+                                    }
+                                    // 避免 totalRunTime totalMileage NULL 值
+                                    if (ObjUtil.isEmpty(tempLog.getTotalRunTime())) {
+                                        tempLog.setTotalRunTime(BigDecimal.ZERO);
+                                    }
+                                    if (ObjUtil.isEmpty(tempLog.getTotalMileage())) {
+                                        tempLog.setTotalMileage(BigDecimal.ZERO);
+                                    }
+                                    normalAttrDeviceRunLogs.add(tempLog);
+                                }
+                            });
+                        }
+                    }
+                }
+            });
+        }
+        return normalAttrDeviceRunLogs;
+    }
+
     @Override
     public List<IotDeviceRunLogRespVO> multipleAccumulatedData(Collection<Long> deviceIds, Collection<String> attrNames, String actualStartTime) {
         return iotDeviceRunLogMapper.multipleAccumulatedData(deviceIds, attrNames, actualStartTime);
     }
 
+    @Override
+    public List<IotDeviceRunLogRespVO> deviceAttrRunLogsSearch(List<Long> deviceIds) {
+        List<IotDeviceRunLogRespVO> multiTotalAttrRunLogs = iotDeviceRunLogMapper.distinctDevicesSearch(deviceIds);;
+        return multiTotalAttrRunLogs;
+    }
+
 }

+ 69 - 108
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorder/IotMainWorkOrderServiceImpl.java

@@ -11,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotlockstock.vo.IotLockStockPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotMaintenanceBomPageReqVO;
@@ -67,6 +68,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_MAIN_WORK_ORDER_EXECUTED;
 import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_MAIN_WORK_ORDER_NOT_EXISTS;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.DEPT_NOT_FOUND;
 
 /**
  * 保养工单 Service 实现类
@@ -397,42 +399,59 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
 
     @Override
     public PageResult<IotDeviceRespVO> deviceMainDistances(IotMainWorkOrderPageReqVO pageReqVO) {
+        // 左侧组织树 组织层级查询
+        Set<Long> ids = new HashSet<>();
+        if (ObjUtil.isEmpty(pageReqVO.getDeptId())) {
+            // 如果没有传 deptId 查询当前登录人所属部门id
+            Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
+            pageReqVO.setDeptId(loginUserDeptId);
+        }
+        Long deptId = pageReqVO.getDeptId();
+        ids = deptService.getChildDeptIdListFromCache(deptId);
+        ids.add(deptId);
+        if (CollUtil.isEmpty(ids)) {
+            return PageResult.empty();
+        }
+        // 查询条件 device_code 或 device_name
+        Set<Long> queryDeviceIds = new HashSet<>();
+        String deviceCode = pageReqVO.getDeviceCode();
+        String deviceName = pageReqVO.getDeviceName();
+
+        Set<Long> deviceCategoryIds = new HashSet<>();
+        Map<Long, Long> deviceCategoryPair = new HashMap<>();
+
+        // 需要根据查询条件中的设备查询对应的保养计划明细 运行记录累计值
+        IotDevicePageReqVO reqVO = new IotDevicePageReqVO();
+        if (StrUtil.isNotBlank(deviceCode)) {
+            reqVO.setDeviceCode(deviceCode);
+        }
+        if (StrUtil.isNotBlank(deviceName)) {
+            reqVO.setDeviceName(deviceName);
+        }
+        reqVO.setDeptIds(new ArrayList<>(ids));
+        List<IotDeviceDO> qualifiedDevices = iotDeviceMapper.selectList(reqVO);
+        if (CollUtil.isNotEmpty(qualifiedDevices)) {
+            qualifiedDevices.forEach(device -> {
+                queryDeviceIds.add(device.getId());
+                // 设置设备类别
+                deviceCategoryIds.add(device.getAssetClass());
+                deviceCategoryPair.put(device.getId(), device.getAssetClass());
+            });
+        }
+
         // 20250624 只查询保养计划中的设备 不查询保养工单表
         // 所有保养计划 + 保养工单 明细中待保养的最近距离 里程/时间/自然日
         // 查询所有保养工单明细中所有设备的累计运行里程 累计运行时间 如果保养项有设置 里程/时间规则 可以计算保养距离
-        IotMainWorkOrderBomPageReqVO bomReqVO = new IotMainWorkOrderBomPageReqVO();
-        // 不查询 已执行 临时创建 的工单
-        IotMainWorkOrderPageReqVO reqVO = new IotMainWorkOrderPageReqVO();
-        reqVO.setResult(1);
-        reqVO.setType(1);
-        List<Long> workOrderIds = new ArrayList<>();
-
-        List<IotMainWorkOrderBomDO> workOrderBomS = new ArrayList<>();
-        if (CollUtil.isNotEmpty(workOrderIds)) {
-            bomReqVO.setWorkOrderIds(workOrderIds);
-            workOrderBomS= iotMainWorkOrderBomMapper.selectList(bomReqVO);
-        }
-        Set<Long> deviceIds = CollUtil.isEmpty(workOrderBomS)
-                ? new HashSet<>()
-                : workOrderBomS.stream()
-                .map(IotMainWorkOrderBomDO::getDeviceId) // 获取 deviceId
-                .filter(Objects::nonNull)      // 过滤非空值
-                .collect(Collectors.toSet());  // 收集到 Set 中
-        Set<Long> orderDeviceIds = new HashSet<>();
-        orderDeviceIds.addAll(deviceIds);
+        Set<Long> deviceIds = new HashSet<>();  // 收集到 Set 中
         // 查询保养计划明细中不包含 deviceIds 的设备id集合
-        List<IotMaintenanceBomDO> mainBomS = new ArrayList<>();
         Set<Long> mainBomDeviceIds = new HashSet<>();
         IotMaintenanceBomPageReqVO mainBomReqVO = new IotMaintenanceBomPageReqVO();
-        if (CollUtil.isNotEmpty(deviceIds)) {
-            mainBomReqVO.setDeviceIds(new ArrayList<>(deviceIds));
-            mainBomS = iotMaintenanceBomMapper.selectAlarmList(mainBomReqVO);
-        } else {
-            mainBomS = iotMaintenanceBomMapper.selectList(mainBomReqVO);
+        if (CollUtil.isNotEmpty(queryDeviceIds)) {
+            mainBomReqVO.setDeviceIds(new ArrayList<>(queryDeviceIds));
         }
+        List<IotMaintenanceBomDO> mainBomS = iotMaintenanceBomMapper.selectList(mainBomReqVO);
         Set<String> boundedMultiAttrNames = new HashSet<>();
-        Set<Long> deviceCategoryIds = new HashSet<>();
-        Map<Long, Long> deviceCategoryPair = new HashMap<>();
+
         if (CollUtil.isNotEmpty(mainBomS)) {
             mainBomDeviceIds = CollUtil.isEmpty(mainBomS)
                     ? Collections.emptySet()
@@ -453,6 +472,7 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
             });
             // 查询所有设备类别id
             // 组装bom关联的设备信息
+            /*
             Map<Long, IotDeviceRespVO> deviceMap = iotDeviceService.getDeviceMap(convertListByFlatMap(mainBomS,
                     bom -> Stream.of(bom.getDeviceId())));
             if (CollUtil.isNotEmpty(deviceMap)) {
@@ -460,7 +480,7 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
                     deviceCategoryIds.add(v.getAssetClass());
                     deviceCategoryPair.put(k, v.getAssetClass());
                 });
-            }
+            } */
         }
         deviceIds.addAll(mainBomDeviceIds);
         if (CollUtil.isEmpty(deviceIds)){
@@ -470,8 +490,20 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
         // 查询 运行记录模板中包含多个累计 时长 公里数 属性的集合
         List<IotDeviceRunLogRespVO> multipleAccumulatedData = new ArrayList<>();
         if (CollUtil.isNotEmpty(deviceIds) && CollUtil.isNotEmpty(boundedMultiAttrNames)) {
-            multipleAccumulatedData = iotDeviceRunLogService.multipleAccumulatedData(deviceIds, boundedMultiAttrNames, null);
+            // multipleAccumulatedData = iotDeviceRunLogService.multipleAccumulatedData(deviceIds, boundedMultiAttrNames, null);
         }
+        List<IotDeviceRunLogRespVO> deviceAttrRunLogs = new ArrayList<>();
+        if (CollUtil.isNotEmpty(deviceIds)) {
+            deviceAttrRunLogs = iotDeviceRunLogService.deviceAttrRunLogsSearch(new ArrayList<>(deviceIds));
+            if (CollUtil.isNotEmpty(deviceAttrRunLogs) && CollUtil.isNotEmpty(boundedMultiAttrNames)) {
+                deviceAttrRunLogs.forEach(runLog -> {
+                    if (boundedMultiAttrNames.contains(runLog.getPointName())) {
+                        multipleAccumulatedData.add(runLog);
+                    }
+                });
+            }
+        }
+
         // key(设备id-累计时长属性名称)    value时长属性累计时长数值
         Map<String, BigDecimal> tempTotalRunDataPair = new HashMap<>();
         if (CollUtil.isNotEmpty(multipleAccumulatedData)) {
@@ -482,8 +514,11 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
         }
 
         // 查询 运行记录模板中 正常的累计时长 公里数集合
-        Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap =
-                iotDeviceRunLogService.getDeviceRunLogMapAlone(new ArrayList<>(deviceIds), new ArrayList<>(deviceCategoryIds), deviceCategoryPair, null);
+        Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = new HashMap<>();
+        if (CollUtil.isNotEmpty(deviceIds) && CollUtil.isNotEmpty(deviceCategoryIds)) {
+            deviceRunLogMap =
+                    iotDeviceRunLogService.getDeviceRunLogMapSearch(new ArrayList<>(deviceIds), new ArrayList<>(deviceCategoryIds), deviceCategoryPair, deviceAttrRunLogs);
+        }
         // 以设备为维度统计每个设备相关的保养项的最近保养距离 key设备id    value设备下每个保养项的的最小保养距离集合
         Map<Long, List<Map<String, Object>>> orderDistancePair = new HashMap<>();
         // 设备保养明细 key设备id  value设备保养工单明细下所有保养规则数据最小值
@@ -609,73 +644,6 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
                 }
             }
         }
-        // 计算出每个保养工单明细的不同保养规则的保养距离最小值
-        if (CollUtil.isNotEmpty(workOrderBomS)) {
-            workOrderBomS.forEach(bom -> {
-                BigDecimal runningTimeDistance = null;
-                BigDecimal runningKiloDistance = null;
-                BigDecimal naturalDateDistance = null;
-                // 计算每个保养项 每个保养规则下的 距离保养时间
-                if (ObjUtil.isNotEmpty(bom.getRunningTimeRule()) && 0 == bom.getRunningTimeRule()) {
-                    // 运行时间保养规则
-                    if (deviceRunLogMap.containsKey(bom.getDeviceId())) {
-                        BigDecimal totalRunTime = deviceRunLogMap.get(bom.getDeviceId()).getTotalRunTime();
-                        BigDecimal lastRunningTime = bom.getLastRunningTime();      // 上次保养运行时间
-                        BigDecimal runningTimePeriod = bom.getNextRunningTime();    // 运行时间周期
-                        BigDecimal timePeriodLead = bom.getTimePeriodLead();    // 运行时间周期提前量
-                        // runningTimeDistance = (lastRunningTime.add(runningTimePeriod).subtract(timePeriodLead)).subtract(totalRunTime);
-                        runningTimeDistance = runningTimePeriod.subtract(totalRunTime.subtract(lastRunningTime));
-                    }
-                }
-                if (ObjUtil.isNotEmpty(bom.getMileageRule()) && 0 == bom.getMileageRule()) {
-                    // 运行里程保养规则
-                    // 累计运行里程规则 累计运行里程 >= (上次保养运行里程+运行里程周期-提前量)
-                    if (deviceRunLogMap.containsKey(bom.getDeviceId())) {
-                        BigDecimal totalMileage = deviceRunLogMap.get(bom.getDeviceId()).getTotalMileage();
-                        BigDecimal lastRunningKilo = bom.getLastRunningKilometers();      // 上次保养运行里程
-                        BigDecimal runningKiloPeriod = bom.getNextRunningKilometers();    // 运行里程周期
-                        BigDecimal kiloCycleLead = bom.getKiloCycleLead();    // 运行里程周期提前量
-                        // runningKiloDistance = (lastRunningKilo.add(runningKiloPeriod).subtract(kiloCycleLead)).subtract(totalMileage);
-                        runningKiloDistance = runningKiloPeriod.subtract(totalMileage.subtract(lastRunningKilo));
-                    }
-                }
-                if (ObjUtil.isNotEmpty(bom.getNaturalDateRule()) && 0 == bom.getNaturalDateRule()) {
-                    // 自然日期保养规则
-                    LocalDateTime lastNaturalDate = bom.getLastNaturalDate();      // 上次保养自然日期
-                    BigDecimal naturalDatePeriod = bom.getNextNaturalDate();        // 自然日周期
-                    BigDecimal natualDateLead = bom.getNaturalDatePeriodLead();    // 自然日周期提前量
-                    if (ObjUtil.isNotEmpty(lastNaturalDate) && ObjUtil.isNotEmpty(naturalDatePeriod) && ObjUtil.isNotEmpty(natualDateLead)) {
-                        // 计算有效天数 = 自然日周期 - 提前量
-                        long days = naturalDatePeriod.longValue(); // 转为长整型天数
-                        // 计算目标日期:上次保养日期 + 有效天数(注意:LocalDateTime加天数会自动处理日期进位)
-                        LocalDateTime targetDate = lastNaturalDate.plusDays(days);
-                        // 获取当前日期时间
-                        LocalDateTime now = LocalDateTime.now();
-                        // 计算日期差值(以天为单位)
-                        naturalDateDistance = new BigDecimal(ChronoUnit.DAYS.between(now, targetDate));
-                    }
-                }
-                // 找出距离0最近的数,作为工单的最近保养距离数据
-                Object closet = chooseNearestDistance(runningTimeDistance, runningKiloDistance, naturalDateDistance);
-                Map<String, Object> tempDistance = new HashMap<>();
-                if (closet == runningTimeDistance) {
-                    tempDistance.put("H", closet);
-                } else if (closet == runningKiloDistance) {
-                    tempDistance.put("KM", closet);
-                } else if (closet == naturalDateDistance) {
-                    tempDistance.put("D", closet);
-                }
-                if (orderDistancePair.containsKey(bom.getDeviceId())) {
-                    List<Map<String, Object>> tempDistances = orderDistancePair.get(bom.getDeviceId());
-                    tempDistances.add(tempDistance);
-                    orderDistancePair.put(bom.getDeviceId(), tempDistances);
-                } else {
-                    List<Map<String, Object>> tempDistances = new ArrayList<>();
-                    tempDistances.add(tempDistance);
-                    orderDistancePair.put(bom.getDeviceId(), tempDistances);
-                }
-            });
-        }
         // 以设备id 为维度 统计每个保养工单明细中 距离最近的保养数据
         resultMap = findClosestToZero(orderDistancePair);
         // 根据保养项规则应该生成保养工单的设备id集合
@@ -708,15 +676,8 @@ public class IotMainWorkOrderServiceImpl implements IotMainWorkOrderService {
         // 排序后输出一个 List<Long> 类型的集合,排序对应上面的排序规则
         List<Long> sortedDeviceIds = sortByNumericValue(resultMap);
         try {
-            // 左侧组织树 组织层级查询
-            Set<Long> ids = new HashSet<>();
-            if (Objects.nonNull(pageReqVO.getDeptId())) {
-                ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
-                ids.add(pageReqVO.getDeptId());
-            }
-            // 不查询保养订单表 暂时传一个不会出现的设备id
-            orderDeviceIds.add(Long.MIN_VALUE);
-            List<IotDeviceRespVO> alarmDevices = iotDeviceMapper.deviceAlarmDistances(sortedDeviceIds, orderDeviceIds, mainBomDeviceIds);
+            List<IotDeviceRespVO> alarmDevices = iotDeviceMapper.deviceAlarmDistancesSearch(sortedDeviceIds, mainBomDeviceIds);
+
             // 处理当前分页数据 拼接上已经排序的 筛选出的设备保养项 最小保养距离
             List<Long> alarmDeviceIds = new ArrayList<>();
             Map<Long, IotDeviceRespVO> alarmDevicePair = new HashMap<>();

+ 35 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceMapper.xml

@@ -273,6 +273,41 @@
         )
     </select>
 
+    <select id="deviceAlarmDistancesSearch"
+            resultType="cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO">
+        SELECT *
+        FROM (
+            SELECT
+            rid.id,
+            rid.dept_id	deptId,
+            rid.device_code deviceCode,
+            rid.device_name deviceName,
+            rid.device_status deviceStatus,
+            rid.asset_property assetProperty,
+            '' workOrderId,
+            MAX(mb.plan_id) planId
+            FROM rq_iot_maintenance_bom mb
+            LEFT JOIN rq_iot_device rid ON rid.id = mb.device_id
+            WHERE mb.deleted = 0
+            AND mb.`status` = 0
+            AND rid.device_code IS NOT NULL
+            <if test="mainBomDeviceIds != null and mainBomDeviceIds.size &gt; 0">
+                AND rid.id IN
+                <foreach collection="mainBomDeviceIds" index="index" item="key" open="(" separator="," close=")">
+                    #{key}
+                </foreach>
+            </if>
+            GROUP BY mb.device_id
+        ) tmp
+        ORDER BY FIELD(tmp.id,
+        <if test="sortedDeviceIds != null and sortedDeviceIds.size &gt; 0">
+            <foreach collection="sortedDeviceIds" index="index" item="key" separator=",">
+                #{key}
+            </foreach>
+        </if>
+        )
+    </select>
+
     <select id="personRelationDevices"
             resultType="cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO">
         SELECT

+ 20 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotDeviceRunLogMapper.xml

@@ -37,12 +37,31 @@
         GROUP BY drl.device_id, mta.`code`
     </select>
 
+    <select id="distinctDevicesSearch"
+            resultType="cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO">
+        SELECT drl.device_id,
+            MAX(drl.total_run_time) AS total_run_time,
+            0.0 total_mileage,
+            drl.point_name point_name
+        FROM rq_iot_device_max_run_log drl
+        WHERE drl.deleted = 0
+        AND drl.is_sum = 1
+        <if test="deviceIds != null and deviceIds.size &gt; 0">
+            AND drl.device_id IN
+            <foreach collection="deviceIds" index="index" item="key" open="(" separator="," close=")">
+                #{key}
+            </foreach>
+        </if>
+        GROUP BY drl.device_id, drl.point_name
+    </select>
+
     <!-- 查询正常统计的累计 公里数 时长 -->
     <select id="normalCumulativeAttrs"
             resultType="cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO">
         SELECT
             mta.device_category_id,
-            mta.`name` pointName
+            mta.`name` pointName,
+            mta.`code` point_code
         FROM rq_iot_model_template_attrs mta
         WHERE mta.deleted = 0
         AND (mta.`code` ='sc' OR mta.`code`='gls')