Bläddra i källkod

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstant.java
lipenghui 3 månader sedan
förälder
incheckning
20de19b7d7
52 ändrade filer med 2789 tillägg och 10 borttagningar
  1. 2 3
      yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstant.java
  2. 34 2
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/IotBomController.java
  3. 6 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/vo/IotBomRespVO.java
  4. 6 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotcommonbommaterial/vo/IotCommonBomMaterialSaveReqVO.java
  5. 3 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorderbommaterial/vo/IotMainWorkOrderBomMaterialRespVO.java
  6. 129 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/IotModelTemplateController.java
  7. 72 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/ModelTemplateAttrs.java
  8. 34 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrArrayDataSpecs.java
  9. 31 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrBoolOrEnumDataSpecs.java
  10. 36 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrDataSpecs.java
  11. 30 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrDateOrTextDataSpecs.java
  12. 51 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrNumericDataSpec.java
  13. 52 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrStructDataSpecs.java
  14. 54 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplatePageReqVO.java
  15. 69 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplateRespVO.java
  16. 46 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplateSaveReqVO.java
  17. 23 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/ModelTemplateUpdateStatusReqVO.java
  18. 108 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/IotModelTemplateAttrsController.java
  19. 75 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsPageReqVO.java
  20. 90 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsRespVO.java
  21. 65 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsSaveReqVO.java
  22. 103 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java
  23. 72 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillPageReqVO.java
  24. 75 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillRespVO.java
  25. 59 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillSaveReqVO.java
  26. 40 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelPageReqVO.java
  27. 47 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelRespVO.java
  28. 42 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelSaveReqVO.java
  29. 33 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/convert/iotmodeltemplate/IotModelTemplateConvert.java
  30. 76 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplate/IotModelTemplateDO.java
  31. 104 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplateattrs/IotModelTemplateAttrsDO.java
  32. 34 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplateattrs/IotThingsModelDO.java
  33. 35 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltree/ModelTreeNode.java
  34. 92 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotopeationfill/IotOpeationFillDO.java
  35. 62 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotopeationmodel/IotOpeationModelDO.java
  36. 1 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotcommonbommaterial/IotCommonBomMaterialMapper.java
  37. 36 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmodeltemplate/IotModelTemplateMapper.java
  38. 51 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmodeltemplateattrs/IotModelTemplateAttrsMapper.java
  39. 48 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationfill/IotOpeationFillMapper.java
  40. 42 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationmodel/IotOpeationModelMapper.java
  41. 15 4
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorderbommaterial/IotMainWorkOrderBomMaterialServiceImpl.java
  42. 70 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplate/IotModelTemplateService.java
  43. 87 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplate/IotModelTemplateServiceImpl.java
  44. 68 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplateattrs/IotModelTemplateAttrsService.java
  45. 80 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplateattrs/IotModelTemplateAttrsServiceImpl.java
  46. 62 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillService.java
  47. 87 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillServiceImpl.java
  48. 70 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationmodel/IotOpeationModelService.java
  49. 98 0
      yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationmodel/IotOpeationModelServiceImpl.java
  50. 13 0
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotModelTemplateAttrsMapper.xml
  51. 66 0
      yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotOpeationFillMapper.xml
  52. 5 1
      yudao-server/src/main/resources/application-dev.yaml

+ 2 - 3
yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstant.java

@@ -50,7 +50,6 @@ public interface ErrorCodeConstant{
     ErrorCode IOT_MAIN_WORK_ORDER_NOT_EXISTS = new ErrorCode(141,"保养工单不存在");
     ErrorCode IOT_DEVICE_RUN_LOG_NOT_EXISTS = new ErrorCode(142, "设备运行数据记录 中间表不存在");
     ErrorCode DEVICE_NOT_EXISTS = new ErrorCode(143, "延凡设备不存在");
-    ErrorCode IOT_MAINTAIN_MATERIALS_NOT_EXISTS = new ErrorCode(144, "维修工单对应物料不存在");
-    ErrorCode IOT_MAINTAIN_BOM_NOT_EXISTS = new ErrorCode(145, "维修工单对应维修项BOM不存在");
-
+    ErrorCode IOT_OPEATION_MODEL_NOT_EXISTS = new ErrorCode(135, "运行记录模板主不存在");
+    ErrorCode IOT_OPEATION_FILL_NOT_EXISTS = new ErrorCode(136, "运行记录填报不存在");
 }

+ 34 - 2
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/IotBomController.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.controller.admin.iotbom;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
@@ -7,11 +8,15 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 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.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.*;
+import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotcommonbommaterial.IotCommonBomMaterialDO;
 import cn.iocoder.yudao.module.pms.service.iotbom.IotBomService;
+import cn.iocoder.yudao.module.pms.service.iotcommonbommaterial.IotCommonBomMaterialService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,7 +28,8 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -36,6 +42,8 @@ public class IotBomController {
 
     @Resource
     private IotBomService iotBomService;
+    @Resource
+    private IotCommonBomMaterialService iotCommonBomMaterialService;
 
     @PostMapping("/create")
     @Operation(summary = "创建PMS BOM 关系")
@@ -95,7 +103,31 @@ public class IotBomController {
             return success(CollectionUtil.newArrayList());
         }
         List<IotBomDO> list = iotBomService.getBomList(reqVO);
-        return success(BeanUtils.toBean(list, IotBomRespVO.class));
+        if (CollUtil.isEmpty(list)) {
+            return success(Collections.emptyList());
+        }
+        List<Long> bomNodeIds = list.stream()
+                .map(IotBomDO::getId)
+                .collect(Collectors.toList());
+
+        IotCommonBomMaterialSaveReqVO bomMaterialSaveReqVO = new IotCommonBomMaterialSaveReqVO();
+        bomMaterialSaveReqVO.setBomNodeIds(bomNodeIds);
+        // 查询所有bom节点已经绑定的物料列表
+        List<IotCommonBomMaterialDO> bomMaterials = iotCommonBomMaterialService.getIotCommonBomMaterials(bomMaterialSaveReqVO);
+        Map<Long, Integer> bomMaterialCount = new HashMap<>();
+        if (CollUtil.isNotEmpty(bomMaterials)) {
+            bomMaterials.forEach(material -> {
+                if (bomMaterialCount.containsKey(material.getBomNodeId())) {
+                    bomMaterialCount.put(material.getBomNodeId(), bomMaterialCount.get(material.getBomNodeId())+1);
+                } else {
+                    bomMaterialCount.put(material.getBomNodeId(), 1);
+                }
+            });
+        }
+        return success(BeanUtils.toBean(list, IotBomRespVO.class, bom -> {
+            Integer materialCount = bomMaterialCount.getOrDefault(bom.getId(), 0);
+            bom.setMaterials(materialCount);
+        }));
     }
 
     @GetMapping(value = {"/list-all-simple", "/simple-list"})

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotbom/vo/IotBomRespVO.java

@@ -80,4 +80,10 @@ public class IotBomRespVO {
     private String deviceStatus;
     @Schema(description = "资产性质")
     private String assetProperty;
+
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "已经绑定的物料数量")
+    private Integer materials;
 }

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotcommonbommaterial/vo/IotCommonBomMaterialSaveReqVO.java

@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 @Schema(description = "管理后台 - PMS 设备分类公共BOM挂载物料关联新增/修改 Request VO")
 @Data
@@ -36,4 +37,9 @@ public class IotCommonBomMaterialSaveReqVO {
     @Schema(description = "备注", example = "随便")
     private String remark;
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "bom节点id集合", example = "随便")
+    private List<Long> bomNodeIds;
 }

+ 3 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorderbommaterial/vo/IotMainWorkOrderBomMaterialRespVO.java

@@ -126,4 +126,7 @@ public class IotMainWorkOrderBomMaterialRespVO {
     @Schema(description = "单位", example = "kg")
     private String unit;
 
+    @Schema(description = "是否是bom节点关联的物料", example = "Y N")
+    private String bomMaterialFlag;
+
 }

+ 129 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/IotModelTemplateController.java

@@ -0,0 +1,129 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate;
+
+import cn.hutool.core.collection.CollUtil;
+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.iotmodeltemplate.vo.ModelTemplateUpdateStatusReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplatePageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplateRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplateSaveReqVO;
+import cn.iocoder.yudao.module.pms.convert.iotdevicetemplate.IotDeviceTemplateConvert;
+import cn.iocoder.yudao.module.pms.convert.iotmodeltemplate.IotModelTemplateConvert;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicetemplate.IotDeviceTemplateDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate.IotModelTemplateDO;
+import cn.iocoder.yudao.module.pms.service.IotProductClassifyService;
+import cn.iocoder.yudao.module.pms.service.iotdevicetemplate.IotDeviceTemplateService;
+import cn.iocoder.yudao.module.pms.service.iotmodeltemplate.IotModelTemplateService;
+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 java.util.Map;
+
+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;
+
+@Tag(name = "管理后台 - PMS 功能优化 设备模板")
+@RestController
+@RequestMapping("/rq/iot-model-template")
+@Validated
+public class IotModelTemplateController {
+
+    @Resource
+    private IotModelTemplateService iotDeviceTemplateService;
+    @Resource
+    private IotProductClassifyService iotProductClassifyService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建PMS 功能优化 设备模板")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:create')")
+    public CommonResult<Long> createIotDeviceTemplate(@Valid @RequestBody IotModelTemplateSaveReqVO createReqVO) {
+        return success(iotDeviceTemplateService.createIotDeviceTemplate(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新PMS 功能优化 设备模板")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:update')")
+    public CommonResult<Boolean> updateIotDeviceTemplate(@Valid @RequestBody IotModelTemplateSaveReqVO updateReqVO) {
+        iotDeviceTemplateService.updateIotDeviceTemplate(updateReqVO);
+        return success(true);
+    }
+
+    @PutMapping("/update-status")
+    @Operation(summary = "修改 设备属性模板 状态")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:update')")
+    public CommonResult<Boolean> updateDeviceTemplateStatus(@Valid @RequestBody ModelTemplateUpdateStatusReqVO reqVO) {
+        iotDeviceTemplateService.updateDeviceTemplateStatus(reqVO.getId(), reqVO.getStatus());
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除PMS 功能优化 设备模板")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:delete')")
+    public CommonResult<Boolean> deleteIotDeviceTemplate(@RequestParam("id") Long id) {
+        iotDeviceTemplateService.deleteIotDeviceTemplate(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得PMS 功能优化 设备模板")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:query')")
+    public CommonResult<IotModelTemplateRespVO> getIotDeviceTemplate(@RequestParam("id") Long id) {
+        IotModelTemplateDO iotDeviceTemplate = iotDeviceTemplateService.getIotDeviceTemplate(id);
+        return success(BeanUtils.toBean(iotDeviceTemplate, IotModelTemplateRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得PMS 功能优化 设备模板分页")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:query')")
+    public CommonResult<PageResult<IotModelTemplateRespVO>> getIotDeviceTemplatePage(@Valid IotModelTemplatePageReqVO pageReqVO) {
+        PageResult<IotModelTemplateDO> pageResult = iotDeviceTemplateService.getIotDeviceTemplatePage(pageReqVO);
+        if (CollUtil.isEmpty(pageResult.getList())) {
+            return success(new PageResult<>(pageResult.getTotal()));
+        }
+        // 拼接所属 设备分类
+        Map<Long, IotProductClassifyDO> deviceCategoryMap = iotProductClassifyService.getIotProductClassifyMap(
+                convertList(pageResult.getList(), IotModelTemplateDO::getDeviceCategoryId));
+        return success(new PageResult<>(IotModelTemplateConvert.INSTANCE.convertList(pageResult.getList(), deviceCategoryMap),
+                pageResult.getTotal()));
+    }
+
+    @GetMapping("/list-by-model-category-id")
+    @Operation(summary = "根据设备分类id获取模板属性列表")
+    @Parameter(name = "deviceCategoryId", description = "设备分类id", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:query')")
+    public CommonResult<IotModelTemplateRespVO> getAttrsByDeviceCategoryId(@RequestParam("deviceCategoryId") Long deviceCategoryId) {
+        IotModelTemplateDO deviceTemplate = iotDeviceTemplateService.getTemplateByDeviceCategoryId(deviceCategoryId);
+        return success(BeanUtils.toBean(deviceTemplate, IotModelTemplateRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出PMS 功能优化 设备模板 Excel")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIotDeviceTemplateExcel(@Valid IotModelTemplatePageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IotModelTemplateDO> list = iotDeviceTemplateService.getIotDeviceTemplatePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "PMS 功能优化 设备模板.xls", "数据", IotModelTemplateRespVO.class,
+                        BeanUtils.toBean(list, IotModelTemplateRespVO.class));
+    }
+
+}

+ 72 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/ModelTemplateAttrs.java

@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model;
+
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype.ModelTemplateAttrDataSpecs;
+import cn.iocoder.yudao.module.pms.enums.devicetemplate.DeviceTemplateAttrAccessModeEnum;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 设备模板属性 json
+ *
+ * dataSpecs 和 dataSpecsList 之中必须传入且只能传入一个
+ *
+ * @author ruiqi
+ */
+@Data
+public class ModelTemplateAttrs {
+
+    /**
+     * 属性名称
+     */
+    @NotEmpty(message = "属性名称")
+    private String name;
+    /**
+     * placeholder 提示语
+     */
+    private String placeHolder;
+    /**
+     * 属性编码
+     */
+    private String code;
+    /**
+     * 属性数据类型 string number boolean
+     *
+     */
+    @NotEmpty(message = "数据类型")
+    private String type;
+    /**
+     * 是否必填 0不必填 1必填
+     */
+    private Integer requiredFlag;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 属性标识符
+     */
+    private String identifier;
+    /**
+     * 默认值
+     */
+    private String defaultValue;
+    /**
+     * 云端可以对该属性进行的操作类型
+     *
+     * 枚举 {@link DeviceTemplateAttrAccessModeEnum}
+     */
+    @InEnum(DeviceTemplateAttrAccessModeEnum.class)
+    private String accessMode;
+    /**
+     * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中
+     */
+    private ModelTemplateAttrDataSpecs dataSpecs;
+    /**
+     * 数据类型(dataType)为列表型(enum、bool、struct)的数据规范存储在 dataSpecsList 中
+     */
+    private List<ModelTemplateAttrDataSpecs> dataSpecsList;
+
+}

+ 34 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrArrayDataSpecs.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 设备模板属性 数据类型为数组的 DataSpec 定义
+ *
+ * @author ruiqi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复
+public class ModelTemplateAttrArrayDataSpecs extends ModelTemplateAttrDataSpecs {
+
+    /**
+     * 数组中的元素个数
+     */
+    private Integer size;
+    /**
+     * 数组中的元素的数据类型。可选值:struct、int、float、double 或 text
+     */
+    private String childDataType;
+    /**
+     * 数据类型(childDataType)为列表型 struct 的数据规范存储在 dataSpecsList 中
+     * 此时 struct 取值范围为:int、float、double、text、date、enum、bool
+     */
+    private List<ModelTemplateAttrDataSpecs> dataSpecsList;
+
+}
+

+ 31 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrBoolOrEnumDataSpecs.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 设备模板属性 数据类型为布尔型或枚举型的 DataSpec 定义
+ *
+ * 数据类型,取值为 bool 或 enum。
+ *
+ * @author ruiqi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复
+public class ModelTemplateAttrBoolOrEnumDataSpecs extends ModelTemplateAttrDataSpecs {
+
+    // TODO @puhui999:要不写下参数校验?这样,注释可以简洁一点
+    /**
+     * 枚举项的名称。
+     * 可包含中文、大小写英文字母、数字、下划线(_)和短划线(-)
+     * 必须以中文、英文字母或数字开头,长度不超过 20 个字符
+     */
+    private String name;
+    /**
+     * 枚举值。
+     */
+    private Integer value;
+
+}

+ 36 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrDataSpecs.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import lombok.Data;
+
+/**
+ * 设备模板属性 DeviceTemplateAttrDataSpecs 抽象类
+ *
+ * 用于表示设备模板属性数据的通用类型,根据具体的 "dataType" 字段动态映射到对应的子类。
+ * 提供多态支持,适用于不同类型的数据结构序列化和反序列化场景。
+ *
+ * @author ruiqi
+ */
+@Data
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "dataType", visible = true)
+@JsonSubTypes({
+        @JsonSubTypes.Type(value = ModelTemplateAttrNumericDataSpec.class, name = "int"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrNumericDataSpec.class, name = "float"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrNumericDataSpec.class, name = "double"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrDateOrTextDataSpecs.class, name = "text"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrDateOrTextDataSpecs.class, name = "textarea"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrDateOrTextDataSpecs.class, name = "date"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrBoolOrEnumDataSpecs.class, name = "bool"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrBoolOrEnumDataSpecs.class, name = "enum"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrArrayDataSpecs.class, name = "array"),
+        @JsonSubTypes.Type(value = ModelTemplateAttrStructDataSpecs.class, name = "struct")
+})
+public abstract class ModelTemplateAttrDataSpecs {
+
+    /**
+     * 数据类型
+     */
+    private String dataType;
+
+}

+ 30 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrDateOrTextDataSpecs.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 设备模板 数据类型为时间型或文本型的 DataSpec 定义
+ *
+ * 数据类型,取值为 date 或 text 或 textarea。
+ *
+ * @author ruiqi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复
+public class ModelTemplateAttrDateOrTextDataSpecs extends ModelTemplateAttrDataSpecs {
+
+    /**
+     * 数据长度,单位为字节。取值不能超过 2048。
+     * 当 dataType 为 text 时,需传入该参数。
+     */
+    private Integer length;
+    /**
+     * 默认值,可选参数,用于存储默认值。
+     */
+    private String defaultValue;
+
+}
+

+ 51 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrNumericDataSpec.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 设备模板属性 数据类型为数值的 DataSpec 定义
+ *
+ * 数据类型,取值为 int、float 或 double。
+ *
+ * @author ruiqi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复
+public class ModelTemplateAttrNumericDataSpec extends ModelTemplateAttrDataSpecs {
+
+    /**
+     * 最大值,需转为字符串类型。值必须与 dataType 类型一致。
+     * 例如,当 dataType 为 int 时,取值为 "200",而不是 200。
+     */
+    private String max;
+    /**
+     * 最小值,需转为字符串类型。值必须与 dataType 类型一致。
+     * 例如,当 dataType 为 int 时,取值为 "0",而不是 0。
+     */
+    private String min;
+    /**
+     * 步长,需转为字符串类型。值必须与 dataType 类型一致。
+     * 例如,当 dataType 为 int 时,取值为 "10",而不是 10。
+     */
+    private String step;
+    /**
+     * 精度。当 dataType 为 float 或 double 时可选传入。
+     */
+    private String precise;
+    /**
+     * 默认值,可传入用于存储的默认值。
+     */
+    private String defaultValue;
+    /**
+     * 单位的符号。
+     */
+    private String unit;
+    /**
+     * 单位的名称。
+     */
+    private String unitName;
+
+}

+ 52 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/model/datatype/ModelTemplateAttrStructDataSpecs.java

@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.datatype;
+
+import cn.iocoder.yudao.module.pms.enums.devicetemplate.DeviceTemplateAttrAccessModeEnum;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+/**
+ * 设备模板属性 数据类型为 struct 的 DataSpec 定义
+ *
+ * @author ruiqi
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@JsonIgnoreProperties({"dataType"}) // 忽略子类中的 dataType 字段,从而避免重复
+public class ModelTemplateAttrStructDataSpecs extends ModelTemplateAttrDataSpecs {
+
+    /**
+     * 属性标识符
+     */
+    private String identifier;
+    /**
+     * 属性名称
+     */
+    private String name;
+    /**
+     * 云端可以对该属性进行的操作类型
+     *
+     * 枚举 {@link DeviceTemplateAttrAccessModeEnum}
+     */
+    private String accessMode;
+    /**
+     * 是否是标准品类的必选服务
+     */
+    private Boolean required;
+    /**
+     * struct 数据的数据类型
+     */
+    private String childDataType;
+    /**
+     * 数据类型(dataType)为非列表型(int、float、double、text、date、array)的数据规范存储在 dataSpecs 中
+     */
+    private ModelTemplateAttrDataSpecs dataSpecs;
+    /**
+     * 数据类型(dataType)为列表型(enum、bool、struct)的数据规范存储在 dataSpecsList 中
+     */
+    private List<ModelTemplateAttrDataSpecs> dataSpecsList;
+
+}
+

+ 54 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplatePageReqVO.java

@@ -0,0 +1,54 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.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.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class IotModelTemplatePageReqVO extends PageParam {
+
+    @Schema(description = "所属设备分类", example = "22225")
+    private Long deviceCategoryId;
+
+    //@Schema(description = "所属设备id", example = "22225")
+    //private Long deviceId;
+
+    @Schema(description = "模板名称", example = "赵六")
+    private String name;
+
+    @Schema(description = "模板编码")
+    private String code;
+
+    @Schema(description = "模板属性 json 格式数据")
+    private String attrs;
+
+    @Schema(description = "模板描述", example = "随便")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    private Integer status;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "模板版本号")
+    private Integer version;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 69 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplateRespVO.java

@@ -0,0 +1,69 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.ModelTemplateAttrs;
+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.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotModelTemplateRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "11061")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "所属设备分类", example = "22225")
+    @ExcelProperty("所属设备分类")
+    private Long deviceCategoryId;
+
+    @Schema(description = "所属设备id", example = "22225")
+    @ExcelProperty("所属设备id")
+    private Long deviceId;
+
+    @Schema(description = "所属设备分类名称", example = "pms")
+    @ExcelProperty("所属设备分类名称")
+    private String deviceCategoryName;
+
+    @Schema(description = "模板名称", example = "赵六")
+    @ExcelProperty("模板名称")
+    private String name;
+
+    @Schema(description = "模板编码")
+    @ExcelProperty("模板编码")
+    private String code;
+
+    @Schema(description = "模板属性 json 格式数据")
+    @ExcelProperty("模板属性 json 格式数据")
+    private List<ModelTemplateAttrs> attrs;
+
+    @Schema(description = "模板描述", example = "随便")
+    @ExcelProperty("模板描述")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    @ExcelProperty("状态 0启用  1停用")
+    private Integer status;
+
+    @Schema(description = "排序")
+    @ExcelProperty("排序")
+    private Integer sort;
+
+    @Schema(description = "备注", example = "随便")
+    @ExcelProperty("备注")
+    private String remark;
+
+    @Schema(description = "模板版本号")
+    @ExcelProperty("模板版本号")
+    private Integer version;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 46 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/IotModelTemplateSaveReqVO.java

@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.model.ModelTemplateAttrs;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板新增/修改 Request VO")
+@Data
+public class IotModelTemplateSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "11061")
+    private Long id;
+
+    @Schema(description = "所属设备分类", example = "22225")
+    private Long deviceCategoryId;
+
+    @Schema(description = "所属设备id", example = "22225")
+    private Long deviceId;
+
+    @Schema(description = "模板名称", example = "赵六")
+    private String name;
+
+    @Schema(description = "模板编码")
+    private String code;
+
+    @Schema(description = "模板属性 json 格式数据")
+    private List<ModelTemplateAttrs> attrs;
+
+    @Schema(description = "模板描述", example = "随便")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    private Integer status;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "模板版本号")
+    private Integer version;
+
+}

+ 23 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplate/vo/ModelTemplateUpdateStatusReqVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 设备属性模板 更新状态 Request VO")
+@Data
+public class ModelTemplateUpdateStatusReqVO {
+
+    @Schema(description = "设备属性模板id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    @NotNull(message = "设备属性模板id不能为空")
+    private Long id;
+
+    @Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "状态不能为空")
+    @InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}")
+    private Integer status;
+
+}

+ 108 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/IotModelTemplateAttrsController.java

@@ -0,0 +1,108 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs;
+
+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.iotmodeltemplateattrs.vo.IotModelTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicetemplateattrs.IotDeviceTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotModelTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotThingsModelDO;
+import cn.iocoder.yudao.module.pms.service.iotdevicetemplateattrs.IotDeviceTemplateAttrsService;
+import cn.iocoder.yudao.module.pms.service.iotmodeltemplateattrs.IotModelTemplateAttrsService;
+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.annotation.security.PermitAll;
+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 = "管理后台 - PMS 功能优化 设备模板属性")
+@RestController
+@RequestMapping("/rq/iot-model-template-attrs")
+@Validated
+public class IotModelTemplateAttrsController {
+
+    @Resource
+    private IotModelTemplateAttrsService iotDeviceTemplateAttrsService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建PMS 功能优化 设备模板属性")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:create')")
+    public CommonResult<Long> createIotDeviceTemplateAttrs(@Valid @RequestBody IotModelTemplateAttrsSaveReqVO createReqVO) {
+        return success(iotDeviceTemplateAttrsService.createIotDeviceTemplateAttrs(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新PMS 功能优化 设备模板属性")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:update')")
+    public CommonResult<Boolean> updateIotDeviceTemplateAttrs(@Valid @RequestBody IotModelTemplateAttrsSaveReqVO updateReqVO) {
+        iotDeviceTemplateAttrsService.updateIotDeviceTemplateAttrs(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除PMS 功能优化 设备模板属性")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:delete')")
+    public CommonResult<Boolean> deleteIotDeviceTemplateAttrs(@RequestParam("id") Long id) {
+        iotDeviceTemplateAttrsService.deleteIotDeviceTemplateAttrs(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得PMS 功能优化 设备模板属性")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:query')")
+    public CommonResult<IotModelTemplateAttrsRespVO> getIotDeviceTemplateAttrs(@RequestParam("id") Long id) {
+        IotModelTemplateAttrsDO iotDeviceTemplateAttrs = iotDeviceTemplateAttrsService.getIotDeviceTemplateAttrs(id);
+        return success(BeanUtils.toBean(iotDeviceTemplateAttrs, IotModelTemplateAttrsRespVO.class));
+    }
+
+
+    @GetMapping("/getAttrs")
+    @PermitAll
+    @Operation(summary = "获得PMS 功能优化 设备模板属性")
+    @Parameter(name = "deviceCategoryName", description = "名称", required = true, example = "1024")
+    public CommonResult<List<IotThingsModelDO>> getModelAttrs(@RequestParam("deviceCategoryName") String deviceCategoryName) {
+        List<IotThingsModelDO> list = iotDeviceTemplateAttrsService.getAttrsByName(deviceCategoryName);
+        return success(BeanUtils.toBean(list,IotThingsModelDO.class));
+    }
+
+
+    @GetMapping("/page")
+    @Operation(summary = "获得PMS 功能优化 设备模板属性分页")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:query')")
+    public CommonResult<PageResult<IotModelTemplateAttrsRespVO>> getIotDeviceTemplateAttrsPage(@Valid IotModelTemplateAttrsPageReqVO pageReqVO) {
+        PageResult<IotModelTemplateAttrsDO> pageResult = iotDeviceTemplateAttrsService.getIotDeviceTemplateAttrsPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, IotModelTemplateAttrsRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出PMS 功能优化 设备模板属性 Excel")
+    @PreAuthorize("@ss.hasPermission('rq:iot-model-template-attrs:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIotDeviceTemplateAttrsExcel(@Valid IotModelTemplateAttrsPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IotModelTemplateAttrsDO> list = iotDeviceTemplateAttrsService.getIotDeviceTemplateAttrsPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "PMS 功能优化 设备模板属性.xls", "数据", IotModelTemplateAttrsRespVO.class,
+                        BeanUtils.toBean(list, IotModelTemplateAttrsRespVO.class));
+    }
+
+}

+ 75 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsPageReqVO.java

@@ -0,0 +1,75 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.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.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板属性分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class IotModelTemplateAttrsPageReqVO extends PageParam {
+
+    @Schema(description = "设备分类id", example = "32238")
+    private Long deviceCategoryId;
+
+    /*@Schema(description = "设备id", example = "32238")
+    private Long deviceId;*/
+
+    @Schema(description = "设备模板id", example = "32238")
+    private Long templateId;
+
+    @Schema(description = "属性名称", example = "李四")
+    private String name;
+
+    @Schema(description = "属性编码")
+    private String code;
+
+    @Schema(description = "属性数据类型 string number boolean", example = "1")
+    private String type;
+
+    @Schema(description = "是否必填 0不必填 1必填")
+    private Integer requiredFlag;
+
+    @Schema(description = "默认值")
+    private String defaultValue;
+
+    @Schema(description = "属性值单位")
+    private String unit;
+
+    @Schema(description = "模板描述", example = "随便")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    private Integer status;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "下拉框选项 ")
+    private String selectOptions;
+
+    @Schema(description = "模板版本号")
+    private Integer version;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+    @Schema(description = "是否数采", example = "1")
+    private Integer isCollection;
+
+    @Schema(description = "物属性", example = "zyj")
+    private String modelAttr;
+
+}

+ 90 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsRespVO.java

@@ -0,0 +1,90 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplate.model.DeviceTemplateAttrs;
+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.time.LocalDateTime;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板属性 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotModelTemplateAttrsRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "12178")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "设备模板id", example = "32238")
+    @ExcelProperty("设备模板id")
+    private Long templateId;
+
+    @Schema(description = "设备id", example = "32238")
+    @ExcelProperty("设备id")
+    private Long deviceId;
+
+    @Schema(description = "设备分类id", example = "32238")
+    @ExcelProperty("设备分类id")
+    private Long deviceCategoryId;
+
+    @Schema(description = "属性名称", example = "李四")
+    @ExcelProperty("属性名称")
+    private String name;
+
+    @Schema(description = "属性编码")
+    @ExcelProperty("属性编码")
+    private String code;
+
+    @Schema(description = "属性数据类型 string number boolean", example = "1")
+    @ExcelProperty("属性数据类型 string number boolean")
+    private String type;
+
+    @Schema(description = "是否必填 0不必填 1必填")
+    @ExcelProperty("是否必填 0不必填 1必填")
+    private Integer requiredFlag;
+
+    @Schema(description = "默认值")
+    @ExcelProperty("默认值")
+    private String defaultValue;
+
+    @Schema(description = "属性值单位")
+    @ExcelProperty("属性值单位")
+    private String unit;
+
+    @Schema(description = "模板描述", example = "随便")
+    @ExcelProperty("模板描述")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    @ExcelProperty("状态 0启用  1停用")
+    private Integer status;
+
+    @Schema(description = "备注", example = "随便")
+    @ExcelProperty("备注")
+    private String remark;
+
+    @Schema(description = "排序")
+    @ExcelProperty("排序")
+    private Integer sort;
+
+    @Schema(description = "下拉框选项 ")
+    @ExcelProperty("下拉框选项 ")
+    private DeviceTemplateAttrs selectOptions;
+
+    @Schema(description = "模板版本号")
+    @ExcelProperty("模板版本号")
+    private Integer version;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @Schema(description = "是否数采", example = "1")
+    private Integer isCollection;
+
+    @Schema(description = "物属性", example = "zyj")
+    private String modelAttr;
+
+}

+ 65 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmodeltemplateattrs/vo/IotModelTemplateAttrsSaveReqVO.java

@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplate.model.DeviceTemplateAttrs;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - PMS 功能优化 设备模板属性新增/修改 Request VO")
+@Data
+public class IotModelTemplateAttrsSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "12178")
+    private Long id;
+
+    @Schema(description = "设备模板id", example = "32238")
+    private Long templateId;
+
+    @Schema(description = "设备id", example = "32238")
+    private Long deviceId;
+
+    @Schema(description = "设备分类id", example = "32238")
+    private Long deviceCategoryId;
+
+    @Schema(description = "属性名称", example = "李四")
+    private String name;
+
+    @Schema(description = "属性编码")
+    private String code;
+
+    @Schema(description = "属性数据类型 string number boolean", example = "1")
+    private String type;
+
+    @Schema(description = "是否必填 0不必填 1必填")
+    private Integer requiredFlag;
+
+    @Schema(description = "默认值")
+    private String defaultValue;
+
+    @Schema(description = "属性值单位")
+    private String unit;
+
+    @Schema(description = "模板描述", example = "随便")
+    private String description;
+
+    @Schema(description = "状态 0启用  1停用", example = "1")
+    private Integer status;
+
+    @Schema(description = "备注", example = "随便")
+    private String remark;
+
+    @Schema(description = "排序")
+    private Integer sort;
+
+    @Schema(description = "下拉框选项 ")
+    private DeviceTemplateAttrs selectOptions;
+
+    @Schema(description = "模板版本号")
+    private Integer version;
+
+    @Schema(description = "是否数采", example = "1")
+    private Integer isCollection;
+
+    @Schema(description = "物属性", example = "zyj")
+    private String modelAttr;
+
+}

+ 103 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java

@@ -0,0 +1,103 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodel.vo.IotModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodel.IotModelDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
+import cn.iocoder.yudao.module.pms.service.iotopeationfill.IotOpeationFillService;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.security.access.prepost.PreAuthorize;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Operation;
+
+import javax.validation.constraints.*;
+import javax.validation.*;
+import javax.servlet.http.*;
+import java.time.LocalDate;
+import java.util.*;
+import java.io.IOException;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
+
+
+@Tag(name = "管理后台 - 运行记录填报")
+@RestController
+@RequestMapping("/rq/iot-opeation-fill")
+@Validated
+public class IotOpeationFillController {
+
+    @Resource
+    private IotOpeationFillService iotOpeationFillService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建运行记录填报")
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:create')")
+    public CommonResult<Long> createIotOpeationFill(@Valid @RequestBody IotOpeationFillSaveReqVO createReqVO) {
+        return success(iotOpeationFillService.createIotOpeationFill(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新运行记录填报")
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:update')")
+    public CommonResult<Boolean> updateIotOpeationFill(@Valid @RequestBody IotOpeationFillSaveReqVO updateReqVO) {
+        iotOpeationFillService.updateIotOpeationFill(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除运行记录填报")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:delete')")
+    public CommonResult<Boolean> deleteIotOpeationFill(@RequestParam("id") Long id) {
+        iotOpeationFillService.deleteIotOpeationFill(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得运行记录填报")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:query')")
+    public CommonResult<IotOpeationFillRespVO> getIotOpeationFill(@RequestParam("id") Long id) {
+        IotOpeationFillDO iotOpeationFill = iotOpeationFillService.getIotOpeationFill(id);
+        return success(BeanUtils.toBean(iotOpeationFill, IotOpeationFillRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得运行记录填报分页")
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:query')")
+    public CommonResult<List<IotDeviceRespVO>> getIotOpeationFillPage(@Valid IotDevicePageReqVO pageReqVO) {
+        List<IotDeviceDO> pageResult = iotOpeationFillService.getFillDevices(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, IotDeviceRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出运行记录填报 Excel")
+    @PreAuthorize("@ss.hasPermission('rq:iot-opeation-fill:export')")
+    @ApiAccessLog(operateType = EXPORT)
+    public void exportIotOpeationFillExcel(@Valid IotOpeationFillPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<IotOpeationFillDO> list = iotOpeationFillService.getIotOpeationFillPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "运行记录填报.xls", "数据", IotOpeationFillRespVO.class,
+                        BeanUtils.toBean(list, IotOpeationFillRespVO.class));
+    }
+
+}

+ 72 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillPageReqVO.java

@@ -0,0 +1,72 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo;
+
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+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 IotOpeationFillPageReqVO extends PageParam {
+
+    @Schema(description = "资产编号")
+    private String deviceCode;
+
+    @Schema(description = "设备名称", example = "赵六")
+    private String deviceName;
+
+    @Schema(description = "填写内容")
+    private String fillContent;
+
+    @Schema(description = "设备类别", example = "1")
+    private String deviceType;
+
+    @Schema(description = "设备部件")
+    private String deviceComponent;
+
+    @Schema(description = "公司id", example = "17048")
+    private Long deptId;
+
+    @Schema(description = "设备id", example = "17048")
+    private Long deviceId;
+
+    @Schema(description = "所属组织", example = "李四")
+    private String orgName;
+
+    @Schema(description = "项目部id", example = "2565")
+    private Long proId;
+
+    @Schema(description = "所属项目部", example = "李四")
+    private String proName;
+
+    @Schema(description = "小队id", example = "26084")
+    private Long teamId;
+
+    @Schema(description = "所属小队", example = "张三")
+    private String teamName;
+
+    @Schema(description = "设备负责人", example = "李四")
+    private String dutyName;
+
+    @Schema(description = "填写日期")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate creDate;
+
+    private Date startDate;
+    private Date endDate;
+
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 75 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillRespVO.java

@@ -0,0 +1,75 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 运行记录填报 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotOpeationFillRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19263")
+    @ExcelProperty("主键id")
+    private Long id;
+
+    @Schema(description = "资产编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("资产编号")
+    private String deviceCode;
+
+    @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @ExcelProperty("设备名称")
+    private String deviceName;
+
+    @Schema(description = "填写内容", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("填写内容")
+    private String fillContent;
+
+    @Schema(description = "设备类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("设备类别")
+    private String deviceType;
+
+    @Schema(description = "设备部件", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("设备部件")
+    private String deviceComponent;
+
+    @Schema(description = "公司id", example = "17048")
+    @ExcelProperty("公司id")
+    private Long deptId;
+
+    @Schema(description = "所属组织", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    @ExcelProperty("所属组织")
+    private String orgName;
+
+    @Schema(description = "项目部id", example = "2565")
+    @ExcelProperty("项目部id")
+    private Long proId;
+
+    @Schema(description = "所属项目部", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    @ExcelProperty("所属项目部")
+    private String proName;
+
+    @Schema(description = "小队id", example = "26084")
+    @ExcelProperty("小队id")
+    private Long teamId;
+
+    @Schema(description = "所属小队", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    @ExcelProperty("所属小队")
+    private String teamName;
+
+    @Schema(description = "设备负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    @ExcelProperty("设备负责人")
+    private String dutyName;
+
+    @Schema(description = "填写日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("填写日期")
+    private LocalDateTime creDate;
+
+    @Schema(description = "创建时间")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 59 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/vo/IotOpeationFillSaveReqVO.java

@@ -0,0 +1,59 @@
+package cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 运行记录填报新增/修改 Request VO")
+@Data
+public class IotOpeationFillSaveReqVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "19263")
+    private Long id;
+
+    @Schema(description = "资产编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "资产编号不能为空")
+    private String deviceCode;
+
+    @Schema(description = "设备名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @NotEmpty(message = "设备名称不能为空")
+    private String deviceName;
+
+    @Schema(description = "填写内容", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "填写内容不能为空")
+    private String fillContent;
+
+    @Schema(description = "设备类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private String deviceType;
+
+    @Schema(description = "设备部件", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String deviceComponent;
+
+    @Schema(description = "公司id", example = "17048")
+    private Long deptId;
+
+    @Schema(description = "所属组织", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    private String orgName;
+
+    @Schema(description = "项目部id", example = "2565")
+    private Long proId;
+
+    @Schema(description = "所属项目部", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    private String proName;
+
+    @Schema(description = "小队id", example = "26084")
+    private Long teamId;
+
+    @Schema(description = "所属小队", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    private String teamName;
+
+    @Schema(description = "设备负责人", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    private String dutyName;
+
+    @Schema(description = "填写日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime creDate;
+
+}

+ 40 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelPageReqVO.java

@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.pms.controller.admin.vo;
+
+import lombok.*;
+import java.util.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import org.springframework.format.annotation.DateTimeFormat;
+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 IotOpeationModelPageReqVO extends PageParam {
+
+    @Schema(description = "部门id", example = "288")
+    private Long deptId;
+
+    @Schema(description = "所属组织", example = "张三")
+    private String orgName;
+
+    @Schema(description = "设备类别", example = "1")
+    private String deviceType;
+
+    @Schema(description = "设备部件")
+    private String deviceComponent;
+
+    @Schema(description = "填写信息")
+    private String fillInfo;
+
+    @Schema(description = "创建人", example = "赵六")
+    private String creName;
+
+    @Schema(description = "创建日期")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] creDate;
+
+}

+ 47 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelRespVO.java

@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.module.pms.controller.admin.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+import com.alibaba.excel.annotation.*;
+
+@Schema(description = "管理后台 - 运行记录模板主 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class IotOpeationModelRespVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "601")
+    @ExcelProperty("主键id")
+    private Long id;
+
+    @Schema(description = "部门id", example = "288")
+    @ExcelProperty("部门id")
+    private Long deptId;
+
+    @Schema(description = "所属组织", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    @ExcelProperty("所属组织")
+    private String orgName;
+
+    @Schema(description = "设备类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("设备类别")
+    private String deviceType;
+
+    @Schema(description = "设备部件", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("设备部件")
+    private String deviceComponent;
+
+    @Schema(description = "填写信息", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("填写信息")
+    private String fillInfo;
+
+    @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    @ExcelProperty("创建人")
+    private String creName;
+
+    @Schema(description = "创建日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建日期")
+    private LocalDateTime creDate;
+
+}

+ 42 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotOpeationModelSaveReqVO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.pms.controller.admin.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import java.util.*;
+import javax.validation.constraints.*;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 运行记录模板主新增/修改 Request VO")
+@Data
+public class IotOpeationModelSaveReqVO {
+
+    @Schema(description = "主键id", requiredMode = Schema.RequiredMode.REQUIRED, example = "601")
+    private Long id;
+
+    @Schema(description = "部门id", example = "288")
+    private Long deptId;
+
+    @Schema(description = "所属组织", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
+    private String orgName;
+
+    @Schema(description = "设备类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotEmpty(message = "设备类别不能为空")
+    private String deviceType;
+
+    @Schema(description = "设备部件", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "设备部件不能为空")
+    private String deviceComponent;
+
+    @Schema(description = "填写信息", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotEmpty(message = "填写信息不能为空")
+    private String fillInfo;
+
+    @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
+    private String creName;
+
+    @Schema(description = "创建日期", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime creDate;
+
+
+}

+ 33 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/convert/iotmodeltemplate/IotModelTemplateConvert.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.pms.convert.iotmodeltemplate;
+
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplate.vo.IotDeviceTemplateRespVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplateRespVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicetemplate.IotDeviceTemplateDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate.IotModelTemplateDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface IotModelTemplateConvert {
+
+    IotModelTemplateConvert INSTANCE = Mappers.getMapper(IotModelTemplateConvert.class);
+
+    default List<IotModelTemplateRespVO> convertList(List<IotModelTemplateDO> list, Map<Long, IotProductClassifyDO> productClassifyMap) {
+        return CollectionUtils.convertList(list, template -> convert(template, productClassifyMap.get(template.getDeviceCategoryId())));
+    }
+
+    default IotModelTemplateRespVO convert(IotModelTemplateDO template, IotProductClassifyDO deviceCategory) {
+        IotModelTemplateRespVO templateVO = BeanUtils.toBean(template, IotModelTemplateRespVO.class);
+        if (deviceCategory != null) {
+            templateVO.setDeviceCategoryName(deviceCategory.getName());
+        }
+        return templateVO;
+    }
+
+}

+ 76 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplate/IotModelTemplateDO.java

@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplate.model.DeviceTemplateAttrs;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.*;
+
+import java.util.List;
+
+/**
+ * PMS 功能优化 运行记录模板 DO
+ *
+ * @author 芋道源码
+ */
+@TableName(value="rq_iot_model_template", autoResultMap = true)
+@KeySequence("rq_iot_device_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotModelTemplateDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 所属设备分类
+     */
+    private Long deviceCategoryId;
+   /* *//**
+     * 所属设备id
+     *//*
+    private Long deviceId;*/
+    /**
+     * 模板名称
+     */
+    private String name;
+    /**
+     * 模板编码
+     */
+    private String code;
+    /**
+     * 模板属性 json 格式数据
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<DeviceTemplateAttrs> attrs;
+    /**
+     * 模板描述
+     */
+    private String description;
+    /**
+     * 状态 0启用  1停用
+     */
+    private Integer status;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 模板版本号
+     */
+    private Integer version;
+
+}

+ 104 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplateattrs/IotModelTemplateAttrsDO.java

@@ -0,0 +1,104 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplate.model.DeviceTemplateAttrs;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+/**
+ * PMS 功能优化 运行记录模板属性 DO
+ *
+ * @author 芋道源码
+ */
+@TableName(value="rq_iot_model_template_attrs", autoResultMap = true)
+@KeySequence("rq_iot_model_template_attrs_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotModelTemplateAttrsDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 设备分类id
+     */
+    private Long deviceCategoryId;
+    /**
+     * 设备id
+     *//*
+    private Long deviceId;*/
+    /**
+     * 设备模板id
+     */
+    private Long templateId;
+    /**
+     * 属性名称
+     */
+    private String name;
+    /**
+     * 属性编码
+     */
+    private String code;
+    /**
+     * 属性数据类型 string number boolean
+     */
+    private String type;
+    /**
+     * 是否必填 0不必填 1必填
+     */
+    private Integer requiredFlag;
+    /**
+     * 默认值
+     */
+    private String defaultValue;
+    /**
+     * 属性值单位
+     */
+    private String unit;
+    /**
+     * 模板描述
+     */
+    private String description;
+    /**
+     * 状态 0启用  1停用
+     */
+    private Integer status;
+    /**
+     * 备注
+     */
+    private String remark;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 下拉框选项 [
+    {"value": "1", "text": "泵"},
+    {"value": "2", "text": "阀门"},
+    {"value": "3", "text": "传感器"}
+  ]
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private DeviceTemplateAttrs selectOptions;
+    /**
+     * 模板版本号
+     */
+    private Integer version;
+
+
+    private Integer isCollection;
+
+    private String modelAttr;
+
+}

+ 34 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltemplateattrs/IotThingsModelDO.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * @author yc
+ * @version 1.0
+ * @className IotThingsModelDO
+ * @date 2025/5/7 11:39
+ * @description
+ */
+@TableName(value="iot_things_model", autoResultMap = true)
+@KeySequence("iot_things_model_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotThingsModelDO {
+    /**
+     * 遇到设备分类名称
+     */
+    private String deviceCategoryName;
+    /**
+     * yanfan设备分类名称
+     */
+    private String modelName;
+    /**
+     * TD数据库字段名
+     */
+    private String identifier;
+}

+ 35 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotmodeltree/ModelTreeNode.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltree;
+
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yc
+ * @version 1.0
+ * @className ModelTreeNode
+ * @date 2025/5/4 22:29
+ * @description
+ */
+@TableName("model_tree_node")
+@KeySequence("model_tree_node_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ModelTreeNode {
+    @TableId
+    private Long id;
+    private String name;
+    private Long parentId;
+    private Integer sortOrder;
+
+    @TableField(exist = false)
+    private List<ModelTreeNode> children = new ArrayList<>();
+}

+ 92 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotopeationfill/IotOpeationFillDO.java

@@ -0,0 +1,92 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill;
+
+import lombok.*;
+
+import java.time.LocalDate;
+import java.util.*;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 运行记录填报 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("rq_iot_opeation_fill")
+@KeySequence("rq_iot_opeation_fill_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotOpeationFillDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 资产编号
+     */
+    private String deviceCode;
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+    /**
+     * 填写内容
+     */
+    private String fillContent;
+    /**
+     * 设备类别
+     */
+    private String deviceType;
+    /**
+     * 设备部件
+     */
+    private String deviceComponent;
+    /**
+     * 公司id
+     */
+    private Long deptId;
+    /**
+     * 所属组织
+     */
+    private String orgName;
+    /**
+     * 项目部id
+     */
+    private Long proId;
+    /**
+     * 所属项目部
+     */
+    private String proName;
+    /**
+     * 小队id
+     */
+    private Long teamId;
+    /**
+     * 所属小队
+     */
+    private String teamName;
+    /**
+     * 设备负责人
+     */
+    private String dutyName;
+    /**
+     * 填写日期
+     */
+    private LocalDate creDate;
+
+}

+ 62 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/dataobject/iotopeationmodel/IotOpeationModelDO.java

@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationmodel;
+
+import lombok.*;
+import java.util.*;
+import java.time.LocalDateTime;
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
+/**
+ * 运行记录模板主 DO
+ *
+ * @author 芋道源码
+ */
+@TableName("rq_iot_opeation_model")
+@KeySequence("rq_iot_opeation_model_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class IotOpeationModelDO extends BaseDO {
+
+    /**
+     * 主键id
+     */
+    @TableId
+    private Long id;
+
+    private Long modelId;
+    private Long componentId;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+    /**
+     * 所属组织
+     */
+    private String orgName;
+    /**
+     * 设备类别
+     */
+    private String deviceType;
+    /**
+     * 设备部件
+     */
+    private String deviceComponent;
+    /**
+     * 填写信息
+     */
+    private String fillInfo;
+    /**
+     * 创建人
+     */
+    private String creName;
+    /**
+     * 创建日期
+     */
+    private LocalDateTime creDate;
+
+}

+ 1 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotcommonbommaterial/IotCommonBomMaterialMapper.java

@@ -36,6 +36,7 @@ public interface IotCommonBomMaterialMapper extends BaseMapperX<IotCommonBomMate
         return selectList(new LambdaQueryWrapperX<IotCommonBomMaterialDO>()
                 .eqIfPresent(IotCommonBomMaterialDO::getDeviceCategoryId, reqVO.getDeviceCategoryId())
                 .eqIfPresent(IotCommonBomMaterialDO::getBomNodeId, reqVO.getBomNodeId())
+                .inIfPresent(IotCommonBomMaterialDO::getBomNodeId, reqVO.getBomNodeIds())
                 .eqIfPresent(IotCommonBomMaterialDO::getMaterialId, reqVO.getMaterialId()));
     }
 

+ 36 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmodeltemplate/IotModelTemplateMapper.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.pms.dal.mysql.iotmodeltemplate;
+
+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.iotmodeltemplate.vo.IotModelTemplatePageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate.IotModelTemplateDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * PMS 功能优化 设备模板 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface IotModelTemplateMapper extends BaseMapperX<IotModelTemplateDO> {
+
+    default PageResult<IotModelTemplateDO> selectPage(IotModelTemplatePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IotModelTemplateDO>()
+                .eqIfPresent(IotModelTemplateDO::getDeviceCategoryId, reqVO.getDeviceCategoryId())
+                .likeIfPresent(IotModelTemplateDO::getName, reqVO.getName())
+                .eqIfPresent(IotModelTemplateDO::getCode, reqVO.getCode())
+                .eqIfPresent(IotModelTemplateDO::getAttrs, reqVO.getAttrs())
+                .eqIfPresent(IotModelTemplateDO::getDescription, reqVO.getDescription())
+                .eqIfPresent(IotModelTemplateDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(IotModelTemplateDO::getSort, reqVO.getSort())
+                .eqIfPresent(IotModelTemplateDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(IotModelTemplateDO::getVersion, reqVO.getVersion())
+                .betweenIfPresent(IotModelTemplateDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(IotModelTemplateDO::getId));
+    }
+
+    default IotModelTemplateDO selectByDeviceCategoryId(Long deviceCategoryId){
+        return selectOne(IotModelTemplateDO::getDeviceCategoryId, deviceCategoryId);
+    };
+}

+ 51 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotmodeltemplateattrs/IotModelTemplateAttrsMapper.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.pms.dal.mysql.iotmodeltemplateattrs;
+
+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.iotdevicetemplateattrs.vo.IotDeviceTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotModelTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotThingsModelDO;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * PMS 功能优化 设备模板属性 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface IotModelTemplateAttrsMapper extends BaseMapperX<IotModelTemplateAttrsDO> {
+
+    default PageResult<IotModelTemplateAttrsDO> selectPage(IotModelTemplateAttrsPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IotModelTemplateAttrsDO>()
+                .eqIfPresent(IotModelTemplateAttrsDO::getDeviceCategoryId, reqVO.getDeviceCategoryId())
+                /*.eqIfPresent(IotModelTemplateAttrsDO::getDeviceId, reqVO.getDeviceId())*/
+                .eqIfPresent(IotModelTemplateAttrsDO::getTemplateId, reqVO.getTemplateId())
+                .likeIfPresent(IotModelTemplateAttrsDO::getName, reqVO.getName())
+                .eqIfPresent(IotModelTemplateAttrsDO::getCode, reqVO.getCode())
+                .eqIfPresent(IotModelTemplateAttrsDO::getType, reqVO.getType())
+                .eqIfPresent(IotModelTemplateAttrsDO::getRequiredFlag, reqVO.getRequiredFlag())
+                .eqIfPresent(IotModelTemplateAttrsDO::getDefaultValue, reqVO.getDefaultValue())
+                .eqIfPresent(IotModelTemplateAttrsDO::getUnit, reqVO.getUnit())
+                .eqIfPresent(IotModelTemplateAttrsDO::getDescription, reqVO.getDescription())
+                .eqIfPresent(IotModelTemplateAttrsDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(IotModelTemplateAttrsDO::getModelAttr, reqVO.getModelAttr())
+                .eqIfPresent(IotModelTemplateAttrsDO::getIsCollection, reqVO.getIsCollection())
+                .eqIfPresent(IotModelTemplateAttrsDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(IotModelTemplateAttrsDO::getSort, reqVO.getSort())
+                .eqIfPresent(IotModelTemplateAttrsDO::getSelectOptions, reqVO.getSelectOptions())
+                .eqIfPresent(IotModelTemplateAttrsDO::getVersion, reqVO.getVersion())
+                .betweenIfPresent(IotModelTemplateAttrsDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(IotModelTemplateAttrsDO::getId));
+    }
+
+    @DS("yanfan")
+    @TenantIgnore
+    List<IotThingsModelDO> getAttrsByName(String name);
+
+}

+ 48 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationfill/IotOpeationFillMapper.java

@@ -0,0 +1,48 @@
+package cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodel.vo.IotModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodel.IotModelDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.material.IotMaintainMaterialDO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 运行记录填报 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface IotOpeationFillMapper extends BaseMapperX<IotOpeationFillDO> {
+
+    default PageResult<IotOpeationFillDO> selectPage(IotOpeationFillPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IotOpeationFillDO>()
+                .eqIfPresent(IotOpeationFillDO::getDeviceCode, reqVO.getDeviceCode())
+                .likeIfPresent(IotOpeationFillDO::getDeviceName, reqVO.getDeviceName())
+                .eqIfPresent(IotOpeationFillDO::getFillContent, reqVO.getFillContent())
+                .eqIfPresent(IotOpeationFillDO::getDeviceType, reqVO.getDeviceType())
+                .eqIfPresent(IotOpeationFillDO::getDeviceComponent, reqVO.getDeviceComponent())
+                .eqIfPresent(IotOpeationFillDO::getDeptId, reqVO.getDeptId())
+                .likeIfPresent(IotOpeationFillDO::getOrgName, reqVO.getOrgName())
+                .eqIfPresent(IotOpeationFillDO::getProId, reqVO.getProId())
+                .likeIfPresent(IotOpeationFillDO::getProName, reqVO.getProName())
+                .eqIfPresent(IotOpeationFillDO::getTeamId, reqVO.getTeamId())
+                .likeIfPresent(IotOpeationFillDO::getTeamName, reqVO.getTeamName())
+                .likeIfPresent(IotOpeationFillDO::getDutyName, reqVO.getDutyName())
+                .eqIfPresent(IotOpeationFillDO::getCreDate, reqVO.getCreDate())
+                .betweenIfPresent(IotOpeationFillDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(IotOpeationFillDO::getId));
+    }
+
+    List<IotDeviceDO> getFillDevices(IotDevicePageReqVO vo);
+}

+ 42 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotopeationmodel/IotOpeationModelMapper.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.pms.dal.mysql.iotopeationmodel;
+
+import java.util.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotOpeationModelPageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationmodel.IotOpeationModelDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 运行记录模板主 Mapper
+ *
+ * @author 芋道源码
+ */
+@Mapper
+public interface IotOpeationModelMapper extends BaseMapperX<IotOpeationModelDO> {
+
+    default PageResult<IotOpeationModelDO> selectPage(IotOpeationModelPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<IotOpeationModelDO>()
+                .eqIfPresent(IotOpeationModelDO::getDeptId, reqVO.getDeptId())
+                .likeIfPresent(IotOpeationModelDO::getOrgName, reqVO.getOrgName())
+                .eqIfPresent(IotOpeationModelDO::getDeviceType, reqVO.getDeviceType())
+                .eqIfPresent(IotOpeationModelDO::getDeviceComponent, reqVO.getDeviceComponent())
+                .eqIfPresent(IotOpeationModelDO::getFillInfo, reqVO.getFillInfo())
+                .likeIfPresent(IotOpeationModelDO::getCreName, reqVO.getCreName())
+                .betweenIfPresent(IotOpeationModelDO::getCreDate, reqVO.getCreDate())
+                .orderByDesc(IotOpeationModelDO::getId));
+    }
+
+    IotOpeationModelDO getNew();
+
+    int insertCom(IotOpeationModelDO modelDO);
+
+    int updateCom(IotOpeationModelDO modelDO);
+
+    int insertFillInfo(IotOpeationModelDO modelDO);
+
+    int updateFillInfo(IotOpeationModelDO modelDO);
+
+}

+ 15 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmainworkorderbommaterial/IotMainWorkOrderBomMaterialServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pms.service.iotmainworkorderbommaterial;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbommaterial.vo.IotMainWorkOrderBomMaterialPageReqVO;
@@ -21,9 +22,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -97,13 +96,25 @@ public class IotMainWorkOrderBomMaterialServiceImpl implements IotMainWorkOrderB
         reqVO.setBomNodeId(pageReqVO.getBomNodeId());
         List<IotCommonBomMaterialDO> bomMaterials = iotCommonBomMaterialService.getIotCommonBomMaterials(reqVO);
         List<String> materialCodes = new ArrayList<>();
+        Map<String, IotCommonBomMaterialDO> bomNodePair = new HashMap<>();
         if (CollUtil.isNotEmpty(bomMaterials)) {
             materialCodes = bomMaterials.stream()
                     .map(IotCommonBomMaterialDO::getCode) // 提取每个元素的 code 属性
                     .collect(Collectors.toList());
+            // 组装每个bomNodeId关联的物料编码
+            bomNodePair = CollectionUtils.convertMap(bomMaterials, IotCommonBomMaterialDO::getCode);
         }
         IPage<IotMainWorkOrderBomMaterialRespVO> iotMaintainMaterialDOIPage =
-                iotMainWorkOrderBomMaterialMapper.selectMaterialsByDept(Page.of(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO.getDeptId(), dept.getParentId(), materialCodes);
+                iotMainWorkOrderBomMaterialMapper.selectMaterialsByDept(Page.of(pageReqVO.getPageNo(), pageReqVO.getPageSize()),
+                        pageReqVO.getDeptId(), dept.getParentId(), materialCodes);
+        List<IotMainWorkOrderBomMaterialRespVO> materials = iotMaintainMaterialDOIPage.getRecords();
+        if (CollUtil.isNotEmpty(materials)) {
+            for (IotMainWorkOrderBomMaterialRespVO material : materials) {
+                if (bomNodePair.containsKey(material.getMaterialCode())){
+                    material.setBomMaterialFlag("Y");
+                }
+            }
+        }
         return new PageResult<>(iotMaintainMaterialDOIPage.getRecords(), iotMaintainMaterialDOIPage.getTotal());
     }
 

+ 70 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplate/IotModelTemplateService.java

@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.pms.service.iotmodeltemplate;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplatePageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplateSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate.IotModelTemplateDO;
+
+import javax.validation.Valid;
+
+/**
+ * PMS 功能优化 设备模板 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface IotModelTemplateService {
+
+    /**
+     * 创建PMS 功能优化 设备模板
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotDeviceTemplate(@Valid IotModelTemplateSaveReqVO createReqVO);
+
+    /**
+     * 更新PMS 功能优化 设备模板
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotDeviceTemplate(@Valid IotModelTemplateSaveReqVO updateReqVO);
+
+    /**
+     * 删除PMS 功能优化 设备模板
+     *
+     * @param id 编号
+     */
+    void deleteIotDeviceTemplate(Long id);
+
+    /**
+     * 获得PMS 功能优化 设备模板
+     *
+     * @param id 编号
+     * @return PMS 功能优化 设备模板
+     */
+    IotModelTemplateDO getIotDeviceTemplate(Long id);
+
+    /**
+     * 获得PMS 功能优化 设备模板分页
+     *
+     * @param pageReqVO 分页查询
+     * @return PMS 功能优化 设备模板分页
+     */
+    PageResult<IotModelTemplateDO> getIotDeviceTemplatePage(IotModelTemplatePageReqVO pageReqVO);
+
+    /**
+     * 根据设备分类id 获取设备模板(属性)
+     *
+     * @param deviceCategoryId 设备分类id
+     * @return 设备模板(包含属性列表)
+     */
+    IotModelTemplateDO getTemplateByDeviceCategoryId(Long deviceCategoryId);
+
+    /**
+     * 修改状态
+     *
+     * @param id     设备属性模板id
+     * @param status 状态
+     */
+    void updateDeviceTemplateStatus(Long id, Integer status);
+}

+ 87 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplate/IotModelTemplateServiceImpl.java

@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.module.pms.service.iotmodeltemplate;
+
+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.iotmodeltemplate.vo.IotModelTemplatePageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplate.vo.IotModelTemplateSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplate.IotModelTemplateDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotmodeltemplate.IotModelTemplateMapper;
+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_TEMPLATE_NOT_EXISTS;
+
+/**
+ * PMS 功能优化 设备模板 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class IotModelTemplateServiceImpl implements IotModelTemplateService {
+
+    @Resource
+    private IotModelTemplateMapper iotModelTemplateMapper;
+
+    @Override
+    public Long createIotDeviceTemplate(IotModelTemplateSaveReqVO createReqVO) {
+        // 插入
+        IotModelTemplateDO iotModelTemplate = BeanUtils.toBean(createReqVO, IotModelTemplateDO.class);
+        iotModelTemplateMapper.insert(iotModelTemplate);
+        // 返回
+        return iotModelTemplate.getId();
+    }
+
+    @Override
+    public void updateIotDeviceTemplate(IotModelTemplateSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotDeviceTemplateExists(updateReqVO.getId());
+        // 更新
+        IotModelTemplateDO updateObj = BeanUtils.toBean(updateReqVO, IotModelTemplateDO.class);
+        iotModelTemplateMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotDeviceTemplate(Long id) {
+        // 校验存在
+        validateIotDeviceTemplateExists(id);
+        // 删除
+        iotModelTemplateMapper.deleteById(id);
+    }
+
+    private void validateIotDeviceTemplateExists(Long id) {
+        if (iotModelTemplateMapper.selectById(id) == null) {
+            throw exception(IOT_DEVICE_TEMPLATE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IotModelTemplateDO getIotDeviceTemplate(Long id) {
+        return iotModelTemplateMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<IotModelTemplateDO> getIotDeviceTemplatePage(IotModelTemplatePageReqVO pageReqVO) {
+        return iotModelTemplateMapper.selectPage(pageReqVO);
+    }
+
+    @Override
+    public IotModelTemplateDO getTemplateByDeviceCategoryId(Long deviceCategoryId) {
+        return iotModelTemplateMapper.selectByDeviceCategoryId(deviceCategoryId);
+    }
+
+    @Override
+    public void updateDeviceTemplateStatus(Long id, Integer status) {
+        // 校验 设备属性模板 存在
+        validateIotDeviceTemplateExists(id);
+        // 更新状态
+        IotModelTemplateDO updateObj = new IotModelTemplateDO();
+        updateObj.setId(id);
+        updateObj.setStatus(status);
+        iotModelTemplateMapper.updateById(updateObj);
+    }
+
+}

+ 68 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplateattrs/IotModelTemplateAttrsService.java

@@ -0,0 +1,68 @@
+package cn.iocoder.yudao.module.pms.service.iotmodeltemplateattrs;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplateattrs.vo.IotDeviceTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicetemplateattrs.vo.IotDeviceTemplateAttrsSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicetemplateattrs.IotDeviceTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotModelTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotThingsModelDO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * PMS 功能优化 设备模板属性 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface IotModelTemplateAttrsService {
+
+    /**
+     * 创建PMS 功能优化 设备模板属性
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotDeviceTemplateAttrs(@Valid IotModelTemplateAttrsSaveReqVO createReqVO);
+
+    /**
+     * 更新PMS 功能优化 设备模板属性
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotDeviceTemplateAttrs(@Valid IotModelTemplateAttrsSaveReqVO updateReqVO);
+
+    /**
+     * 删除PMS 功能优化 设备模板属性
+     *
+     * @param id 编号
+     */
+    void deleteIotDeviceTemplateAttrs(Long id);
+
+    /**
+     * 获得PMS 功能优化 设备模板属性
+     *
+     * @param id 编号
+     * @return PMS 功能优化 设备模板属性
+     */
+    IotModelTemplateAttrsDO getIotDeviceTemplateAttrs(Long id);
+
+    /**
+     *
+     * @param modelDO
+     * @return
+     * @description 根据设备分类名称查询yanfan物模型
+     */
+    List<IotThingsModelDO> getAttrsByName(String name);
+
+    /**
+     * 获得PMS 功能优化 设备模板属性分页
+     *
+     * @param pageReqVO 分页查询
+     * @return PMS 功能优化 设备模板属性分页
+     */
+    PageResult<IotModelTemplateAttrsDO> getIotDeviceTemplateAttrsPage(IotModelTemplateAttrsPageReqVO pageReqVO);
+
+}

+ 80 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotmodeltemplateattrs/IotModelTemplateAttrsServiceImpl.java

@@ -0,0 +1,80 @@
+package cn.iocoder.yudao.module.pms.service.iotmodeltemplateattrs;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotModelTemplateAttrsDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotThingsModelDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotmodeltemplateattrs.IotModelTemplateAttrsMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_DEVICE_TEMPLATE_ATTRS_NOT_EXISTS;
+
+/**
+ * PMS 功能优化 设备模板属性 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class IotModelTemplateAttrsServiceImpl implements IotModelTemplateAttrsService {
+
+    @Resource
+    private IotModelTemplateAttrsMapper iotModelTemplateAttrsMapper;
+
+    @Override
+    public Long createIotDeviceTemplateAttrs(IotModelTemplateAttrsSaveReqVO createReqVO) {
+        // 插入
+        IotModelTemplateAttrsDO iotDeviceTemplateAttrs = BeanUtils.toBean(createReqVO, IotModelTemplateAttrsDO.class);
+        iotModelTemplateAttrsMapper.insert(iotDeviceTemplateAttrs);
+        // 返回
+        return iotDeviceTemplateAttrs.getId();
+    }
+
+    @Override
+    public void updateIotDeviceTemplateAttrs(IotModelTemplateAttrsSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotDeviceTemplateAttrsExists(updateReqVO.getId());
+        // 更新
+        IotModelTemplateAttrsDO updateObj = BeanUtils.toBean(updateReqVO, IotModelTemplateAttrsDO.class);
+        iotModelTemplateAttrsMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotDeviceTemplateAttrs(Long id) {
+        // 校验存在
+        validateIotDeviceTemplateAttrsExists(id);
+        // 删除
+        iotModelTemplateAttrsMapper.deleteById(id);
+    }
+
+    private void validateIotDeviceTemplateAttrsExists(Long id) {
+        if (iotModelTemplateAttrsMapper.selectById(id) == null) {
+            throw exception(IOT_DEVICE_TEMPLATE_ATTRS_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IotModelTemplateAttrsDO getIotDeviceTemplateAttrs(Long id) {
+        return iotModelTemplateAttrsMapper.selectById(id);
+    }
+
+    @Override
+    public List<IotThingsModelDO> getAttrsByName(String name) {
+        return iotModelTemplateAttrsMapper.getAttrsByName(name);
+    }
+
+    @Override
+    public PageResult<IotModelTemplateAttrsDO> getIotDeviceTemplateAttrsPage(IotModelTemplateAttrsPageReqVO pageReqVO) {
+        return iotModelTemplateAttrsMapper.selectPage(pageReqVO);
+    }
+
+}

+ 62 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillService.java

@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.pms.service.iotopeationfill;
+
+import java.util.*;
+import javax.validation.*;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodel.vo.IotModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodel.IotModelDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
+
+/**
+ * 运行记录填报 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface IotOpeationFillService {
+
+    /**
+     * 创建运行记录填报
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotOpeationFill(@Valid IotOpeationFillSaveReqVO createReqVO);
+
+    /**
+     * 更新运行记录填报
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotOpeationFill(@Valid IotOpeationFillSaveReqVO updateReqVO);
+
+    /**
+     * 删除运行记录填报
+     *
+     * @param id 编号
+     */
+    void deleteIotOpeationFill(Long id);
+
+    /**
+     * 获得运行记录填报
+     *
+     * @param id 编号
+     * @return 运行记录填报
+     */
+    IotOpeationFillDO getIotOpeationFill(Long id);
+
+    /**
+     * 获得运行记录填报分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 运行记录填报分页
+     */
+    PageResult<IotOpeationFillDO> getIotOpeationFillPage(IotOpeationFillPageReqVO pageReqVO);
+
+    List<IotDeviceDO> getFillDevices(IotDevicePageReqVO vo);
+
+}

+ 87 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationfill/IotOpeationFillServiceImpl.java

@@ -0,0 +1,87 @@
+package cn.iocoder.yudao.module.pms.service.iotopeationfill;
+
+import cn.iocoder.yudao.module.pms.controller.admin.iotmodel.vo.IotModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDevicePageReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotmodel.IotModelDO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_OPEATION_FILL_NOT_EXISTS;
+
+/**
+ * 运行记录填报 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class IotOpeationFillServiceImpl implements IotOpeationFillService {
+
+    @Resource
+    private IotOpeationFillMapper iotOpeationFillMapper;
+
+    @Override
+    public Long createIotOpeationFill(IotOpeationFillSaveReqVO createReqVO) {
+        // 插入
+        IotOpeationFillDO iotOpeationFill = BeanUtils.toBean(createReqVO, IotOpeationFillDO.class);
+        iotOpeationFillMapper.insert(iotOpeationFill);
+        // 返回
+        return iotOpeationFill.getId();
+    }
+
+    @Override
+    public void updateIotOpeationFill(IotOpeationFillSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotOpeationFillExists(updateReqVO.getId());
+        // 更新
+        IotOpeationFillDO updateObj = BeanUtils.toBean(updateReqVO, IotOpeationFillDO.class);
+        iotOpeationFillMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotOpeationFill(Long id) {
+        // 校验存在
+        validateIotOpeationFillExists(id);
+        // 删除
+        iotOpeationFillMapper.deleteById(id);
+    }
+
+    private void validateIotOpeationFillExists(Long id) {
+        if (iotOpeationFillMapper.selectById(id) == null) {
+            throw exception(IOT_OPEATION_FILL_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IotOpeationFillDO getIotOpeationFill(Long id) {
+        return iotOpeationFillMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<IotOpeationFillDO> getIotOpeationFillPage(IotOpeationFillPageReqVO pageReqVO) {
+        return iotOpeationFillMapper.selectPage(pageReqVO);
+    }
+
+
+    @Override
+    public List<IotDeviceDO> getFillDevices(IotDevicePageReqVO vo) {
+        return iotOpeationFillMapper.getFillDevices(vo);
+    }
+
+}

+ 70 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationmodel/IotOpeationModelService.java

@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.pms.service.iotopeationmodel;
+
+import java.util.*;
+import javax.validation.*;
+
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotOpeationModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotOpeationModelSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationmodel.IotOpeationModelDO;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+
+/**
+ * 运行记录模板主 Service 接口
+ *
+ * @author 芋道源码
+ */
+public interface IotOpeationModelService {
+
+    /**
+     * 创建运行记录模板主
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createIotOpeationModel(@Valid IotOpeationModelSaveReqVO createReqVO);
+
+    /**
+     * 更新运行记录模板主
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateIotOpeationModel(@Valid IotOpeationModelSaveReqVO updateReqVO);
+
+    /**
+     * 删除运行记录模板主
+     *
+     * @param id 编号
+     */
+    void deleteIotOpeationModel(Long id);
+
+    /**
+     * 获得运行记录模板主
+     *
+     * @param id 编号
+     * @return 运行记录模板主
+     */
+    IotOpeationModelDO getIotOpeationModel(Long id);
+
+
+    IotOpeationModelDO getNew();
+
+
+    int insertCom(IotOpeationModelDO modelDO);
+
+    int updateCom(IotOpeationModelDO modelDO);
+
+    int insertFillInfo(IotOpeationModelDO modelDO);
+
+    int updateFillInfo(IotOpeationModelDO modelDO);
+
+
+    /**
+     * 获得运行记录模板主分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 运行记录模板主分页
+     */
+    PageResult<IotOpeationModelDO> getIotOpeationModelPage(IotOpeationModelPageReqVO pageReqVO);
+
+}

+ 98 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotopeationmodel/IotOpeationModelServiceImpl.java

@@ -0,0 +1,98 @@
+package cn.iocoder.yudao.module.pms.service.iotopeationmodel;
+
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotOpeationModelPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.vo.IotOpeationModelSaveReqVO;
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationmodel.IotOpeationModelDO;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationmodel.IotOpeationModelMapper;
+import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_OPEATION_MODEL_NOT_EXISTS;
+
+/**
+ * 运行记录模板主 Service 实现类
+ *
+ * @author 芋道源码
+ */
+@Service
+@Validated
+public class IotOpeationModelServiceImpl implements IotOpeationModelService {
+
+    @Resource
+    private IotOpeationModelMapper iotOpeationModelMapper;
+
+    @Override
+    public Long createIotOpeationModel(IotOpeationModelSaveReqVO createReqVO) {
+        // 插入
+        IotOpeationModelDO iotOpeationModel = BeanUtils.toBean(createReqVO, IotOpeationModelDO.class);
+        iotOpeationModelMapper.insert(iotOpeationModel);
+        // 返回
+        return Long.valueOf(iotOpeationModel.getDeptId());
+    }
+
+    @Override
+    public void updateIotOpeationModel(IotOpeationModelSaveReqVO updateReqVO) {
+        // 校验存在
+        validateIotOpeationModelExists(updateReqVO.getId());
+        // 更新
+        IotOpeationModelDO updateObj = BeanUtils.toBean(updateReqVO, IotOpeationModelDO.class);
+        iotOpeationModelMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteIotOpeationModel(Long id) {
+        // 校验存在
+        validateIotOpeationModelExists(id);
+        // 删除
+        iotOpeationModelMapper.deleteById(id);
+    }
+
+    private void validateIotOpeationModelExists(Long id) {
+        if (iotOpeationModelMapper.selectById(id) == null) {
+            throw exception(IOT_OPEATION_MODEL_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public IotOpeationModelDO getIotOpeationModel(Long id) {
+        return iotOpeationModelMapper.selectById(id);
+    }
+
+    @Override
+    public IotOpeationModelDO getNew() {
+        return iotOpeationModelMapper.getNew();
+    }
+
+    @Override
+    public int insertCom(IotOpeationModelDO modelDO) {
+        return iotOpeationModelMapper.insertCom(modelDO);
+    }
+
+    @Override
+    public int updateCom(IotOpeationModelDO modelDO) {
+        return iotOpeationModelMapper.updateCom(modelDO);
+    }
+
+    @Override
+    public int insertFillInfo(IotOpeationModelDO modelDO) {
+        return iotOpeationModelMapper.insertFillInfo(modelDO);
+    }
+
+    @Override
+    public int updateFillInfo(IotOpeationModelDO modelDO) {
+        return iotOpeationModelMapper.updateFillInfo(modelDO);
+    }
+
+    @Override
+    public PageResult<IotOpeationModelDO> getIotOpeationModelPage(IotOpeationModelPageReqVO pageReqVO) {
+        return iotOpeationModelMapper.selectPage(pageReqVO);
+    }
+
+}

+ 13 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotModelTemplateAttrsMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.pms.dal.mysql.iotmodeltemplateattrs.IotModelTemplateAttrsMapper">
+
+
+    <select id="getAttrsByName"
+            parameterType="java.lang.String"
+            resultType="cn.iocoder.yudao.module.pms.dal.dataobject.iotmodeltemplateattrs.IotThingsModelDO">
+        select * from yanfan.iot_things_model where product_name = #{procutName}
+    </select>
+
+
+</mapper>

+ 66 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/resources/mapper/static/IotOpeationFillMapper.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper">
+
+
+    <select id="getDeviceIds"
+            resultType="cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO">
+        select distinct b.id from
+             rqiot.rq_iot_opeation_model a,
+             rqiot.rq_iot_device b
+        where
+            a.dept_id = b.dept_id
+          and
+            a.device_type = b.asset_class
+    </select>
+
+    <select id="selectFillList"
+            parameterType="cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO"
+            resultType="cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO">
+        select
+            b.dept_id,
+            b.device_code,
+            b.device_name,
+            a.fill_info fillContent,
+            a.org_name,
+            a.device_type,
+            b.id deviceId,
+            a.device_component
+        from
+            rqiot.rq_iot_opeation_model a,
+            rqiot.rq_iot_device b
+        where
+            a.dept_id = b.dept_id
+          and
+            a.device_type = b.asset_class
+        <if test="deptId != null  and deptId != ''">
+          and
+            a.dept_id = #{deptId}
+        </if>
+          and a.deleted = 0
+          and b.deleted = 0
+    </select>
+
+    <select id="fillList"
+            parameterType="cn.iocoder.yudao.module.pms.controller.admin.iotopeationfill.vo.IotOpeationFillPageReqVO"
+            resultType="cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO">
+        select * from rq_iot_opeation_fill
+        where
+            cre_date = #{creDate}
+        <if test="deptId != null  and deptId != ''">
+            and dept_id = #{deptId}
+        </if>
+        and deleted != 1
+    </select>
+
+    <insert id="insertFill"
+            parameterType="cn.iocoder.yudao.module.pms.dal.dataobject.iotopeationfill.IotOpeationFillDO">
+        insert into rq_iot_opeation_fill(dept_id,device_code,device_name,fill_content,device_type,org_name,cre_date,device_component,device_id)
+        values
+        <foreach collection="list" item="item" separator=",">
+            (#{item.deptId},#{item.deviceCode},#{item.deviceName},#{item.fillContent},
+            #{item.deviceType},#{item.orgName},#{item.creDate},#{item.deviceComponent},#{item.deviceId})
+        </foreach>
+    </insert>
+
+</mapper>

+ 5 - 1
yudao-server/src/main/resources/application-dev.yaml

@@ -68,13 +68,17 @@ spring:
             show-sql: true #JPA是否显示sql语句
             # 使用mysql的方言,否则报错
             database-platform: org.hibernate.dialect.MySQLDialect
+        yanfan:
+          url: jdbc:mysql://1.94.244.160:3306/yanfan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+          username: root
+          password: .N_Mdq!BR1W4
 
   # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
   redis:
     host: localhost # 地址
     port: 6379 # 端口
     database: 0  # 数据库索引
-    password: 123456
+    #password: 123456
 
 --- #################### 定时任务相关配置 ####################