소스 검색

Merge branch 'master-jdk17-dev' of http://120.27.232.27:3000/bozzysadmb/ISCS_Standard_Back into master-jdk17-dev

小车车 2 주 전
부모
커밋
2f81cd95ab
100개의 변경된 파일5279개의 추가작업 그리고 147개의 파일을 삭제
  1. 5 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java
  2. 3 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/exceptionmisplace/vo/ExceptionMisplaceRespVO.java
  3. 6 5
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/exceptionmisplace/vo/ExceptionMisplaceSaveReqVO.java
  4. 161 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/HardwareApiController.java
  5. 188 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/HardwareMaterialApiController.java
  6. 31 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/AutoReplaceMaterialVO.java
  7. 33 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/AutoReplaceReportVO.java
  8. 42 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetCheckVO.java
  9. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetHomePageVO.java
  10. 39 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetMaterialVO.java
  11. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetMaterialsVO.java
  12. 45 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckMaterialsDateVO.java
  13. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckProgressVO.java
  14. 30 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckStandardVO.java
  15. 36 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/ExMaterialTypeVO.java
  16. 36 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/InstructionVO.java
  17. 28 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsCheckInitVO.java
  18. 45 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsCheckVO.java
  19. 33 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsHomeVO.java
  20. 94 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketDetailVO.java
  21. 8 4
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketKeyRespVO.java
  22. 84 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketPointsRespVO.java
  23. 4 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketRespVO.java
  24. 19 19
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/MaterialsController.java
  25. 4 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/vo/ImportMaterialsVO.java
  26. 2 2
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsloan/MaterialsLoanController.java
  27. 10 4
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetPageReqVO.java
  28. 11 5
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetRespVO.java
  29. 9 5
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetSaveReqVO.java
  30. 22 24
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialstype/MaterialsTypeController.java
  31. 28 5
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialstype/vo/MaterialsTypeRespVO.java
  32. 15 10
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/cabinetopenrecord/CabinetOpenRecordDO.java
  33. 13 9
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/exceptionmisplace/ExceptionMisplaceDO.java
  34. 8 9
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/jobticket/JobTicketLocksetDO.java
  35. 10 12
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/mailsendtaskitem/MailSendTaskItemDO.java
  36. 20 2
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materials/MaterialsDO.java
  37. 8 8
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialschangerecord/MaterialsChangeRecordDO.java
  38. 2 2
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialscheckplan/MaterialsCheckPlanDO.java
  39. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialscheckrecord/MaterialsCheckRecordDO.java
  40. 12 16
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialsloan/MaterialsLoanDO.java
  41. 8 2
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialsplancabinet/MaterialsPlanCabinetDO.java
  42. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/ExDTO.java
  43. 30 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsJobCardExDTO.java
  44. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsKeyExDTO.java
  45. 31 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockCabinetSlotsExDTO.java
  46. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockExDTO.java
  47. 26 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/CoincidePointToUnLockDTO.java
  48. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LPBParamDTO.java
  49. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LTParamDTO.java
  50. 38 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanMaterialDTO.java
  51. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanParamDTO.java
  52. 33 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointBatchDTO.java
  53. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointDTO.java
  54. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LocksetPointDTO.java
  55. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ParamDTO.java
  56. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnKeyDTO.java
  57. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnLocksetDTO.java
  58. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnTicketLockDTO.java
  59. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeLocksetDTO.java
  60. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeOutKeyDTO.java
  61. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeTicketLockDTO.java
  62. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateColockerStatusDTO.java
  63. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateKeyStatusDTO.java
  64. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateSwitchParam.java
  65. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateTicketStatusDTO.java
  66. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/AddLoanDTO.java
  67. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/AutoChangeDTO.java
  68. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CabinetRfidListDTO.java
  69. 22 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CheckParamDTO.java
  70. 37 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CheckRecordDTO.java
  71. 22 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/OpenTimeoutDTO.java
  72. 26 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RecRetMaterialDTO.java
  73. 22 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RecRetParamDTO.java
  74. 49 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialDTO.java
  75. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialParamDTO.java
  76. 28 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialsDTO.java
  77. 26 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReturnLoanDTO.java
  78. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RfidListDTO.java
  79. 25 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/SignDTO.java
  80. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/StartCheckPlanDTO.java
  81. 21 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/SubmitPlanDTO.java
  82. 2 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/isolationpoint/IsolationPointMapper.java
  83. 3 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketKeyMapper.java
  84. 7 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketLockMapper.java
  85. 16 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketMapper.java
  86. 8 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketPointsMapper.java
  87. 2 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketUserMapper.java
  88. 5 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materials/MaterialsMapper.java
  89. 4 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialscheckrecord/MaterialsCheckRecordMapper.java
  90. 5 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialsloan/MaterialsLoanMapper.java
  91. 12 4
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialstype/MaterialsTypeMapper.java
  92. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/KeyStatusEnum.java
  93. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LockStatusEnum.java
  94. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LocksetStatusEnum.java
  95. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/PointStatusEnum.java
  96. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/TicketStatusEnum.java
  97. 145 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiService.java
  98. 1182 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiServiceImpl.java
  99. 179 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareMaterialApiService.java
  100. 1299 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareMaterialApiServiceImpl.java

+ 5 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/exception/ServiceException.java

@@ -33,6 +33,11 @@ public final class ServiceException extends RuntimeException {
         this.message = errorCode.getMsg();
     }
 
+    public ServiceException(String message)
+    {
+        this.message = message;
+    }
+
     public ServiceException(Integer code, String message) {
         this.code = code;
         this.message = message;

+ 3 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/exceptionmisplace/vo/ExceptionMisplaceRespVO.java

@@ -22,6 +22,9 @@ public class ExceptionMisplaceRespVO {
     @ExcelProperty("物资ID")
     private Long materialsId;
 
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
+
     @Schema(description = "物资")
     private String materialsName;
 

+ 6 - 5
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/exceptionmisplace/vo/ExceptionMisplaceSaveReqVO.java

@@ -1,10 +1,8 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.exceptionmisplace.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import jakarta.validation.constraints.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
+
 import java.time.LocalDateTime;
 
 @Schema(description = "管理后台 - 物资归还异常新增/修改 Request VO")
@@ -17,6 +15,9 @@ public class ExceptionMisplaceSaveReqVO {
     @Schema(description = "物资ID", example = "30106")
     private Long materialsId;
 
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
+
     @Schema(description = "出借主键ID", example = "13436")
     private Long materialsLoanId;
 
@@ -44,4 +45,4 @@ public class ExceptionMisplaceSaveReqVO {
     @Schema(description = "异常类型(字典exception_type)", example = "2")
     private String exceptionType;
 
-}
+}

+ 161 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/HardwareApiController.java

@@ -0,0 +1,161 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketRespVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketSaveReqVO;
+import cn.iocoder.yudao.module.iscs.dal.dto.exUpdate.ExDTO;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi.*;
+import cn.iocoder.yudao.module.iscs.service.hardwareapi.HardwareApiService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 硬件调用接口
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Tag(name = "管理后台 - 锁控机柜调用")
+@RestController
+@RequestMapping("/iscs/hardware-api")
+@Validated
+public class HardwareApiController {
+    @Autowired
+    private HardwareApiService hardwareApiService;
+
+    // ----------------------------------作业票取还钥匙-------------------------------------------------------
+    @Operation(summary = "取出钥匙")
+    @PostMapping("/updateTakeOutKey")
+    public CommonResult<Boolean> updateTakeOutKey(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") TakeOutKeyDTO dto) {
+        return CommonResult.success(hardwareApiService.updateTakeOutKey(dto));
+    }
+
+    @Operation(summary = "归还钥匙")
+    @PostMapping("/updateReturnKey")
+    public CommonResult<Boolean> updateReturnKey(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") ReturnKeyDTO dto) {
+        return CommonResult.success(hardwareApiService.updateReturnKey(dto));
+    }
+
+
+    // ----------------------------------作业票取还挂锁-------------------------------------------------------
+    @Operation(summary = "取出挂锁时更新数据")
+    @PostMapping("/updateTicketLockTake")
+    public CommonResult<Boolean> updateTicketLockTake(@RequestBody @Parameter(name = "list", description = "修改数据类,放到body") ParamDTO dto) {
+        return CommonResult.success(hardwareApiService.updateTicketLockTake(dto.getList()));
+    }
+
+    @Operation(summary = "归还挂锁时更新数据")
+    @PostMapping("/updateTicketLockReturn")
+    public CommonResult<Boolean> updateTicketLockReturn(@RequestBody @Parameter(name = "list", description = "修改数据类,放到body") ReturnTicketLockDTO dto) {
+        return CommonResult.success(hardwareApiService.updateTicketLockReturn(dto));
+    }
+
+    @Operation(summary = "批量更新作业票下隔离点的上锁状况")
+    @PostMapping("/updateLockPointBatch")
+    public CommonResult<Boolean> updateLockPointBatch(@RequestBody @Parameter(name = "list", description = "修改数据类,放到body") LPBParamDTO dto) {
+        return CommonResult.success(hardwareApiService.updateLockPointBatch(dto.getList()));
+    }
+
+
+    // ----------------------------------作业票取还辅件-------------------------------------------------------
+    @Operation(summary = "取出辅件时更新数据")
+    @PostMapping("/updateLocksetTake")
+    public CommonResult<Boolean> updateLocksetTake(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") LTParamDTO dto) {
+        return CommonResult.success(hardwareApiService.updateLocksetTake(dto.getList()));
+    }
+
+    @Operation(summary = "辅件绑定隔离点(辅件和给隔离点上锁时)")
+    @PostMapping("/updateLocksetPoint")
+    public CommonResult<Boolean> updateLocksetPoint(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") LocksetPointDTO dto) {
+        return CommonResult.success(hardwareApiService.updateLocksetPoint(dto));
+    }
+
+    @Operation(summary = "辅件归还物资柜")
+    @PostMapping("/updateLocksetReturn")
+    public CommonResult<Boolean> updateLocksetReturn(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") ReturnLocksetDTO dto) {
+        return CommonResult.success(hardwareApiService.updateLocksetReturn(dto));
+    }
+
+    // ----------------------------------作业票及作业票的相关数据查询-------------------------------------------------------
+    @Operation(summary = "获取作业票和关联数据")
+    @Parameter(name = "ticketId", description = "ticketId")
+    @GetMapping(value = "/selectTicketDetailById")
+    public CommonResult<JobTicketRespVO> selectTicketDetailById(Long ticketId) {
+        return CommonResult.success(hardwareApiService.selectTicketDetailById(ticketId));
+    }
+
+    // 共锁人上锁/解锁
+    @Operation(summary = "共锁人上锁/解锁")
+    @PostMapping("/updateColockerStatus")
+    public CommonResult<Boolean> updateColockerStatus(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") UpdateColockerStatusDTO dto) {
+        return CommonResult.success(hardwareApiService.updateColockerStatus(dto));
+    }
+
+    @Operation(summary = "批量更新隔离点开关状态")
+    @PostMapping("/updateSwitchList")
+    public CommonResult<Boolean> updateSwitchList(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") UpdateSwitchParam dto) {
+        return CommonResult.success(hardwareApiService.updateSwitchList(dto));
+    }
+
+    // ----------------------------------作业票及作业票的相关数据查询-------------------------------------------------------
+
+    @Operation(summary = "上锁取钥匙前检查")
+    @Parameter(name = "ticketId", description = "ticketId")
+    @GetMapping(value = "/checkBeforeToLock")
+    public CommonResult<Boolean> checkBeforeToLock(Long ticketId) {
+        return CommonResult.success(hardwareApiService.checkBeforeToLock(ticketId));
+    }
+
+    @Operation(summary = "解锁取钥匙前检查")
+    @Parameter(name = "ticketId", description = "ticketId")
+    @GetMapping(value = "/checkBeforeToUnlock")
+    public CommonResult<Boolean> checkBeforeToUnlock(Long ticketId) {
+        return CommonResult.success(hardwareApiService.checkBeforeToUnlock(ticketId));
+    }
+
+    @Operation(summary = "重合点位数据解锁")
+    @PostMapping("/updateCoincideToUnLock")
+    public CommonResult<Boolean> updateCoincideToUnLock(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") CoincidePointToUnLockDTO dto) {
+        return CommonResult.success(hardwareApiService.updateCoincideToUnLock(dto));
+    }
+
+    // ----------------------------------批量更新硬件状态-------------------------------------------------------
+    @Operation(summary = "批量更新硬件状态")
+    @PostMapping("/updateHardwareEsStatus")
+    public CommonResult<Boolean> updateHardwareEsStatus(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") ExDTO dto) {
+        return CommonResult.success(hardwareApiService.updateHardwareEsStatus(dto));
+    }
+
+    // ----------------------------------判断当前登陆人员是否有需要去上所或者去解锁的需求-------------------------------------------------------
+    @Operation(summary = "判断当前登陆人员是否有需要去上所或者去解锁的需求")
+    @GetMapping(value = "/getMySelfState")
+    public CommonResult<Boolean> getMySelfState() {
+        return CommonResult.success(hardwareApiService.getMySelfState());
+    }
+
+    @Operation(summary = "判断当前锁还入时能不能锁")
+    @GetMapping(value = "/getLockStateByNfc")
+    public CommonResult<Integer> getLockStateByNfc(String nfc) {
+        return CommonResult.success(hardwareApiService.getLockStateByNfc(nfc, null));
+    }
+
+
+    @Operation(summary = "mars结束作业票")
+    @PostMapping("/updateJobToFinish")
+    public CommonResult<Boolean> updateJobToFinish(@RequestBody @Valid JobTicketSaveReqVO isJobTicket) {
+        return CommonResult.success(hardwareApiService.updateJobToFinish(isJobTicket));
+    }
+
+    @Operation(summary = "mars取消作业票")
+    @PostMapping("/updateJobToCancel")
+    public CommonResult<Boolean> updateJobToCancel(@RequestBody @Valid JobTicketSaveReqVO isJobTicket) {
+        return CommonResult.success(hardwareApiService.updateJobToCancel(isJobTicket));
+    }
+
+
+}

+ 188 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/HardwareMaterialApiController.java

@@ -0,0 +1,188 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi.*;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.cabinetopenrecord.CabinetOpenRecordDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi.*;
+import cn.iocoder.yudao.module.iscs.service.hardwareapi.HardwareMaterialApiService;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 硬件调用接口
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Tag(name = "管理后台 - 硬件物资调用接口")
+@RestController
+@Validated
+@RequestMapping("/iscs/hardware/material-api")
+public class HardwareMaterialApiController {
+    @Autowired
+    private HardwareMaterialApiService hardwareMaterialApiService;
+
+    // ----------------------------------手动更换物资-------------------------------------------------------
+    @Operation(summary = "获取物资柜手动更换物资类型和异常数量和物资信息")
+    @Parameter(name = "cabinetId / cabinetCode", description = "物资柜ID / 物资柜code")
+    @GetMapping(value = "/selectExMaterialTypeById")
+    public CommonResult<List<ExMaterialTypeVO>> selectExMaterialTypeById(Long cabinetId, String cabinetCode) throws JsonProcessingException {
+        return CommonResult.success(hardwareMaterialApiService.selectExMaterialTypeById(cabinetId, cabinetCode));
+    }
+
+
+    @Operation(summary = "手动更换物资-校验后的提交")
+    @PostMapping("/insertCheckedRecord")
+    public CommonResult<Boolean> insertCheckedRecord(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") ReplaceMaterialParamDTO dto) throws JsonProcessingException {
+        return CommonResult.success(hardwareMaterialApiService.insertCheckedRecord(dto));
+    }
+
+    @Operation(summary = "手动更换物资")
+    @PostMapping("/insertReplaceRecord")
+    public CommonResult<Boolean> insertReplaceRecord(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") ReplaceMaterialParamDTO dto) throws JsonProcessingException {
+        return CommonResult.success(hardwareMaterialApiService.insertReplaceRecord(dto));
+    }
+
+    @Operation(summary = "手动更换物资-实体操作")
+    @PostMapping("/updateMaterialsReplace")
+    public CommonResult<Boolean> updateMaterialsReplace(@RequestBody @Parameter(name = "dto", description = "修改数据类,放到body") ReplaceMaterialsDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.updateMaterialsReplace(dto));
+    }
+
+
+    // ----------------------------------物资柜开门异常-------------------------------------------------------
+
+    @Operation(summary = "新增物资柜开门超时异常")
+    @PostMapping("/insertCabinetOpenTimeout")
+    public CommonResult<Boolean> insertCabinetOpenTimeout(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") OpenTimeoutDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertCabinetOpenTimeout(dto));
+    }
+
+    @Operation(summary = "解除柜开门超时异常")
+    @PostMapping("/updateCabinetOpenTimeout")
+    public CommonResult<Boolean> updateCabinetOpenTimeout(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") OpenTimeoutDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.updateCabinetOpenTimeout(dto));
+    }
+
+    // ----------------------------------物资柜开门记录-------------------------------------------------------
+
+    @Operation(summary = "新增物资柜开门记录")
+    @PostMapping("/insertCabinetOpenRecord")
+    public CommonResult<Boolean> insertCabinetOpenRecord(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") CabinetOpenRecordDO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertCabinetOpenRecord(dto));
+    }
+
+    @Operation(summary = "物资柜关门")
+    @PostMapping("/updateCabinetClose")
+    public CommonResult<Boolean> updateCabinetClose(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") CabinetOpenRecordDO dto) {
+        return CommonResult.success(hardwareMaterialApiService.updateCabinetClose(dto));
+    }
+
+    // ----------------------------------物资取还-------------------------------------------------------
+    @Operation(summary = "获取物资柜物品分类及分类下物资数量和列表")
+    @Parameter(name = "cabinetId / cabinetCode", description = "物资柜ID / 物资柜CODE")
+    @GetMapping(value = "/selectMaterialsByCabinetId")
+    public CommonResult<List<CabinetMaterialVO>> selectMaterialsByCabinetId(Long cabinetId, String cabinetCode) throws JsonProcessingException {
+        return CommonResult.success(hardwareMaterialApiService.selectMaterialsByCabinetId(cabinetId, cabinetCode));
+    }
+
+    @Operation(summary = "通过RFID获取物资信息")
+    @Parameter(name = "rfid", description = "物资rfid")
+    @GetMapping(value = "/selectMaterialByRfid")
+    public CommonResult<MaterialsDO> selectMaterialByRfid(String rfid) {
+        return CommonResult.success(hardwareMaterialApiService.selectMaterialByRfid(rfid));
+    }
+
+    @Operation(summary = "通过RFID列表获取批量物资信息")
+    @Parameter(name = "list", description = "物资rfid列表")
+    @PostMapping(value = "/selectMaterialsByRfidList")
+    public CommonResult<List<MaterialsDO>> selectMaterialsByRfidList(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") RfidListDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.selectMaterialsByRfidList(dto));
+    }
+
+    @Operation(summary = "RFID所属柜子区分")
+    @Parameter(name = "list", description = "物资rfid列表")
+    @PostMapping(value = "/selectCabinetMaterials")
+    public CommonResult<CabinetMaterialsVO> selectCabinetMaterials(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") CabinetRfidListDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.selectCabinetMaterials(dto));
+    }
+
+    // ----------------------------------主界面-------------------------------------------------------
+    @Operation(summary = "主界面")
+    @Parameter(name = "cabinetCode", description = "物资柜CODE")
+    @GetMapping("/getCabinetHomePage")
+    public CommonResult<CabinetHomePageVO> getCabinetHomePage(String cabinetCode) {
+        CabinetHomePageVO result = hardwareMaterialApiService.getCabinetHomePage(cabinetCode);
+        return CommonResult.success(result);
+    }
+
+    // ----------------------------------物资使用说明-------------------------------------------------------
+    @Operation(summary = "查询物资使用说明")
+    @GetMapping("/getInstructionsList")
+    public CommonResult<List<InstructionVO>> getInstructionsList() {
+        List<InstructionVO> result = hardwareMaterialApiService.getInstructionsList();
+        return CommonResult.success(result);
+    }
+
+    // ----------------------------------物资检查计划-------------------------------------------------------
+    @Operation(summary = "在某个柜子上我的最近一次物资检查计划")
+    @Parameter(name = "cabinetCode", description = "物资柜CODE")
+    @GetMapping("/getLastCheckPlanByCabinetCode")
+    public CommonResult<CabinetCheckVO> getLastCheckPlanByCabinetCode(String cabinetCode) {
+        CabinetCheckVO result = hardwareMaterialApiService.getLastCheckPlanByCabinetCode(cabinetCode);
+        return CommonResult.success(result);
+    }
+
+    @Operation(summary = "物资检查表")
+    @Parameters({
+            @Parameter(name = "cabinetCode", description = "物资柜CODE"),
+            @Parameter(name = "planId", description = "物资计划id")}
+    )
+    @GetMapping("/getCheckMaterialsByCabinetCode")
+    public CommonResult<MaterialsCheckInitVO> getCheckMaterialsByCabinetCode(String cabinetCode, Long planId) {
+        MaterialsCheckInitVO result = hardwareMaterialApiService.getCheckMaterialsByCabinetCode(cabinetCode, planId);
+        return CommonResult.success(result);
+    }
+
+    @Operation(summary = "开始检查")
+    @PostMapping("/startCheckPlan")
+    public CommonResult<Boolean> startCheckPlan(@RequestBody @Parameter(name = "dto", description = "放到body") StartCheckPlanDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.startCheckPlan(dto));
+    }
+
+    @Operation(summary = "提交物资检查记录")
+    @PostMapping("/insertCheckRecord")
+    public CommonResult<Boolean> insertCheckRecord(@RequestBody @Parameter(name = "dto", description = "放到body") CheckParamDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertCheckRecord(dto));
+    }
+
+    @Operation(summary = "最终提交物资检查记录")
+    @PostMapping("/insertSubmitPlan")
+    public CommonResult<Boolean> insertSubmitPlan(@RequestBody @Parameter(name = "dto", description = "放到body") SubmitPlanDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertSubmitPlan(dto));
+    }
+
+    @Operation(summary = "检查签名")
+    @PostMapping("/insertSign")
+    public CommonResult<Boolean> insertSign(@RequestBody @Parameter(name = "dto", description = "放到body") SignDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertSign(dto));
+    }
+
+
+    // ----------------------------------自动更换-------------------------------------------------------
+    @Operation(summary = "自动更换")
+    @PostMapping("/insertAutoChange")
+    public CommonResult<AutoReplaceReportVO> insertAutoChange(@RequestBody @Parameter(name = "dto", description = "数据类,放到body") AutoChangeDTO dto) {
+        return CommonResult.success(hardwareMaterialApiService.insertAutoChange(dto));
+    }
+
+}

+ 31 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/AutoReplaceMaterialVO.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资更换记录对象 is_materials_change_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class AutoReplaceMaterialVO
+{
+
+    @Schema(description = "物资名称")
+    private String materialsName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
+
+    @Schema(description = "物资状态(字典material_info_status)")
+    private String status;
+
+}

+ 33 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/AutoReplaceReportVO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 物资更换记录对象 is_materials_change_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class AutoReplaceReportVO
+{
+
+    @JsonFormat(timezone="GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "创建时间")
+    private Date createTime;
+
+    @Schema(description = "用户名称")
+    private String nikeName;
+
+    @Schema(description = "放入物资")
+    private List<AutoReplaceMaterialVO> bindingList;
+
+    @Schema(description = "取出物资")
+    private List<AutoReplaceMaterialVO> unbindingList;
+
+}

+ 42 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetCheckVO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CabinetCheckVO {
+
+    @Schema(description = "物资计划id")
+    private Long planId;
+
+    @Schema(description = "计划名称")
+    private String planName;
+
+    @Schema(description = "计划日期")
+    @JsonFormat(timezone="GMT+8", pattern = "yyyy-MM-dd")
+    private Date planDate;
+
+    @Schema(description = "检查状态(0代表未开始,1代表已完成, 2代表进行中)")
+    private Integer status;
+
+    @Schema(description = "签名图片")
+    private String signatureImg;
+
+    @Schema(description = "签名时间")
+    @JsonFormat(timezone="GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date signatureTime;
+
+    @Schema(description = "物资类型分类检查结果")
+    private List<MaterialsCheckVO> list;
+
+}

+ 29 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetHomePageVO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CabinetHomePageVO {
+
+    @Schema(description = "物资取还数量")
+    private Integer rarNumber;
+
+    @Schema(description = "物资检查数量")
+    private Integer checkNumber;
+
+    @Schema(description = "物资更换数量")
+    private Integer changeNumber;
+
+    @Schema(description = "物资类型分类数据")
+    private List<MaterialsHomeVO> list;
+
+}

+ 39 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetMaterialVO.java

@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CabinetMaterialVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资数量")
+    private Integer number;
+
+    @Schema(description = "可借数量")
+    private Integer borrowableNumber;
+
+    @Schema(description = "物资列表(该物资柜所有物资)")
+    private List<MaterialsRespVO> materials;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CabinetMaterialsVO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscabinet.MaterialsCabinetDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ *
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CabinetMaterialsVO {
+
+    @Schema(description = "柜子信息")
+    private MaterialsCabinetDO isMaterialsCabinet;
+
+    @Schema(description = "当前物资柜子物资RFID")
+    private List<String> cabinetRfidList;
+
+    @Schema(description = "非当前物资柜子的系统内物资")
+    private List<String> notCabinetRfidList;
+
+}

+ 45 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckMaterialsDateVO.java

@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CheckMaterialsDateVO {
+
+    @Schema(description = "物资柜ID")
+    private Long materialsCabinetId;
+
+    @Schema(description = "物资ID")
+    private Long materialsId;
+
+    @Schema(description = "物资名称")
+    private String materialsName;
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资状态(字典material_info_status)")
+    private String status;
+
+    @Schema(description = "物资检查标准")
+    private String checkStandard;
+
+}

+ 29 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckProgressVO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CheckProgressVO {
+
+
+    @Schema(description = "待检查")
+    private Integer checkNum;
+
+    @Schema(description = "正常")
+    private Integer normalNum;
+
+    @Schema(description = "过期")
+    private Integer timeOutNum;
+
+    @Schema(description = "损坏")
+    private Integer badNum;
+
+
+}

+ 30 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/CheckStandardVO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CheckStandardVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资检查标准")
+    private String checkStandard;
+
+}

+ 36 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/ExMaterialTypeVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class ExMaterialTypeVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "异常数量")
+    private Integer exNumber;
+
+    @Schema(description = "异常的物资")
+    private List<MaterialsRespVO> materials;
+
+}

+ 36 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/InstructionVO.java

@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialsinstructions.MaterialsInstructionsDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class InstructionVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "统计数据")
+    private Integer number;
+
+    @Schema(description = "该类型下的物资使用说明")
+    private List<MaterialsInstructionsDO> instructions;
+
+}

+ 28 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsCheckInitVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscheckrecord.MaterialsCheckRecordDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class MaterialsCheckInitVO {
+
+    @Schema(description = "物资检查数据")
+    private List<MaterialsCheckRecordDO> list;
+
+    @Schema(description = "物资检查标准")
+    private List<CheckStandardVO> standards;
+
+    @Schema(description = "下方统计")
+    private CheckProgressVO checkProgressVO;
+
+
+}

+ 45 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsCheckVO.java

@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class MaterialsCheckVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资总数量")
+    private Integer allNumber;
+
+    @Schema(description = "借出数量")
+    private Integer loanNumber;
+
+    @Schema(description = "待检数量")
+    private Integer checkNumber;
+
+    @Schema(description = "正常数量")
+    private Integer normalNumber;
+
+    @Schema(description = "过期数量")
+    private Integer timeoutNumber;
+
+    @Schema(description = "损坏数量")
+    private Integer badNumber;
+
+}

+ 33 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/hardwareMaterialApi/MaterialsHomeVO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class MaterialsHomeVO {
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资类型名称")
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    private String materialsTypePicture;
+
+    @Schema(description = "物资总数量")
+    private Integer allNumber;
+
+    @Schema(description = "可借数量")
+    private Integer borrowableNumber;
+
+}

+ 94 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketDetailVO.java

@@ -0,0 +1,94 @@
+package cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo;
+
+import cn.iocoder.yudao.module.iscs.controller.admin.isolationpoint.vo.PointDetailVO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketUserDO;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 作业票对象 is_job_ticket
+ *
+ * @author cgj
+ * @date 2024-10-18
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class JobTicketDetailVO {
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "作业票编号")
+    private String ticketCode;
+
+    @Schema(description = "作业票名称")
+    private String ticketName;
+
+    @Schema(description = "所属车间ID")
+    private Long workshopId;
+
+    @Schema(description = "所属车间Name")
+    private String workshopName;
+
+    @Schema(description = "所属区域ID")
+    private Long workareaId;
+
+    @Schema(description = "所属区域Name")
+    private String workareaName;
+
+    @Schema(description = "所属SOPID")
+    private Long sopId;
+
+    @Schema(description = "所属SOPNAME")
+    private String sopName;
+
+    @Schema(description = "作业票类型")
+    private String ticketType;
+
+    @Schema(description = "作业票详情")
+    private String ticketContent;
+
+    @Schema(description = "作业票状态")
+    private String ticketStatus;
+
+    @Schema(description = "作业票开始时间")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date ticketStartTime;
+
+    @Schema(description = "作业票结束时间")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date ticketEndTime;
+
+    @Schema(description = "删除标志(0代表存在 2代表删除)")
+    private String delFlag;
+
+    @Schema(description = "挂锁ID")
+    private Long lockId;
+
+    @Schema(description = "上锁钥匙ID")
+    private Long lockedByKeyId;
+
+    @Schema(description = "解锁钥匙ID")
+    private Long unlockedByKeyId;
+
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "上锁时间")
+    private Date lockTime;
+
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    @Schema(description = "解锁时间")
+    private Date unlockTime;
+
+    @Schema(description = "隔离点数据")
+    private List<PointDetailVO> pointDetailVOList;
+
+    @Schema(description = "人员数据")
+    private List<JobTicketUserDO> jobTicketUserList;
+
+}

+ 8 - 4
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketKeyRespVO.java

@@ -1,11 +1,11 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
+
 import java.time.LocalDateTime;
-import com.alibaba.excel.annotation.*;
 
 @Schema(description = "管理后台 - 作业票钥匙 Response VO")
 @Data
@@ -56,4 +56,8 @@ public class JobTicketKeyRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
+    @Schema(description = "钥匙nfc", example = "3195qw6")
+    @ExcelProperty("钥匙nfc")
+    private String keyNfc;
+
 }

+ 84 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketPointsRespVO.java

@@ -2,10 +2,12 @@ package cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo;
 
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.Date;
 
 @Schema(description = "管理后台 - 作业票隔离点 Response VO")
 @Data
@@ -87,6 +89,8 @@ public class JobTicketPointsRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
+
+
     @Schema(description = "作用", example = "作用")
     @ExcelProperty("作用")
     private String ability;
@@ -95,4 +99,84 @@ public class JobTicketPointsRespVO {
     @ExcelProperty("锁定人")
     private String lockUserName;
 
+    @Schema(description = "隔离点nfc")
+    private String pointNfc;
+
+    @Schema(description = "隔离点序列号")
+    private String pointSerialNumber;
+
+    @Schema(description = "挂锁Name")
+    private String lockName;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "锁具Name")
+    private String locksetName;
+
+    @Schema(description = "作用")
+    private String effect;
+
+    @Schema(description = "开关状态")
+    private String switchStatus;
+
+    @Schema(description = "开关状态最近更新时间")
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date switchLastUpdateTime;
+
+
+    @Schema(description = "隔离点类型")
+    private String pointType;
+
+    @Schema(description = "隔离点类型Name")
+    private String pointTypeName;
+
+    @Schema(description = "所属车间Name")
+    private String workshopName;
+
+    @Schema(description = "所属区域Name")
+    private String workareaName;
+
+    @Schema(description = "所属mars岗位Name")
+    private String workstationName;
+
+    @Schema(description = "所属电柜ID")
+    private Long lotoId;
+
+    @Schema(description = "所属电柜Name")
+    private String lotoName;
+
+    @Schema(description = "危险能量类型")
+    private String powerType;
+
+    @Schema(description = "危险能量类型Name")
+    private String powerTypeName;
+
+    @Schema(description = "隔离方式")
+    private String isolationMethod;
+
+    @Schema(description = "隔离点图标")
+    private String pointIcon;
+
+    @Schema(description = "隔离点图片")
+    private String pointPicture;
+
+    @Schema(description = "锁具类型id")
+    private Long lockTypeId;
+
+    @Schema(description = "锁具类型编码")
+    private String lockTypeCode;
+
+    @Schema(description = "锁具类型名称")
+    private String lockTypeName;
+
+    @Schema(description = "锁具类型图标")
+    private String lockTypeIcon;
+
+    @Schema(description = "锁具类型图片")
+    private String lockTypeImg;
+
+    @Schema(description = "辅件类型ID")
+    private Long locksetTypeId;
+
 }

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketRespVO.java

@@ -7,6 +7,7 @@ import lombok.Data;
 
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Set;
 
 @Schema(description = "管理后台 - 作业票 Response VO")
 @Data
@@ -121,4 +122,7 @@ public class JobTicketRespVO {
     @Schema(description = "作业日志")
     private List<TicketOperLogRespVO> ticketOperLogList;
 
+    @Schema(description = "解锁时禁止解除的点位")
+    private Set<JobTicketPointsRespVO> noUnlockTicketPointsVOSet;
+
 }

+ 19 - 19
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/MaterialsController.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materials;
 
+import cn.hutool.core.lang.Assert;
 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.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialBindingVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsPageReqVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
-import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsSaveReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.*;
 import cn.iocoder.yudao.module.iscs.service.materials.MaterialsService;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import io.swagger.v3.oas.annotations.Operation;
@@ -18,15 +16,18 @@ import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
+import org.apache.commons.io.FilenameUtils;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.UPDATE;
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 @Tag(name = "管理后台 - 物资")
@@ -91,10 +92,9 @@ public class MaterialsController {
         ExcelUtils.write(response, "物资.xls", "数据", MaterialsRespVO.class, list);
     }
 
-    /*@Operation(summary = "导入模板-物资")
+    @Operation(summary = "导入模板-物资")
     @PostMapping("/importTemplate")
-    public void importTemplate(HttpServletResponse response) {
-        ExcelUtil util = new ExcelUtil();
+    public void importTemplate(HttpServletResponse response) throws IOException {
         ImportMaterialsVO importMaterialsVO = new ImportMaterialsVO();
         importMaterialsVO.setCabinetName("测试物资柜(测试示例行可删除)");
         importMaterialsVO.setMaterialsName("测试白大褂K380(测试示例行可删除)");
@@ -105,24 +105,24 @@ public class MaterialsController {
         importMaterialsVO.setExpirationDate(new Date());
         ArrayList<ImportMaterialsVO> importMaterialsVOS = new ArrayList<>();
         importMaterialsVOS.add(importMaterialsVO);
-        util.importTempExcelWithDate(response, "物资数据", importMaterialsVOS);
-    }*/
+        ExcelUtils.write(response, "物资数据.xls", "物资数据", ImportMaterialsVO.class, importMaterialsVOS);
+    }
+
 
-    /*@Operation(summary = "导入-物资")
+
+    @Operation(summary = "导入-物资")
     @ApiAccessLog(operateType = IMPORT)
     @PreAuthorize("@ss.hasPermi('iscs:materials:import')")
     @PostMapping("/importMaterials")
-    public CommonResult<Boolean> importMaterials(MultipartFile file, boolean updateSupport) throws Exception {
+    public CommonResult<String> importMaterials(MultipartFile file) throws Exception {
         String filename = file.getOriginalFilename();
         String extension = FilenameUtils.getExtension(filename);
         // 文件不是 .xlsx 或 .xls
         Assert.isFalse(!"xls".equalsIgnoreCase(extension) && !"xlsx".equalsIgnoreCase(extension), "文件不是xls或xlsx,请重新上传!");
-        ExcelUtil<ImportMaterialsVO> util = new ExcelUtil<>(ImportMaterialsVO.class);
-        List<ImportMaterialsVO> itemList = util.importExcel(file.getInputStream());
-        String operName = getUsername();
-        String message = isMaterialsService.importMaterials(itemList, updateSupport, operName);
-        return AjaxResult.success(message);
-    }*/
+        List<ImportMaterialsVO> list = ExcelUtils.read(file, ImportMaterialsVO.class);
+        String message = materialsService.importMaterials(list);
+        return CommonResult.success(message);
+    }
 
     @Operation(summary = "绑定物资-物资柜绑定物资")
     @PreAuthorize("@ss.hasPermission('iscs:materials:binding')")

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materials/vo/ImportMaterialsVO.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materials.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
@@ -18,6 +19,7 @@ public class ImportMaterialsVO
 {
 
     @Schema(description = "物资柜ID")
+    @ExcelIgnore
     private Long materialsCabinetId;
 
     @Schema(description = "物资柜Name")
@@ -29,6 +31,7 @@ public class ImportMaterialsVO
     private String materialsName;
 
     @Schema(description = "物资类型ID")
+    @ExcelIgnore
     private Long materialsTypeId;
 
     @ExcelProperty(value = "物资类型")
@@ -50,6 +53,7 @@ public class ImportMaterialsVO
     @ExcelProperty(value = "有效期")
     private Date expirationDate;
 
+    @ExcelIgnore
     private String properties;
 
 }

+ 2 - 2
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsloan/MaterialsLoanController.java

@@ -36,12 +36,12 @@ public class MaterialsLoanController {
     @Resource
     private MaterialsLoanService materialsLoanService;
 
-    @PostMapping("/insertMaterialsLoan")
+    /*@PostMapping("/insertMaterialsLoan")
     @Operation(summary = "创建物资借出")
     @PreAuthorize("@ss.hasPermission('iscs:materials-loan:create')")
     public CommonResult<Long> insertMaterialsLoan(@Valid @RequestBody MaterialsLoanSaveReqVO createReqVO) {
         return success(materialsLoanService.createMaterialsLoan(createReqVO));
-    }
+    }*/
 
     @PutMapping("/updateMaterialsLoan")
     @Operation(summary = "更新物资借出")

+ 10 - 4
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetPageReqVO.java

@@ -1,10 +1,10 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materialsplancabinet.vo;
 
-import lombok.*;
-import java.util.*;
-import io.swagger.v3.oas.annotations.media.Schema;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
 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;
@@ -23,8 +23,14 @@ public class MaterialsPlanCabinetPageReqVO extends PageParam {
     @Schema(description = "是否提交(0-否 1-是)")
     private String submit;
 
+    @Schema(description = "检查状态(0代表未开始,1代表已完成 2.进行中)")
+    private String status;
+
     @Schema(description = "创建时间")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
-}
+    @Schema(description = "检察员")
+    private Long checkUserId;
+
+}

+ 11 - 5
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetRespVO.java

@@ -1,11 +1,11 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materialsplancabinet.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
+
 import java.time.LocalDateTime;
-import com.alibaba.excel.annotation.*;
 
 @Schema(description = "管理后台 - 物资检查计划关联物资柜 Response VO")
 @Data
@@ -32,8 +32,14 @@ public class MaterialsPlanCabinetRespVO {
     @ExcelProperty("是否提交(0-否 1-是)")
     private String submit;
 
+    @Schema(description = "检查状态(0代表未开始,1代表已完成 2.进行中)")
+    private String status;
+
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
-}
+    @Schema(description = "检察员")
+    private Long checkUserId;
+
+}

+ 9 - 5
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialsplancabinet/vo/MaterialsPlanCabinetSaveReqVO.java

@@ -1,10 +1,8 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materialsplancabinet.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import jakarta.validation.constraints.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
+
 import java.time.LocalDateTime;
 
 @Schema(description = "管理后台 - 物资检查计划关联物资柜新增/修改 Request VO")
@@ -26,4 +24,10 @@ public class MaterialsPlanCabinetSaveReqVO {
     @Schema(description = "是否提交(0-否 1-是)")
     private String submit;
 
-}
+    @Schema(description = "检查状态(0代表未开始,1代表已完成 2.进行中)")
+    private String status;
+
+    @Schema(description = "检察员")
+    private Long checkUserId;
+
+}

+ 22 - 24
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialstype/MaterialsTypeController.java

@@ -1,33 +1,31 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materialstype;
 
-import org.springframework.web.bind.annotation.*;
-import jakarta.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 jakarta.validation.constraints.*;
-import jakarta.validation.*;
-import jakarta.servlet.http.*;
-import java.util.*;
-import java.io.IOException;
-
+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.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.*;
-
-import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.*;
+import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.MaterialsTypePageReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.MaterialsTypeRespVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.MaterialsTypeSaveReqVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materialstype.MaterialsTypeDO;
 import cn.iocoder.yudao.module.iscs.service.materialstype.MaterialsTypeService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
 @Tag(name = "管理后台 - 物资类型")
 @RestController
@@ -67,8 +65,8 @@ public class MaterialsTypeController {
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('iscs:materials-type:query')")
     public CommonResult<MaterialsTypeRespVO> selectMaterialsTypeById(@RequestParam("id") Long id) {
-        MaterialsTypeDO materialsType = materialsTypeService.getMaterialsType(id);
-        return success(BeanUtils.toBean(materialsType, MaterialsTypeRespVO.class));
+        MaterialsTypeRespVO materialsType = materialsTypeService.getMaterialsType(id);
+        return success(materialsType);
     }
 
     @GetMapping("/getMaterialsTypePage")

+ 28 - 5
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/materialstype/vo/MaterialsTypeRespVO.java

@@ -1,11 +1,13 @@
 package cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import org.springframework.format.annotation.DateTimeFormat;
+import lombok.Data;
+
 import java.time.LocalDateTime;
-import com.alibaba.excel.annotation.*;
 
 @Schema(description = "管理后台 - 物资类型 Response VO")
 @Data
@@ -80,4 +82,25 @@ public class MaterialsTypeRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
-}
+
+    @Schema(description = "物资规则ID")
+    @TableId(type = IdType.AUTO)
+    private Long ruleId;
+
+    @Schema(description = "是否需要归还")
+    private Integer restitutionRequired;
+
+    @Schema(description = "是否归还原位")
+    private Integer restorationRequired;
+
+    @Schema(description = "出借时长")
+    private Integer loanDuration;
+
+    @Schema(description = "提醒时间")
+    private Integer reminderTime;
+
+    @Schema(description = "超时报警")
+    private Integer timeoutAlarm;
+
+
+}

+ 15 - 10
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/cabinetopenrecord/CabinetOpenRecordDO.java

@@ -1,13 +1,14 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.cabinetopenrecord;
 
-import lombok.*;
-import java.util.*;
-import java.time.LocalDateTime;
-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;
+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 io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+
+import java.util.Date;
 
 /**
  * 物资柜开关门记录 DO
@@ -40,15 +41,19 @@ public class CabinetOpenRecordDO extends BaseDO {
     /**
      * 开门时间
      */
-    private LocalDateTime openTime;
+    private Date openTime;
     /**
      * 关门时间
      */
-    private LocalDateTime closeTime;
+    private Date closeTime;
     /**
      * 开门人员
      */
     private String userId;
 
+    @Schema(description = "物资柜code")
+    @TableField(exist = false)
+    private String cabinetCode;
+
 
-}
+}

+ 13 - 9
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/exceptionmisplace/ExceptionMisplaceDO.java

@@ -1,13 +1,14 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.exceptionmisplace;
 
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
-import java.util.*;
-import java.time.LocalDateTime;
-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;
+import java.util.Date;
 
 /**
  * 物资归还异常 DO
@@ -33,6 +34,9 @@ public class ExceptionMisplaceDO extends BaseDO {
      * 物资ID
      */
     private Long materialsId;
+
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
     /**
      * 出借主键ID
      */
@@ -52,11 +56,11 @@ public class ExceptionMisplaceDO extends BaseDO {
     /**
      * 异常处理时间
      */
-    private LocalDateTime handleTime;
+    private Date handleTime;
     /**
      * 异常发生时间
      */
-    private LocalDateTime occurTime;
+    private Date occurTime;
     /**
      * 备注
      */
@@ -71,4 +75,4 @@ public class ExceptionMisplaceDO extends BaseDO {
     private String exceptionType;
 
 
-}
+}

+ 8 - 9
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/jobticket/JobTicketLocksetDO.java

@@ -1,13 +1,12 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket;
 
-import lombok.*;
-import java.util.*;
-import java.time.LocalDateTime;
-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;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.util.Date;
 
 /**
  * 作业票锁具 DO
@@ -66,11 +65,11 @@ public class JobTicketLocksetDO extends BaseDO {
     /**
      * 取出时间
      */
-    private LocalDateTime collectTime;
+    private Date collectTime;
     /**
      * 归还时间
      */
-    private LocalDateTime giveBackTime;
+    private Date giveBackTime;
     /**
      * 备注
      */

+ 10 - 12
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/mailsendtaskitem/MailSendTaskItemDO.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.mailsendtaskitem;
 
-import lombok.*;
-import java.util.*;
-import java.time.LocalDateTime;
-import java.time.LocalDateTime;
-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;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.util.Date;
 
 /**
  * 系统邮件任务 DO
@@ -49,11 +47,11 @@ public class MailSendTaskItemDO extends BaseDO {
     /**
      * 实际发送时间
      */
-    private LocalDateTime sendTime;
+    private Date sendTime;
     /**
      * 计划发送时间
      */
-    private LocalDateTime scheduledSendTime;
+    private Date scheduledSendTime;
     /**
      * 所属计划id
      */
@@ -69,11 +67,11 @@ public class MailSendTaskItemDO extends BaseDO {
     /**
      * 取消时间
      */
-    private LocalDateTime cancelTime;
+    private Date cancelTime;
     /**
      * 备注
      */
     private String remark;
 
 
-}
+}

+ 20 - 2
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materials/MaterialsDO.java

@@ -2,12 +2,14 @@ package cn.iocoder.yudao.module.iscs.dal.dataobject.materials;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 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 io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 
-import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.Date;
 
 /**
  * 物资 DO
@@ -68,7 +70,7 @@ public class MaterialsDO extends BaseDO {
     /**
      * 有效期
      */
-    private LocalDate expirationDate;
+    private Date expirationDate;
     /**
      * 物资RFID
      */
@@ -98,5 +100,21 @@ public class MaterialsDO extends BaseDO {
      */
     private String status;
 
+    @Schema(description = "物资类型图标")
+    @TableField(exist = false)
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    @TableField(exist = false)
+    private String materialsTypePicture;
+
+    @Schema(description = "物资规格属性项")
+    @TableField(exist = false)
+    private String propertyIds;
+
+    @Schema(description = "最近借取人id")
+    @TableField(exist = false)
+    private Long loanUserId;
+
 
 }

+ 8 - 8
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialschangerecord/MaterialsChangeRecordDO.java

@@ -1,12 +1,12 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.materialschangerecord;
 
-import lombok.*;
-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;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.util.Date;
 
 /**
  * 物资更换记录 DO
@@ -55,7 +55,7 @@ public class MaterialsChangeRecordDO extends BaseDO {
     /**
      * 更换时间
      */
-    private LocalDateTime changeDate;
+    private Date changeDate;
     /**
      * 更换类型(0-手动更换 1-自动更换)
      */
@@ -70,4 +70,4 @@ public class MaterialsChangeRecordDO extends BaseDO {
     private String status;
 
 
-}
+}

+ 2 - 2
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialscheckplan/MaterialsCheckPlanDO.java

@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
-import java.time.LocalDate;
+import java.util.Date;
 
 /**
  * 物资检查计划 DO
@@ -39,7 +39,7 @@ public class MaterialsCheckPlanDO extends BaseDO {
     /**
      * 计划日期
      */
-    private LocalDate planDate;
+    private Date planDate;
     /**
      * 检察员
      */

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialscheckrecord/MaterialsCheckRecordDO.java

@@ -2,8 +2,10 @@ package cn.iocoder.yudao.module.iscs.dal.dataobject.materialscheckrecord;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 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 io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 
 import java.util.Date;
@@ -69,5 +71,26 @@ public class MaterialsCheckRecordDO extends BaseDO {
      */
     private String remark;
 
+    @Schema(description = "物资名称")
+    @TableField(exist = false)
+    private String materialsName;
+
+    @Schema(description = "物资类型名称")
+    @TableField(exist = false)
+    private String materialsTypeName;
+
+    @Schema(description = "物资类型图标")
+    @TableField(exist = false)
+    private String materialsTypeIcon;
+
+    @Schema(description = "物资类型缩略图")
+    @TableField(exist = false)
+    private String materialsTypePicture;
+
+    @Schema(description = "物资RFID")
+    @TableField(exist = false)
+    private String materialsRfid;
+
+
 
 }

+ 12 - 16
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialsloan/MaterialsLoanDO.java

@@ -1,16 +1,12 @@
 package cn.iocoder.yudao.module.iscs.dal.dataobject.materialsloan;
 
-import lombok.*;
-import java.util.*;
-import java.time.LocalDateTime;
-import java.time.LocalDateTime;
-import java.time.LocalDateTime;
-import java.time.LocalDateTime;
-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;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.util.Date;
 
 /**
  * 物资借出 DO
@@ -47,11 +43,11 @@ public class MaterialsLoanDO extends BaseDO {
     /**
      * 领取时间
      */
-    private LocalDateTime loanTime;
+    private Date loanTime;
     /**
      * 提醒时间
      */
-    private LocalDateTime reminderTime;
+    private Date reminderTime;
     /**
      * 归还人ID
      */
@@ -63,15 +59,15 @@ public class MaterialsLoanDO extends BaseDO {
     /**
      * 理应归还时间
      */
-    private LocalDateTime restitutionTime;
+    private Date restitutionTime;
     /**
      * 实际归还时间
      */
-    private LocalDateTime actualRestitutionTime;
+    private Date actualRestitutionTime;
     /**
      * 超时报警
      */
-    private LocalDateTime timeoutAlarm;
+    private Date timeoutAlarm;
     /**
      * 是否需要归还
      */
@@ -86,4 +82,4 @@ public class MaterialsLoanDO extends BaseDO {
     private String status;
 
 
-}
+}

+ 8 - 2
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/materialsplancabinet/MaterialsPlanCabinetDO.java

@@ -3,9 +3,10 @@ package cn.iocoder.yudao.module.iscs.dal.dataobject.materialsplancabinet;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.*;
 
-import java.time.LocalDateTime;
+import java.util.Date;
 
 /**
  * 物资检查计划关联物资柜 DO
@@ -30,6 +31,9 @@ public class MaterialsPlanCabinetDO extends BaseDO {
      * 物资柜ID
      */
     private Long cabinetId;
+
+    @Schema(description = "检察员")
+    private Long checkUserId;
     /**
      * 签名图片
      */
@@ -37,11 +41,13 @@ public class MaterialsPlanCabinetDO extends BaseDO {
     /**
      * 签名时间
      */
-    private LocalDateTime signatureTime;
+    private Date signatureTime;
     /**
      * 是否提交(0-否 1-是)
      */
     private String submit;
 
+    @Schema(description = "检查状态(0代表未开始,1代表已完成 2.进行中)")
+    private String status;
 
 }

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/ExDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.exUpdate;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class ExDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "钥匙状态")
+    private List<IsKeyExDTO> keyExDTOList;
+
+    @Schema(description = "挂锁状态")
+    private List<IsLockExDTO> lockExDTOList;
+
+    @Schema(description = "工卡状态")
+    private List<IsJobCardExDTO> jobCardExDTOList;
+
+    @Schema(description = "锁控机柜仓位")
+    private List<IsLockCabinetSlotsExDTO> slotsExDTOList;
+
+}

+ 30 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsJobCardExDTO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.exUpdate;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 工作卡对象 is_job_card
+ *
+ * @author cgj
+ * @date 2024-11-12
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class IsJobCardExDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    @Schema(description = "工作卡NFC")
+    private String cardNfc;
+
+    @Schema(description = "异常状态(0-异常 1-正常)")
+    private String exStatus;
+
+    @Schema(description = "异常备注")
+    private String exRemark;
+
+}

+ 29 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsKeyExDTO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.exUpdate;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 钥匙对象 is_key
+ *
+ * @author cgj
+ * @date 2024-11-19
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class IsKeyExDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "钥匙NFC")
+    private String keyNfc;
+
+    @Schema(description = "异常状态(0-异常 1-正常)")
+    private String exStatus;
+
+    @Schema(description = "异常备注")
+    private String exRemark;
+
+}

+ 31 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockCabinetSlotsExDTO.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.exUpdate;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 锁控机柜-仓位对象 is_lock_cabinet_slots
+ *
+ * @author cgj
+ * @date 2025-05-14
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class IsLockCabinetSlotsExDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "行")
+    private String row;
+
+    @Schema(description = "列")
+    private String col;
+
+    @Schema(description = "状态(0-可用 1-不可用(异常))")
+    private String status;
+
+    @Schema(description = "备注")
+    private String remark;
+
+}

+ 29 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockExDTO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.exUpdate;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 挂锁对象 is_lock
+ *
+ * @author cgj
+ * @date 2024-11-19
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class IsLockExDTO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "异常状态(0-异常 1-正常)")
+    private String exStatus;
+
+    @Schema(description = "异常备注")
+    private String exRemark;
+
+}

+ 26 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/CoincidePointToUnLockDTO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketPointsRespVO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Set;
+
+
+/**
+ * 作业票对象 is_job_ticket
+ *
+ * @author cgj
+ * @date 2024-10-18
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class CoincidePointToUnLockDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "解锁时禁止解除的点位")
+    private Set<JobTicketPointsRespVO> noUnlockTicketPointsVOSet;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LPBParamDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LPBParamDTO {
+
+    @Schema(description = "传参数据")
+    private List<LockPointBatchDTO> list;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LTParamDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LTParamDTO {
+
+    @Schema(description = "传参数据")
+    private List<TakeLocksetDTO> list;
+
+}

+ 38 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanMaterialDTO.java

@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资对象 is_materials
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class LoanMaterialDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "物资ID")
+    private Long materialsId;
+
+    @Schema(description = "物资rfid")
+    private String materialsRfid;
+
+    @Schema(description = "状态(0-借出 1-柜中)")
+    private String loanState;
+
+    @Schema(description = "领取人ID")
+    private Long loanUserId;
+
+    @Schema(description = "归还人ID")
+    private Long restitutionUserId;
+
+    @Schema(description = "归还柜ID")
+    private Long restitutionToId;
+
+    @Schema(description = "归还柜code")
+    private String restitutionToCabinetCode;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanParamDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LoanParamDTO {
+
+    @Schema(description = "传参数据")
+    private List<LoanMaterialDTO> list;
+
+}

+ 33 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointBatchDTO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LockPointBatchDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "隔离点nfc")
+    private String pointNfc;
+
+    @Schema(description = "keyNfc")
+    private String keyNfc;
+
+    @Schema(description = "任务目标:0—挂锁;1—解锁")
+    private Integer target;
+
+    @Schema(description = "任务当前状态:0—挂锁;1—解锁;2-无操作")
+    private Integer status;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LockPointDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "隔离点nfc")
+    private String pointNfc;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LocksetPointDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class LocksetPointDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "辅件NFC")
+    private String locksetNfc;
+
+    @Schema(description = "隔离点nfc")
+    private String pointNfc;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ParamDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class ParamDTO {
+
+    @Schema(description = "传参数据")
+    private List<TakeTicketLockDTO> list;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnKeyDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 硬件对象 is_hardware
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class ReturnKeyDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "钥匙NFC")
+    private String keyNfc;
+
+    @Schema(description = "序列号-取出硬件ID")
+    private String serialNumber;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnLocksetDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class ReturnLocksetDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String locksetNfc;
+
+    @Schema(description = "归还硬件的序列号")
+    private String serialNumber;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnTicketLockDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class ReturnTicketLockDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "归还硬件的序列号")
+    private String serialNumber;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeLocksetDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class TakeLocksetDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "锁具NFC")
+    private String locksetNfc;
+
+    @Schema(description = "序列号-取出硬件ID")
+    private String serialNumber;
+
+    @Schema(description = "对接时不需要传入,给了NFC就行")
+    private Long locksetId;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeOutKeyDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 硬件对象 is_hardware
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class TakeOutKeyDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "钥匙NFC")
+    private String keyNfc;
+
+    @Schema(description = "序列号-取出硬件ID")
+    private String serialNumber;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeTicketLockDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class TakeTicketLockDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "取出硬件的序列号")
+    private String serialNumber;
+
+    @Schema(description = "对接时不需要传入,给了NFC就行")
+    private Long lockId;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateColockerStatusDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class UpdateColockerStatusDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "工作卡NFC")
+    private String cardNfc;
+
+    @Schema(description = "作业状态(4 共锁,5 解锁)")
+    private String jobStatus;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateKeyStatusDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 硬件对象 is_hardware
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class UpdateKeyStatusDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "钥匙NFC")
+    private String keyNfc;
+
+    @Schema(description = "序列号-取出硬件ID(和归还序列号不可同时有值)")
+    private String fromSerialNumber;
+
+    @Schema(description = "序列号-归还硬件ID")
+    private Long toSerialNumber;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateSwitchParam.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class UpdateSwitchParam {
+
+    @Schema(description = "批量更新点位开关状态数据")
+    private List<UpdateSwitchStatusDTO> list;
+
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateTicketStatusDTO.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class UpdateTicketStatusDTO {
+
+    @Schema(description = "作业票ID")
+    private Long ticketId;
+
+    @Schema(description = "挂锁NFC")
+    private String lockNfc;
+
+    @Schema(description = "锁具状态(0-待取出 1-未上锁 2-已上锁 3-已解锁 4-已归还)")
+    private String lockStatus;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/AddLoanDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资借出对象 is_materials_loan
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class AddLoanDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "物资ID")
+    private Long materialsId;
+
+    @Schema(description = "materialsRfid")
+    private String materialsRfid;
+
+    @Schema(description = "领取人ID")
+    private Long loanUserId;
+
+}

+ 27 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/AutoChangeDTO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 手动更换
+ *
+ * @author cgj
+ * @date 2024-10-18
+ */
+@Data
+public class AutoChangeDTO
+{
+    @Schema(description = "物资柜CODE")
+    private String cabinetCode;
+
+    @Schema(description = "此次需要绑定的物资数据")
+    private List<String> bindingMaterialRfidList;
+
+    @Schema(description = "此次需要解绑的物资数据")
+    private List<String> unbindMaterialRfidList;
+
+
+}

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CabinetRfidListDTO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class CabinetRfidListDTO {
+
+    @Schema(description = "cabinetCode")
+    private String cabinetCode;
+
+    @Schema(description = "RFID列表")
+    private List<String> list;
+
+}

+ 22 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CheckParamDTO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscheckrecord.MaterialsCheckRecordDO;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 物资检查记录对象 is_materials_check_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class CheckParamDTO
+{
+
+    @Schema(description = "提交的物资检查清单")
+    private List<MaterialsCheckRecordDO> list;
+
+}

+ 37 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/CheckRecordDTO.java

@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 物资检查记录对象 is_materials_check_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class CheckRecordDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "计划id")
+    private Long planId;
+
+    @Schema(description = "物资柜id")
+    private Long cabinetId;
+
+    @Schema(description = "物资id")
+    private Long materialsId;
+
+    @Schema(description = "检查记录状态(0-正常 1-异常)")
+    private String status;
+
+    @Schema(description = "异常原因")
+    private String reason;
+
+    @Schema(description = "措施")
+    private String measure;
+
+}

+ 22 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/OpenTimeoutDTO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ *
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class OpenTimeoutDTO
+{
+
+    @Schema(description = "物资柜柜ID")
+    private Long loanFromId;
+
+    @Schema(description = "物资柜柜code")
+    private String loanFromCode;
+
+}

+ 26 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RecRetMaterialDTO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资对象 is_materials
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class RecRetMaterialDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "物资rfid")
+    private String materialsRfid;
+
+    @Schema(description = "状态(0-借出 1-柜中)")
+    private String loanState;
+
+    @Schema(description = "归还柜code")
+    private String restitutionToCabinetCode;
+
+}

+ 22 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RecRetParamDTO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 物资对象 is_materials
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class RecRetParamDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "操作的物资列表")
+    private List<RecRetMaterialDTO> list;
+
+}

+ 49 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialDTO.java

@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 物资更换记录对象 is_materials_change_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class ReplaceMaterialDTO
+{
+    @Schema(description = "旧物资id")
+    private Long oldMaterialsId;
+
+    @Schema(description = "物资名称")
+    private String materialsName;
+
+    @Schema(description = "物资类型ID")
+    private Long materialsTypeId;
+
+    @Schema(description = "物资规格id")
+    private String propertiesValueId;
+
+    @Schema(description = "物资规格")
+    private String propertiesValue;
+
+    @Schema(description = "物资规格种类id")
+    private String propertiesPropertyId;
+
+    @Schema(description = "物资规格种类")
+    private String propertiesProperty;
+
+    @Schema(description = "物资RFID")
+    private String materialsRfid;
+
+    @Schema(description = "有效期")
+    @JsonFormat(timezone="GMT+8", pattern = "yyyy-MM-dd")
+    private Date expirationDate;
+
+    @Schema(description = "措施")
+    private String measure;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialParamDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 物资更换记录对象 is_materials_change_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class ReplaceMaterialParamDTO
+{
+    @Schema(description = "list")
+    private List<ReplaceMaterialDTO> list;
+
+}

+ 28 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReplaceMaterialsDTO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 隔离点对象 is_isolation_point
+ *
+ * @author cgj
+ * @date 2024-10-18
+ */
+@Data
+public class ReplaceMaterialsDTO
+{
+
+    @Schema(description = "物资柜code")
+    private String cabinetCode;
+
+    @Schema(description = "绑定的物资数据")
+    private List<String> bindingMaterialRfidList;
+
+    @Schema(description = "解绑的物资数据")
+    private List<String> unbindMaterialRfidList;
+
+
+}

+ 26 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/ReturnLoanDTO.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资借出对象 is_materials_loan
+ *
+ * @author cgj
+ * @date 2024-11-08
+ */
+@Data
+public class ReturnLoanDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "物资ID")
+    private Long materialsId;
+
+    @Schema(description = "归还人ID")
+    private Long restitutionUserId;
+
+    @Schema(description = "归还柜ID")
+    private Long restitutionToId;
+
+}

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/RfidListDTO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * UpdateTicketLockDTO
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Data
+public class RfidListDTO {
+
+    @Schema(description = "RFID列表")
+    private List<String> list;
+
+}

+ 25 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/SignDTO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 物资检查记录对象 is_materials_check_record
+ *
+ * @author cgj
+ * @date 2025-01-14
+ */
+@Data
+public class SignDTO
+{
+
+    @Schema(description = "计划id")
+    private Long planId;
+
+    @Schema(description = "物资柜code")
+    private String cabinetCode;
+
+    @Schema(description = "签名图片")
+    private String signatureImg;
+
+}

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/StartCheckPlanDTO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author cgj
+ * @date 2025-01-14
+ */
+@EqualsAndHashCode(callSuper = false)
+@Data
+public class StartCheckPlanDTO
+{
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "计划id")
+    private Long planId;
+
+    @Schema(description = "物资柜code")
+    private String cabinetCode;
+
+}

+ 21 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareMaterialApi/SubmitPlanDTO.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 手动更换
+ *
+ * @author cgj
+ * @date 2024-10-18
+ */
+@Data
+public class SubmitPlanDTO
+{
+    @Schema(description = "物资柜CODE")
+    private String cabinetCode;
+
+    @Schema(description = "检查计划id")
+    private Long planId;
+
+}

+ 2 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/isolationpoint/IsolationPointMapper.java

@@ -48,4 +48,6 @@ public interface IsolationPointMapper extends BaseMapperX<IsolationPointDO> {
 
     Page<IsolationPointRespVO> getIsolationPointPage(Page<IsolationPointDO> page, @Param(value = "vo") IsolationPointPageReqVO vo);
 
+    IsolationPointRespVO getOneByNfc(@Param(value = "nfc") String nfc);
+
 }

+ 3 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketKeyMapper.java

@@ -4,6 +4,7 @@ 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.iscs.controller.admin.jobticket.vo.JobTicketKeyPageReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketKeyRespVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketKeyDO;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Mapper;
@@ -45,4 +46,6 @@ public interface JobTicketKeyMapper extends BaseMapperX<JobTicketKeyDO> {
     })
     Boolean physicalDeleteByIds(@Param(value = "ids") List<Long> ids);
 
+    List<JobTicketKeyRespVO> getListByTicketId(@Param(value = "ticketId") Long ticketId);
+
 }

+ 7 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketLockMapper.java

@@ -4,6 +4,7 @@ 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.iscs.controller.admin.jobticket.vo.JobTicketLockPageReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketLockRespVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketLockDO;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Mapper;
@@ -44,5 +45,11 @@ public interface JobTicketLockMapper extends BaseMapperX<JobTicketLockDO> {
     })
     Boolean physicalDeleteByIds(@Param(value = "ids") List<Long> ids);
 
+    List<JobTicketLockRespVO> getTicketLockByTicketId(@Param(value = "ticketId") Long ticketId);
+
+    JobTicketLockDO getLockJobByBfc(@Param(value = "nfc") String nfc, @Param(value = "ticketId") Long ticketId);
+
+    List<JobTicketLockDO> getLockJob(@Param(value = "lockId") Long lockId);
+
 
 }

+ 16 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketMapper.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.iscs.dal.mysql.jobticket;
 
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketDetailVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketPageReqVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketRespVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.MonitorTicketPageVO;
@@ -38,5 +39,20 @@ public interface JobTicketMapper extends BaseMapperX<JobTicketDO> {
 
     JobTicketRespVO getJobTicket(@Param(value = "id") Long id);
 
+    /**
+     * 上锁取钥匙后未归还的重复点位作业票干扰
+     * @param pointIds
+     * @return
+     */
+    List<JobTicketDetailVO> selectConflictTicket1(@Param(value = "pointIds") List<Long> pointIds, @Param(value = "ticketId") Long ticketId);
+
+    /**
+     * 上锁取钥匙后已归还
+     * @param pointIds
+     * @return
+     */
+    List<JobTicketDetailVO> selectConflictTicket2(@Param(value = "pointIds") List<Long> pointIds, @Param(value = "ticketId") Long ticketId);
+
+
 
 }

+ 8 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketPointsMapper.java

@@ -54,4 +54,12 @@ public interface JobTicketPointsMapper extends BaseMapperX<JobTicketPointsDO> {
     List<JobTicketPointsRespVO> listByTicketId(@Param(value = "ticketId") Long ticketId);
 
 
+    List<JobTicketPointsDO> getFinishConflictJob(@Param(value = "pointId") Long pointId, @Param(value = "lockId") Long lockId);
+
+    List<JobTicketPointsDO> getNotFinishConflictJob(@Param(value = "pointId") Long pointId, @Param(value = "lockId") Long lockId);
+
+    JobTicketPointsDO getLockingData(@Param(value = "pointId") Long pointId);
+
+    List<JobTicketPointsDO> getVirtualLockConflictPoint(@Param(value = "pointId") Long pointId, @Param(value = "lockId") Long lockId, @Param(value = "ticketId") Long ticketId);
+
 }

+ 2 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketUserMapper.java

@@ -46,5 +46,7 @@ public interface JobTicketUserMapper extends BaseMapperX<JobTicketUserDO> {
 
     List<JobTicketUserRespVO> listByTicketId(@Param(value = "ticketId") Long ticketId);
 
+    List<JobTicketUserDO> getMyJob(@Param(value = "userId") Long userId);
+
 
 }

+ 5 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materials/MaterialsMapper.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iscs.dal.mysql.materials;
 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.iscs.controller.admin.hardwareapi.hardwareMaterialApi.CheckMaterialsDateVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsPageReqVO;
 import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
@@ -47,5 +48,9 @@ public interface MaterialsMapper extends BaseMapperX<MaterialsDO> {
 
     List<MaterialsRespVO> getExMaterials(@Param(value = "materialsIds") List<Long> materialsIds);
 
+    List<CheckMaterialsDateVO> getCheckMaterialsByCabinetId(@Param(value = "cabinetId") Long cabinetId);
+
+    List<MaterialsDO> getMaterialListByRfid(@Param(value = "rfidList") List<String> rfidList);
+
 
 }

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialscheckrecord/MaterialsCheckRecordMapper.java

@@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 物资检查记录 Mapper
  *
@@ -36,4 +38,6 @@ public interface MaterialsCheckRecordMapper extends BaseMapperX<MaterialsCheckRe
 
     Page<MaterialsCheckRecordRespVO> getMaterialsCheckRecordPage(Page<MaterialsCheckRecordDO> page, @Param(value = "vo") MaterialsCheckRecordPageReqVO vo);
 
+    List<MaterialsCheckRecordDO> getCheckMaterialsByCabinetCode(@Param(value = "planId") Long planId, @Param(value = "cabinetId") Long cabinetId);
+
 }

+ 5 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialsloan/MaterialsLoanMapper.java

@@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * 物资借出 Mapper
  *
@@ -38,5 +40,8 @@ public interface MaterialsLoanMapper extends BaseMapperX<MaterialsLoanDO> {
 
     Page<MaterialsLoanRespVO> getMaterialsLoanPage(Page<MaterialsLoanDO> page, @Param(value = "vo") MaterialsLoanPageReqVO vo);
 
+    List<Long> getLastLoanRecord(@Param(value = "ids") List<Long> ids);
+
+
 
 }

+ 12 - 4
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/materialstype/MaterialsTypeMapper.java

@@ -1,13 +1,12 @@
 package cn.iocoder.yudao.module.iscs.dal.mysql.materialstype;
 
-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.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.MaterialsTypePageReqVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.MaterialsTypeRespVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.materialstype.MaterialsTypeDO;
 import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.module.iscs.controller.admin.materialstype.vo.*;
 
 /**
  * 物资类型 Mapper
@@ -38,4 +37,13 @@ public interface MaterialsTypeMapper extends BaseMapperX<MaterialsTypeDO> {
                 .orderByDesc(MaterialsTypeDO::getId));
     }
 
+    /**
+     * 查询物资类型
+     *
+     * @param materialsTypeId 物资类型主键
+     * @return 物资类型
+     */
+    MaterialsTypeRespVO getMaterialsType(Long materialsTypeId);
+
+
 }

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/KeyStatusEnum.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.enums;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum KeyStatusEnum {
+    /**
+     * 上锁人包含0-5,共锁人包含0、4、5
+     */
+    WAIT_TAKE(0, "待取出"),
+    TAKED(1, "已取出"),
+    RETURNED(2, "已归还");
+
+    /**
+     * 状态编号
+     */
+    public final Integer status;
+
+    /**
+     * 描述
+     */
+    public final String desc;
+}

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LockStatusEnum.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.enums;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum LockStatusEnum {
+    WAIT_TAKE("0", "待取出"),
+    NOT_LOCK("1", "未上锁"),
+    LOCKED("2", "已上锁"),
+    WAIT_REMOVE_LOCK("3", "待解锁"),
+    REMOVED_LOCK("4", "已解锁"),
+    RETURN_LOCK("5", "已归还");
+
+    /**
+     * 状态编号
+     */
+    public final String status;
+
+    /**
+     * 描述
+     */
+    public final String desc;
+}

+ 24 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LocksetStatusEnum.java

@@ -0,0 +1,24 @@
+package cn.iocoder.yudao.module.iscs.enums;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum LocksetStatusEnum {
+    WAIT_TAKE("0", "待取出"),
+    TAKED("1", "已取出"),
+    WAIT_USE("2", "待使用"),
+    USING("3", "使用中"),
+    WAIT_REMOVED("4", "待拆除"),
+    WAIT_RETURN("5", "待归还"),
+    RETURNED("6", "已归还");
+
+    /**
+     * 状态编号
+     */
+    public final String status;
+
+    /**
+     * 描述
+     */
+    public final String desc;
+}

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/PointStatusEnum.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.enums;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum PointStatusEnum {
+    /**
+     * 上锁人包含0-5,共锁人包含0、4、5
+     */
+    UNLOCK(0, "未上锁"),
+    LOCKED(1, "已上锁"),
+    REMOVE_LOCK(2, "已解锁");
+
+    /**
+     * 状态编号
+     */
+    public final Integer status;
+
+    /**
+     * 描述
+     */
+    public final String desc;
+}

+ 23 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/TicketStatusEnum.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.iscs.enums;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum TicketStatusEnum {
+    NOT_STARTED("0", "未开始"),
+    READY_TO_LOCK("1", "待上锁"),
+    PROCESSING("2", "进行中"),
+    READY_TO_UNLOCK("3", "待解锁"),
+    UNLOCKED("4", "已解锁"),
+    FINISHED("5", "已结束");
+
+    /**
+     * 状态编号
+     */
+    public final String status;
+
+    /**
+     * 描述
+     */
+    public final String desc;
+}

+ 145 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiService.java

@@ -0,0 +1,145 @@
+package cn.iocoder.yudao.module.iscs.service.hardwareapi;
+
+
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketRespVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketSaveReqVO;
+import cn.iocoder.yudao.module.iscs.dal.dto.exUpdate.ExDTO;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi.*;
+
+import java.util.List;
+
+/**
+ * 硬件调用接口
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+public interface HardwareApiService {
+
+    /**
+     * 取出钥匙
+     * @param dto
+     * @return
+     */
+    Boolean updateTakeOutKey(TakeOutKeyDTO dto);
+
+    /**
+     * 归还钥匙
+     * @param dto
+     * @return
+     */
+    Boolean updateReturnKey(ReturnKeyDTO dto);
+
+    /**
+     * 取出挂锁时更新数据
+     * @param list
+     * @return
+     */
+    Boolean updateTicketLockTake(List<TakeTicketLockDTO> list);
+
+    /**
+     * 归还挂锁时更新数据
+     * @param dto
+     * @return
+     */
+    Boolean updateTicketLockReturn(ReturnTicketLockDTO dto);
+
+    /**
+     * 批量更新作业票下隔离点的上锁状况
+     * @return
+     */
+    Boolean updateLockPointBatch(List<LockPointBatchDTO> list);
+
+
+
+
+
+    /**
+     * 取出辅件时更新数据
+     * @param list
+     * @return
+     */
+    Boolean updateLocksetTake(List<TakeLocksetDTO> list);
+
+    /**
+     * 辅件绑定隔离点
+     * @param dto
+     * @return
+     */
+    Boolean updateLocksetPoint(LocksetPointDTO dto);
+
+    /**
+     * 辅件归还物资柜
+     * @param dto
+     * @return
+     */
+    Boolean updateLocksetReturn(ReturnLocksetDTO dto);
+
+
+    /**
+     * 获取作业票和关联数据
+     * @param ticketId
+     * @return
+     */
+    JobTicketRespVO selectTicketDetailById(Long ticketId);
+
+    /**
+     * 共锁人上锁/解锁
+     * @param dto
+     * @return
+     */
+    Boolean updateColockerStatus(UpdateColockerStatusDTO dto);
+
+    /**
+     * 批量更新开关状态
+     * @param dto
+     * @return
+     */
+    Boolean updateSwitchList(UpdateSwitchParam dto);
+
+    /**
+     * 上锁取钥匙前检查
+     * @param ticketId
+     * @return
+     */
+    Boolean checkBeforeToLock(Long ticketId);
+
+    /**
+     * 解锁取钥匙前检查
+     * @param ticketId
+     * @return
+     */
+    Boolean checkBeforeToUnlock(Long ticketId);
+
+    /**
+     * 重合点位数据解锁
+     * @param dto
+     * @return
+     */
+    Boolean updateCoincideToUnLock(CoincidePointToUnLockDTO dto);
+
+    /**
+     * 批量更新硬件状态
+     * @param dto
+     * @return
+     */
+    Boolean updateHardwareEsStatus(ExDTO dto);
+
+    /**
+     * 判断当前登陆人员是否有需要去上所或者去解锁的需求
+     * @return false 不需要 true 需要
+     */
+    Boolean getMySelfState();
+
+    /**
+     * 通过nfc查询当前锁能不能锁
+     * @param nfc
+     * @return
+     */
+    Integer getLockStateByNfc(String nfc, Long ticketId);
+
+    Boolean updateJobToFinish(JobTicketSaveReqVO isJobTicket);
+
+    Boolean updateJobToCancel(JobTicketSaveReqVO isJobTicket);
+
+}

+ 1182 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiServiceImpl.java

@@ -0,0 +1,1182 @@
+package cn.iocoder.yudao.module.iscs.service.hardwareapi;
+
+import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.redis.RedisCacheUtil;
+import cn.iocoder.yudao.module.iscs.controller.admin.isolationpoint.vo.IsolationPointRespVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.isolationpoint.vo.PointDetailVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.*;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.hardware.HardwareDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.isolationpoint.IsolationPointDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.jobcard.JobCardDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.*;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.key.KeyDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.lock.LockDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.lockcabinetslots.LockCabinetSlotsDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.lockset.LocksetDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.rfidtoken.RfidTokenDO;
+import cn.iocoder.yudao.module.iscs.dal.dto.exUpdate.*;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareApi.*;
+import cn.iocoder.yudao.module.iscs.enums.*;
+import cn.iocoder.yudao.module.iscs.service.hardware.HardwareService;
+import cn.iocoder.yudao.module.iscs.service.isolationpoint.IsolationPointService;
+import cn.iocoder.yudao.module.iscs.service.jobcard.JobCardService;
+import cn.iocoder.yudao.module.iscs.service.jobticket.*;
+import cn.iocoder.yudao.module.iscs.service.key.KeyService;
+import cn.iocoder.yudao.module.iscs.service.lock.LockService;
+import cn.iocoder.yudao.module.iscs.service.lockcabinetslots.LockCabinetSlotsService;
+import cn.iocoder.yudao.module.iscs.service.lockset.LocksetService;
+import cn.iocoder.yudao.module.iscs.service.rfidtoken.RfidTokenService;
+import cn.iocoder.yudao.module.system.service.attribute.AttributeService;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
+import static cn.iocoder.yudao.module.iscs.enums.TicketStatusEnum.FINISHED;
+import static cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants.ISCS_ATTR;
+
+
+/**
+ * 硬件Service业务层处理
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Slf4j
+@Service
+public class HardwareApiServiceImpl implements HardwareApiService {
+    @Autowired
+    private JobTicketService isJobTicketService;
+    @Autowired
+    private KeyService isKeyService;
+    @Autowired
+    private JobTicketKeyService iIsJobTicketKeyService;
+    @Autowired
+    private LockService iIsLockService;
+    @Autowired
+    private JobTicketLockService iIsJobTicketLockService;
+    @Autowired
+    private IsolationPointService iIsIsolationPointService;
+    @Autowired
+    private LocksetService iIsLocksetService;
+    @Autowired
+    private JobTicketLocksetService iIsJobTicketLocksetService;
+    @Autowired
+    private HardwareService isHardwareService;
+    @Autowired
+    private JobTicketPointsService iIsJobTicketPointsService;
+    @Autowired
+    private JobTicketUserService iIsJobTicketUserService;
+    @Autowired
+    private JobCardService iIsJobCardService;
+    @Autowired
+    private AttributeService isSystemAttributeService;
+    @Autowired
+    private RfidTokenService iIsRfidTokenService;
+    @Autowired
+    private LockCabinetSlotsService iIsLockCabinetSlotsService;
+    @Autowired
+    private TicketOperLogService isTicketOperLogService;
+    @Autowired
+    private JobTicketStepService iIsJobTicketStepService;
+    @Autowired
+    private RedisCacheUtil redisCacheUtil;
+
+
+    /**
+     * 取出钥匙
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public Boolean updateTakeOutKey(TakeOutKeyDTO dto) {
+        Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+        Assert.notBlank(dto.getKeyNfc(), "请告诉我钥匙的NFC!");
+        Assert.notBlank(dto.getSerialNumber(), "请告知归还到哪里!");
+        // 1.获取作业票数据
+        JobTicketDO jobTicket = isJobTicketService.getById(dto.getTicketId());
+        Assert.notNull(jobTicket, "作业票数据丢失啦!");
+        // 1.1获取上锁时取出的锁的信息
+        KeyDO startKey = isKeyService.getOne(Wrappers.<KeyDO>lambdaQuery().eq(KeyDO::getKeyNfc, dto.getKeyNfc()));
+        Assert.notNull(startKey, "钥匙数据丢失啦!");
+        // 1.2通过序列号查询柜子信息
+        HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery()
+                .eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+        Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+        // 1.3初始化时间参数
+        Date date = new Date();
+        // 1.4获取上锁时的数据
+        JobTicketKeyDO jobTicketKey = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                .eq(JobTicketKeyDO::getTicketId, dto.getTicketId())
+                .ne(JobTicketKeyDO::getKeyStatus, "2")
+                .eq(JobTicketKeyDO::getTicketType, "0")
+                .last("limit 1"));
+        // 2.根据作业票判断到了哪一阶段了,如果未归还的上锁数据不为空并且上锁数据中这两个数据有空的,那肯定是上锁阶段还没有完成
+        if (jobTicketKey!=null && (jobTicketKey.getCollectTime() == null || jobTicketKey.getGiveBackTime() == null)) {
+            // 3.上锁阶段取钥匙
+            iIsJobTicketKeyService.update(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getId, jobTicketKey.getId())
+                    .set(JobTicketKeyDO::getKeyId, startKey.getId())
+                    .set(JobTicketKeyDO::getFromHardwareId, isHardware.getId())
+                    .set(JobTicketKeyDO::getCollectTime, date)
+                    .set(JobTicketKeyDO::getKeyStatus, KeyStatusEnum.TAKED.status));
+            // 上锁阶段需要变更状态
+            // TODO
+            /*JobTicketUpdateProgressReqVO reqVO = new JobTicketUpdateProgressReqVO();
+            reqVO.userId = SecurityUtils.getUserId();
+            reqVO.ticketId = dto.getTicketId();
+            reqVO.equipStatus = 3;
+            isJobTicketService.updateTicketProgress(reqVO);*/
+        } else {
+            JobTicketKeyDO jobTicketKey1 = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getTicketId, dto.getTicketId())
+                    .ne(JobTicketKeyDO::getKeyStatus, "2")
+                    .eq(JobTicketKeyDO::getTicketType, "1")
+                    .last("limit 1"));
+            // 3.1解锁阶段取钥匙
+            iIsJobTicketKeyService.update(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getId, jobTicketKey1.getId())
+                    .set(JobTicketKeyDO::getKeyId, startKey.getId())
+                    .set(JobTicketKeyDO::getFromHardwareId, isHardware.getId())
+                    .set(JobTicketKeyDO::getCollectTime, date)
+                    .set(JobTicketKeyDO::getKeyStatus, KeyStatusEnum.TAKED.status));
+        }
+        return true;
+    }
+
+    /**
+     * 上锁阶段,取钥匙时更新状态
+     *
+     * @param ticketId
+     */
+    private void updateFirstProgress(Long ticketId) {
+        // 判断作业票的整体状态,防止状态回退异常
+        JobTicketUserDO jobTicketUser = iIsJobTicketUserService.getOne(Wrappers.<JobTicketUserDO>lambdaQuery()
+                .eq(JobTicketUserDO::getTicketId, ticketId)
+                .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue()));
+        Assert.isFalse(Integer.parseInt(jobTicketUser.getJobStatus()) > JobStatusEnum.ACQUIRE_KEY.status, "作业票已完成设备拿取,无法操作!");
+        JobTicketDO isJobTicket = isJobTicketService.getOne(Wrappers.<JobTicketDO>lambdaQuery()
+                .eq(JobTicketDO::getId, ticketId));
+        Assert.isFalse(Integer.parseInt(isJobTicket.getTicketStatus()) > Integer.parseInt(TicketStatusEnum.READY_TO_LOCK.status), "作业票已完成设备拿取,无法进行操作!");
+        // 上锁阶段取钥匙,更新is_job_ticket_user和is_job_ticket
+        // 1.新更人员状态
+        iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                .eq(JobTicketUserDO::getTicketId, ticketId)
+                .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue())
+                .set(JobTicketUserDO::getJobStatus, JobStatusEnum.ACQUIRE_KEY.status));
+        // 2.获取设备取出状态
+        boolean b = checkTakeStatus(ticketId);
+        // 3.根据设备去除状态更新is_job_ticket
+        if (b) {
+            isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate()
+                    .eq(JobTicketDO::getId, ticketId)
+                    .set(JobTicketDO::getTicketStatus, TicketStatusEnum.READY_TO_LOCK.status));
+        }
+    }
+
+    /**
+     * 检查上锁前的设备是否全部取出完毕
+     *
+     * @param ticketId
+     * @return
+     */
+    private boolean checkTakeStatus(Long ticketId) {
+        // 1.检查钥匙是否取出
+        int keyCount = (int) iIsJobTicketKeyService.count(Wrappers.<JobTicketKeyDO>lambdaQuery()
+                .eq(JobTicketKeyDO::getTicketId, ticketId)
+                .eq(JobTicketKeyDO::getKeyStatus, KeyStatusEnum.WAIT_TAKE.status)
+                .eq(JobTicketKeyDO::getTicketType, 0));
+        // 2.检查挂锁是否全部取出
+        int lockCount = (int) iIsJobTicketLockService.count(Wrappers.<JobTicketLockDO>lambdaQuery()
+                .eq(JobTicketLockDO::getTicketId, ticketId)
+                .eq(JobTicketLockDO::getLockStatus, LockStatusEnum.WAIT_TAKE.status));
+        // 3.检查辅件是否全部取出
+        int locksetCount = (int) iIsJobTicketLocksetService.count(Wrappers.<JobTicketLocksetDO>lambdaQuery()
+                .eq(JobTicketLocksetDO::getJobTicketId, ticketId)
+                .eq(JobTicketLocksetDO::getLocksetStatus, LocksetStatusEnum.WAIT_TAKE.status));
+        if (keyCount == 0 && lockCount == 0 && locksetCount == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 归还钥匙
+     *
+     * @param dto
+     * @return
+     */
+    @Transactional
+    @Override
+    public Boolean updateReturnKey(ReturnKeyDTO dto) {
+        Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+        Assert.notBlank(dto.getKeyNfc(), "请告诉我钥匙的NFC!");
+        Assert.notBlank(dto.getSerialNumber(), "请告知归还到哪里!");
+        // 1.获取作业票数据
+        JobTicketDO jobTicket = isJobTicketService.getById(dto.getTicketId());
+        Assert.notNull(jobTicket, "作业票数据丢失啦!");
+        // 1.1获取上锁时取出的锁的信息
+        KeyDO startKey = isKeyService.getOne(Wrappers.<KeyDO>lambdaQuery().eq(KeyDO::getKeyNfc, dto.getKeyNfc()));
+        Assert.notNull(startKey, "钥匙数据丢失啦!");
+        // 1.2通过序列号查询柜子信息
+        HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery()
+                .eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+        Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+        // 1.3初始化时间参数
+        Date date = new Date();
+        // 1.4获取上锁时的数据
+        JobTicketKeyDO jobTicketKey = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                .eq(JobTicketKeyDO::getTicketId, dto.getTicketId())
+                .eq(JobTicketKeyDO::getKeyId, startKey.getId())
+                .ne(JobTicketKeyDO::getKeyStatus, "2")
+                .eq(JobTicketKeyDO::getTicketType, "0"));
+        // 2.根据作业票判断到了哪一阶段了,如果未归还的上锁数据不为空并且上锁数据中这两个数据有空的,那肯定是上锁阶段还没有完成
+        if (jobTicketKey!=null && (jobTicketKey.getCollectTime() == null || jobTicketKey.getGiveBackTime() == null)) {
+            // 3.1上锁阶段还钥匙
+            iIsJobTicketKeyService.update(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getId, jobTicketKey.getId())
+                    .set(JobTicketKeyDO::getKeyId, startKey.getId())
+                    .set(JobTicketKeyDO::getToHardwareId, isHardware.getId())
+                    .set(JobTicketKeyDO::getGiveBackTime, date)
+                    .set(JobTicketKeyDO::getKeyStatus, KeyStatusEnum.RETURNED.status));
+            // 3.1.1还完钥匙判断点位是不是都上锁完成,如果都上锁完成,则更新作业进度
+            List<JobTicketPointsDO> pointsLock = iIsJobTicketPointsService.list(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                    .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                    .eq(JobTicketPointsDO::getPointStatus, "0"));
+            if (pointsLock.isEmpty()) {
+                isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate()
+                        .eq(JobTicketDO::getId, dto.getTicketId())
+                        .set(JobTicketDO::getTicketStatus, "3"));
+            } else {
+                // 3.1.2如果没上完,允许再次获取一个新钥匙去上锁,所以要在生成一个取钥匙的初始化数据
+                JobTicketKeyDO isJobTicketKey = new JobTicketKeyDO();
+                isJobTicketKey.setTicketId(dto.getTicketId());
+                isJobTicketKey.setKeyStatus("0");
+                isJobTicketKey.setTicketType(0);
+                iIsJobTicketKeyService.save(isJobTicketKey);
+            }
+        } else {
+            JobTicketKeyDO jobTicketKey1 = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getTicketId, dto.getTicketId())
+                    .eq(JobTicketKeyDO::getKeyId, startKey.getId())
+                    .ne(JobTicketKeyDO::getKeyStatus, "2")
+                    .eq(JobTicketKeyDO::getTicketType, "1"));
+            // 3.2解锁阶段还钥匙
+            iIsJobTicketKeyService.update(Wrappers.<JobTicketKeyDO>lambdaUpdate()
+                    .eq(JobTicketKeyDO::getId, jobTicketKey1.getId())
+                    .set(JobTicketKeyDO::getKeyId, startKey.getId())
+                    .set(JobTicketKeyDO::getToHardwareId, isHardware.getId())
+                    .set(JobTicketKeyDO::getGiveBackTime, date)
+                    .set(JobTicketKeyDO::getKeyStatus, KeyStatusEnum.RETURNED.status));
+            // 3.2.1还完钥匙判断点位是不是都解锁完成,如果都解锁完成,则更新作业进度
+            List<JobTicketPointsDO> pointsLock = iIsJobTicketPointsService.list(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                    .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                    .eq(JobTicketPointsDO::getPointStatus, "2"));
+            if (pointsLock.isEmpty()) {
+                isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate()
+                        .eq(JobTicketDO::getId, dto.getTicketId())
+                        .set(JobTicketDO::getTicketStatus, "4"));
+            } else {
+                // 3.1.2如果没解完,允许再次获取一个新钥匙去解锁,所以要在生成一个解锁时取钥匙的初始化数据
+                JobTicketKeyDO isJobTicketKey = new JobTicketKeyDO();
+                isJobTicketKey.setTicketId(dto.getTicketId());
+                isJobTicketKey.setKeyStatus("0");
+                isJobTicketKey.setTicketType(1);
+                iIsJobTicketKeyService.save(isJobTicketKey);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 取出挂锁时更新数据
+     *
+     * @param list
+     * @return
+     */
+    @Override
+    public synchronized Boolean updateTicketLockTake(List<TakeTicketLockDTO> list) {
+        Assert.isFalse(list.isEmpty(), "请取出至少一把挂锁!");
+        // 情况复杂,遍历处理吧
+        for (TakeTicketLockDTO dto : list) {
+            Assert.notBlank(dto.getLockNfc(), "挂锁nfc缺失!");
+            Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+            Assert.notBlank(dto.getSerialNumber(), "请告知归还到哪一个柜子!");
+            // 1.查询挂锁信息
+            LockDO lock = iIsLockService.getOne(Wrappers.<LockDO>lambdaQuery()
+                    .eq(LockDO::getLockNfc, dto.getLockNfc()));
+            Assert.notNull(lock, "该nfc无对应的挂锁信息!");
+            // 1.1检查这把锁是不是已经在该作业票中使用
+            List<JobTicketLockDO> jobTicketLockList = iIsJobTicketLockService.list(Wrappers.<JobTicketLockDO>lambdaQuery()
+                    .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                    .eq(JobTicketLockDO::getLockId, lock.getId()));
+            Assert.isFalse(!jobTicketLockList.isEmpty(), lock.getLockName() + "已被取出!");
+            // 1.2通过序列号查询柜子信息
+            HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery()
+                    .eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+            Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+            // 2.获取本次作业票产生的和挂锁关联的数据,按照从上到下的顺序,取一个可以使用的
+            JobTicketLockDO isJobTicketLock = iIsJobTicketLockService.getOne(Wrappers.<JobTicketLockDO>lambdaQuery()
+                    .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                    .isNull(JobTicketLockDO::getLockId)
+                    .orderByAsc(JobTicketLockDO::getId)
+                    .last("limit 1"));
+            Assert.notNull(isJobTicketLock, "无初始化数据来提供给该挂锁更新");
+            // 1.2开始补充该条数据
+            isJobTicketLock.setLockId(lock.getId());
+            isJobTicketLock.setFromHardwareId(isHardware.getId());
+            isJobTicketLock.setLockStatus(LockStatusEnum.NOT_LOCK.status);
+            iIsJobTicketLockService.updateById(isJobTicketLock);
+        }
+
+        List<JobTicketLockDO> lockList = iIsJobTicketLockService.list(Wrappers.<JobTicketLockDO>lambdaQuery()
+                .eq(JobTicketLockDO::getTicketId, list.get(0).getTicketId()));
+        // 已取锁数量
+        int takeCount = (int) lockList.stream().filter(data -> data.getLockId() != null).count();
+        int status = takeCount == lockList.size() ? 2 : 1;
+
+        // TODO
+        /*JobTicketUpdateProgressReqVO reqVO = new JobTicketUpdateProgressReqVO();
+        reqVO.ticketId = list.get(0).getTicketId();
+        reqVO.userId = SecurityUtils.getUserId();
+        reqVO.equipStatus = status;
+        isJobTicketService.updateTicketProgress(reqVO);*/
+
+
+        return true;
+    }
+
+    /**
+     * 归还挂锁时更新数据
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public Boolean updateTicketLockReturn(ReturnTicketLockDTO dto) {
+        // Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+        Assert.notBlank(dto.getLockNfc(), "挂锁nfc缺失!");
+        Assert.notBlank(dto.getSerialNumber(), "请告知归还到哪一个柜子!");
+        // 1.通过nfc查询挂锁信息
+        LockDO lock = iIsLockService.getOne(Wrappers.<LockDO>lambdaQuery()
+                .eq(LockDO::getLockNfc, dto.getLockNfc()));
+        Assert.notNull(lock, "该nfc无对应的挂锁信息!");
+        // 1.1通过序列号查询柜子信息
+        HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery().eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+        Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+        // 2.开始更新归还信息
+        if (dto.getTicketId() != null) {
+            // 2.1登陆后归还, 判断钥匙在哪个阶段,根据不同阶段更新不一样
+            Integer lockStateByNfc = getLockStateByNfc(dto.getLockNfc(), dto.getTicketId());
+            if (lockStateByNfc.equals(0) || lockStateByNfc.equals(2)) {
+                // 0-上锁未取钥匙(可锁-需更改还锁逻辑)
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketLockDO::getLockId, lock.getId())
+                        .set(JobTicketLockDO::getLockId, null)
+                        .set(JobTicketLockDO::getFromHardwareId, null)
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.WAIT_TAKE.status));
+            } else if (lockStateByNfc.equals(1)) {
+                // 1-上锁取了钥匙(不可锁)
+                return true;
+            } else {
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketLockDO::getLockId, lock.getId())
+                        .set(JobTicketLockDO::getToHardwareId, isHardware.getId())
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.RETURN_LOCK.status));
+            }
+        } else {
+            // 2.2不登陆状态下归还
+            // 查一下哪个作业票用了这个挂锁,而且还没有完成
+            List<JobTicketLockDO> jobTicketLockList = iIsJobTicketLockService.getLockJob(lock.getId());
+            if (jobTicketLockList.isEmpty()) {
+                log.error("当前挂锁未找到关联的作业票, nfc: {}, name : {}", dto.getLockNfc(), lock.getLockName());
+                return null;
+            } else if (jobTicketLockList.size() == 1) {
+                // 2.1登陆后归还, 判断钥匙在哪个阶段,根据不同阶段更新不一样
+                Integer lockStateByNfc = getLockStateByNfc(dto.getLockNfc(), jobTicketLockList.get(0).getTicketId());
+                if (lockStateByNfc.equals(0) || lockStateByNfc.equals(2)) {
+                    // 0-上锁未取钥匙(可锁-需更改还锁逻辑)
+                    iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                            .eq(JobTicketLockDO::getTicketId, jobTicketLockList.get(0).getTicketId())
+                            .eq(JobTicketLockDO::getLockId, lock.getId())
+                            .set(JobTicketLockDO::getLockId, null)
+                            .set(JobTicketLockDO::getFromHardwareId, null)
+                            .set(JobTicketLockDO::getLockStatus, LockStatusEnum.WAIT_TAKE.status));
+                } else if (lockStateByNfc.equals(1)) {
+                    // 1-上锁取了钥匙(不可锁)
+                    return true;
+                } else {
+                    // 说明找到的就是
+                    iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                            .eq(JobTicketLockDO::getLockId, lock.getId())
+                            .set(JobTicketLockDO::getToHardwareId, isHardware.getId())
+                            .set(JobTicketLockDO::getLockStatus, LockStatusEnum.RETURN_LOCK.status));
+                }
+            } else {
+                // 出现了多条对应
+                log.error("当前挂锁找到多条关联的作业票, nfc: {}, name : {}", dto.getLockNfc(), lock.getLockName());
+            }
+            // TODO
+           /* JobTicketUpdateProgressReqVO reqVO = new JobTicketUpdateProgressReqVO();
+            reqVO.userId = SecurityUtils.getUserId();
+            reqVO.ticketId = jobTicketLockList.get(0).getTicketId();
+            reqVO.equipStatus = 3;
+            isJobTicketService.updateTicketProgress(reqVO);*/
+        }
+
+        return true;
+    }
+
+
+    /**
+     * 批量更新作业票下隔离点的上锁状况
+     *
+     * @param list
+     * @return
+     */
+    @Transactional
+    @Override
+    public Boolean updateLockPointBatch(List<LockPointBatchDTO> list) {
+        Assert.isFalse(list.isEmpty(), "没有接收到数据啊!");
+        // 情况复杂,循环处理
+        for (LockPointBatchDTO dto : list) {
+            Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+            // 1.获取作业票数据
+            JobTicketDO jobTicket = isJobTicketService.getById(dto.getTicketId());
+            Assert.notNull(jobTicket, "作业票数据丢失啦!");
+            Assert.notBlank(dto.getLockNfc(), "挂锁nfc缺失!");
+            Assert.notBlank(dto.getPointNfc(), "请告知隔离点信息!");
+            Assert.notNull(dto.getTarget(), "请告我是去挂锁还是解锁!");
+            Assert.notNull(dto.getStatus(), "请告我任务当前状态!");
+            Assert.notBlank(dto.getKeyNfc(), "钥匙信息不可为空!");
+            // 1.通过nfc查询挂锁信息
+            LockDO lock = iIsLockService.getOne(Wrappers.<LockDO>lambdaQuery()
+                    .eq(LockDO::getLockNfc, dto.getLockNfc()));
+            Assert.notNull(lock, "该nfc无对应的挂锁信息");
+            // 1.1通过nfc查询钥匙信息
+            KeyDO key = isKeyService.getOne(Wrappers.<KeyDO>lambdaQuery()
+                    .eq(KeyDO::getKeyNfc, dto.getKeyNfc()));
+            Assert.notNull(lock, "该nfc无对应的钥匙信息");
+            // 2.通过nfc查询隔离点信息
+            IsolationPointRespVO point = iIsIsolationPointService.getOneByNfc(dto.getPointNfc());
+            Assert.notNull(point, "该nfc无对应的隔离点信息");
+            Date date = new Date();
+            if (dto.getTarget().equals(0)) {
+                log.info("--------------开始上锁-----------");
+                // 重复点位模式检查
+                checkBeforeLockKeyBack(isSystemAttributeService.getAttributeByKey("sys.job.lock_type").getSysAttrValue(), BeanUtils.toBean(point, IsolationPointDO.class), lock);
+                // 2.1更新隔离点上锁信息
+                iIsJobTicketPointsService.update(Wrappers.<JobTicketPointsDO>lambdaUpdate()
+                        .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketPointsDO::getPointId, point.getId())
+                        .set(JobTicketPointsDO::getLockId, lock.getId())
+                        .set(JobTicketPointsDO::getLockedByKeyId, key.getId())
+                        .set(JobTicketPointsDO::getLockTime, date)
+                        .set(JobTicketPointsDO::getPointStatus, PointStatusEnum.LOCKED.status));
+                // 3.开始更新上锁时挂锁信息
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketLockDO::getLockId, lock.getId())
+                        .set(JobTicketLockDO::getIsolationPointId, point.getId())
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.LOCKED.status));
+                // 4.如果隔离点上锁完毕,则更新作业负责人的任务状态
+                int count = (int) iIsJobTicketPointsService.count(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                        .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketPointsDO::getPointStatus, "0"));
+                if (count == 0) {
+                    iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                            .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue())
+                            .eq(JobTicketUserDO::getTicketId, dto.getTicketId())
+                            .set(JobTicketUserDO::getJobStatus, "4"));
+                }
+            } else {
+                log.info("--------------开始解锁-----------");
+                // 2.1.1更新隔离点解锁信息
+                iIsJobTicketPointsService.update(Wrappers.<JobTicketPointsDO>lambdaUpdate()
+                        .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketPointsDO::getPointId, point.getId())
+                        .set(JobTicketPointsDO::getUnlockedByKeyId, key.getId())
+                        .set(JobTicketPointsDO::getUnlockTime, date)
+                        .set(JobTicketPointsDO::getPointStatus, PointStatusEnum.REMOVE_LOCK.status));
+                // 3.1开始更新解锁时挂锁信息
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, dto.getTicketId())
+                        .eq(JobTicketLockDO::getLockId, lock.getId())
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.REMOVED_LOCK.status));
+                // 4.1如果都解锁了,则更新作业负责人的任务状态
+                int count = (int) iIsJobTicketPointsService.count(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                        .eq(JobTicketPointsDO::getTicketId, dto.getTicketId())
+                        .ne(JobTicketPointsDO::getPointStatus, "2"));
+                if (count == 0) {
+                    iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                            .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue())
+                            .eq(JobTicketUserDO::getTicketId, dto.getTicketId())
+                            .set(JobTicketUserDO::getJobStatus, "5"));
+                }
+                // 4.2开始更新因为重合点位,当时没有解锁的点位的数据
+                // updateConflictPoints(point.getPointId(), key.getKeyId(), date, lock.getLockId());
+            }
+        }
+        /*JobTicketUpdateProgressReqVO reqVO = new JobTicketUpdateProgressReqVO();
+        reqVO.userId = SecurityUtils.getUserId();
+        reqVO.ticketId = list.get(0).getTicketId();
+        reqVO.equipStatus = 3;
+        isJobTicketService.updateTicketProgress(reqVO);*/
+        // 4.更新下作业票的状态,如果是上锁时的操作
+        if (list.get(0).getTarget() != null && list.get(0).getTarget().equals(0)) {
+            isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate()
+                    .eq(JobTicketDO::getId, list.get(0).getTicketId())
+                    .set(JobTicketDO::getTicketStatus, "2"));
+        }
+        // 完成上锁
+        // 完成解锁
+        lockLog(list);
+        return true;
+    }
+
+    private void lockLog(List<LockPointBatchDTO> list) {
+        // 上锁日志
+        List<LockPointBatchDTO> lockList = list.stream().filter(o -> o.getTarget().equals(0)).collect(Collectors.toList());
+        if (!lockList.isEmpty()) {
+            JobTicketDO byId = isJobTicketService.getById(lockList.get(0).getTicketId());
+            if (byId != null) {
+                List<String> nfcList = lockList.stream().map(LockPointBatchDTO::getPointNfc).collect(Collectors.toList());
+                List<RfidTokenDO> list2 = iIsRfidTokenService.list(Wrappers.<RfidTokenDO>lambdaQuery()
+                        .in(RfidTokenDO::getRfid, nfcList));
+                List<Long> collect = list2.stream().map(RfidTokenDO::getId).collect(Collectors.toList());
+                List<IsolationPointDO> list1 = iIsIsolationPointService.list(Wrappers.<IsolationPointDO>lambdaQuery()
+                        .in(IsolationPointDO::getRfidId, collect));
+                // String pointNames = list1.stream().map(IsIsolationPoint::getPointName).collect(Collectors.joining(","));
+                StringBuilder pointNames = new StringBuilder();
+                for (IsolationPointDO isIsolationPoint : list1) {
+                    pointNames.append("<").append(isIsolationPoint.getPointIcon()).append(">").append("[").append(isIsolationPoint.getPointName()).append("] ");
+                }
+                // 完成上锁
+                isTicketOperLogService.addLog5(byId.getId(), byId.getTicketName(), pointNames.toString());
+            }
+        }
+        List<LockPointBatchDTO> unlockList = list.stream().filter(o -> o.getTarget().equals(1)).collect(Collectors.toList());
+        if (!unlockList.isEmpty()) {
+            JobTicketDO byId = isJobTicketService.getById(unlockList.get(0).getTicketId());
+            if (byId != null) {
+                List<String> nfcList = unlockList.stream().map(LockPointBatchDTO::getPointNfc).collect(Collectors.toList());
+                List<RfidTokenDO> list2 = iIsRfidTokenService.list(Wrappers.<RfidTokenDO>lambdaQuery()
+                        .in(RfidTokenDO::getRfid, nfcList));
+                List<Long> collect = list2.stream().map(RfidTokenDO::getId).collect(Collectors.toList());
+                List<IsolationPointDO> list1 = iIsIsolationPointService.list(Wrappers.<IsolationPointDO>lambdaQuery()
+                        .in(IsolationPointDO::getRfidId, collect));
+                StringBuilder pointNames = new StringBuilder();
+                for (IsolationPointDO isIsolationPoint : list1) {
+                    pointNames.append("<").append(isIsolationPoint.getPointIcon()).append(">").append("[").append(isIsolationPoint.getPointName()).append("] ");
+                }
+                // 完成解锁
+                isTicketOperLogService.addLog9(byId.getId(), byId.getTicketName(), String.valueOf(pointNames));
+            }
+        }
+    }
+
+    /**
+     * 需要增加上锁还钥匙的时候锁的验证
+     * 1)、强制共享锁,交叉点位的锁rfid还钥匙时必须相同
+     * 2)、强制多锁,交叉点位的锁rfid还钥匙时必须不同
+     * 3)、非强制共享锁,交叉点位的锁rfid还钥匙时可相同
+     * <p>
+     * 上锁后还钥匙
+     */
+    private void checkBeforeLockKeyBack(String type, IsolationPointDO point, LockDO lock) {
+        if (type.equals("1")) {
+            // 强制共享锁,交叉点位的锁rfid还钥匙时必须相同,即重复点位锁信息需与已上的锁的信息校验
+            // 开始查询已经上锁的点位信息
+            JobTicketPointsDO lockingData = iIsJobTicketPointsService.getLockingData(point.getId());
+            if (lockingData != null) {
+                Assert.isTrue(lock.getId().equals(lockingData.getLockId()),
+                        "点位挂锁错误!点位[" + point.getPointName() + "]当前正在被" + iIsLockService.getById(lockingData.getLockId()).getLockNfc() + "挂锁锁定!");
+            }
+        }
+        if (type.equals("2")) {
+            // 强制多锁,交叉点位的锁rfid还钥匙时必须不同
+            // 开始查询已经上锁的点位信息
+            JobTicketPointsDO lockingData = iIsJobTicketPointsService.getLockingData(point.getId());
+            if (lockingData != null) {
+                Assert.isFalse(lock.getId().equals(lockingData.getLockId()), "点位挂锁错误,重复点位[" + point.getPointName() + "]请多锁完成重复点位上锁!");
+            }
+        }
+    }
+
+
+    /**
+     * 解锁时,解除因为点位冲突而没有被解除的点位数据
+     */
+    public void updateConflictPoints(Long pointId, Long unlockedByKeyId, Date date, Long lockId) {
+        // 查询当前点位是否有取了钥匙去解锁的作业票,如果有则更新
+        List<JobTicketPointsDO> notFinishConflictJob = iIsJobTicketPointsService.getNotFinishConflictJob(pointId, lockId);
+        // 查询当前点位是否有已经完成的作业票,但是该点位没有解锁的
+        List<JobTicketPointsDO> finishConflictJob = iIsJobTicketPointsService.getFinishConflictJob(pointId, lockId);
+        finishConflictJob.addAll(notFinishConflictJob);
+        HashSet<JobTicketPointsDO> isJobTicketPoints1 = new HashSet<>(finishConflictJob);
+        // 查询都是去解锁的
+        if (!finishConflictJob.isEmpty()) {
+            for (JobTicketPointsDO isJobTicketPoints : isJobTicketPoints1) {
+                // 2.1.1更新隔离点解锁信息
+                iIsJobTicketPointsService.update(Wrappers.<JobTicketPointsDO>lambdaUpdate()
+                        .eq(JobTicketPointsDO::getId, isJobTicketPoints.getId())
+                        .set(JobTicketPointsDO::getUnlockedByKeyId, unlockedByKeyId)
+                        .set(JobTicketPointsDO::getUnlockTime, date)
+                        .set(JobTicketPointsDO::getPointStatus, PointStatusEnum.REMOVE_LOCK.status));
+                // 3.1开始更新解锁时挂锁信息
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, isJobTicketPoints.getTicketId())
+                        .eq(JobTicketLockDO::getIsolationPointId, pointId)
+                        .eq(JobTicketLockDO::getLockId, lockId)
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.REMOVED_LOCK.status));
+                // 4.1如果都解锁了,则更新作业负责人的任务状态
+                int count = (int) iIsJobTicketPointsService.count(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                        .eq(JobTicketPointsDO::getTicketId, isJobTicketPoints.getTicketId())
+                        .ne(JobTicketPointsDO::getPointStatus, "2"));
+                if (count == 0) {
+                    iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                            .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue())
+                            .eq(JobTicketUserDO::getTicketId, isJobTicketPoints.getTicketId())
+                            .set(JobTicketUserDO::getJobStatus, "5"));
+                }
+            }
+        }
+
+    }
+
+    /**
+     * 取出辅件时更新数据
+     *
+     * @param list
+     * @return
+     */
+    @Override
+    public Boolean updateLocksetTake(List<TakeLocksetDTO> list) {
+        Assert.isFalse(list.isEmpty(), "请取出至少一个辅件!");
+        // 情况复杂,软条件过多,单条剥离处理吧
+        for (TakeLocksetDTO dto : list) {
+            Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+            Assert.notBlank(dto.getLocksetNfc(), "辅件nfc缺失!");
+            // 1.查询辅件的详情
+            LocksetDO lockset = iIsLocksetService.getOne(Wrappers.<LocksetDO>lambdaQuery().eq(LocksetDO::getLocksetNfc, dto.getLocksetNfc()));
+            Assert.notNull(lockset, dto.getLocksetNfc() + "无对应的辅件信息!");
+            // 1.1通过序列号查询柜子信息
+            HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery()
+                    .eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+            Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+            // 1.2获取该辅件的类型,找到is_job_ticket_lockset有没有对应的,可能会有多条,取其中一条即可,
+            JobTicketLocksetDO jobTicketLockset = iIsJobTicketLocksetService.getOne(Wrappers.<JobTicketLocksetDO>lambdaQuery()
+                    .eq(JobTicketLocksetDO::getJobTicketId, dto.getTicketId())
+                    // 未使用过的数据
+                    .isNull(JobTicketLocksetDO::getLocksetId)
+                    // 处理下多条取一条用,按照从上倒下顺序使用
+                    .orderByAsc(JobTicketLocksetDO::getJobTicketId)
+                    .last("limit 1"));
+            Assert.notNull(jobTicketLockset, "无初始化数据来提供给该辅件更新");
+            // 1.3开始补充该条数据
+            jobTicketLockset.setLocksetId(lockset.getId());
+            jobTicketLockset.setFromHardwareId(isHardware.getId());
+            jobTicketLockset.setLocksetStatus(LocksetStatusEnum.TAKED.status);
+            jobTicketLockset.setCollectTime(new Date());
+            iIsJobTicketLocksetService.updateById(jobTicketLockset);
+        }
+        return true;
+    }
+
+    /**
+     * 辅件绑定隔离点(辅件和给隔离点上锁时)
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public Boolean updateLocksetPoint(LocksetPointDTO dto) {
+        Assert.notNull(dto.getTicketId(), "请告诉我关于哪个作业票!");
+        Assert.notBlank(dto.getLocksetNfc(), "辅件nfc缺失!");
+        Assert.notNull(dto.getPointNfc(), "请告知隔离点信息!");
+        // 1.通过nfc查询挂锁信息
+        LocksetDO lockset = iIsLocksetService.getOne(Wrappers.<LocksetDO>lambdaQuery()
+                .eq(LocksetDO::getLocksetNfc, dto.getLocksetNfc()));
+        Assert.notNull(lockset, "该nfc无对应的辅件信息");
+        // 2.通过nfc查询隔离点信息
+        IsolationPointRespVO point = iIsIsolationPointService.getOneByNfc(dto.getPointNfc());
+        Assert.notNull(point, "该nfc无对应的隔离点信息");
+        // 3.开始更新绑定关系
+        iIsJobTicketLocksetService.update(Wrappers.<JobTicketLocksetDO>lambdaUpdate()
+                .eq(JobTicketLocksetDO::getJobTicketId, dto.getTicketId())
+                .eq(JobTicketLocksetDO::getLocksetId, lockset.getId())
+                .set(JobTicketLocksetDO::getPointId, point.getId())
+                .set(JobTicketLocksetDO::getLocksetStatus, LocksetStatusEnum.USING.status));
+        return true;
+    }
+
+    /**
+     * 辅件归还物资柜
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public Boolean updateLocksetReturn(ReturnLocksetDTO dto) {
+        Assert.notBlank(dto.getLocksetNfc(), "辅件nfc缺失!");
+        Assert.notBlank(dto.getSerialNumber(), "请告知归还到哪一个柜子!");
+        // 1.通过nfc查询辅件信息
+        LocksetDO lockset = iIsLocksetService.getOne(Wrappers.<LocksetDO>lambdaQuery()
+                .eq(LocksetDO::getLocksetNfc, dto.getLocksetNfc()));
+        Assert.notNull(lockset, "该nfc无对应的辅件信息!");
+        // 1.1通过序列号查询柜子信息
+        HardwareDO isHardware = isHardwareService.getOne(Wrappers.<HardwareDO>lambdaQuery().eq(HardwareDO::getSerialNumber, dto.getSerialNumber()));
+        Assert.notNull(isHardware, "该序列号无对应的硬件信息!");
+        // 2.开始更新归还信息
+        if (dto.getTicketId() != null) {
+            // 2.1登陆后归还
+            iIsJobTicketLocksetService.update(Wrappers.<JobTicketLocksetDO>lambdaUpdate()
+                    .eq(JobTicketLocksetDO::getJobTicketId, dto.getTicketId())
+                    .eq(JobTicketLocksetDO::getLocksetId, lockset.getId())
+                    .set(JobTicketLocksetDO::getToHardwareId, isHardware.getId())
+                    .set(JobTicketLocksetDO::getLocksetStatus, LocksetStatusEnum.RETURNED.status));
+        } else {
+            // 2.2不登陆状态下归还
+            // 查一下哪个作业票用了这个挂锁,而且还没有完成
+            List<JobTicketLocksetDO> jobTicketLocksetList = iIsJobTicketLocksetService.list(Wrappers.<JobTicketLocksetDO>lambdaQuery()
+                    .eq(JobTicketLocksetDO::getLocksetId, lockset.getId())
+                    .ne(JobTicketLocksetDO::getLocksetStatus, LocksetStatusEnum.RETURNED.status));
+            if (jobTicketLocksetList.isEmpty()) {
+                log.error("当前辅件未找到关联的作业票, nfc: {}, name : {}", dto.getLocksetNfc(), lockset.getLocksetName());
+            } else if (jobTicketLocksetList.size() == 1) {
+                // 说明找到的就是
+                iIsJobTicketLocksetService.update(Wrappers.<JobTicketLocksetDO>lambdaUpdate()
+                        .eq(JobTicketLocksetDO::getLocksetId, lockset.getId())
+                        .set(JobTicketLocksetDO::getToHardwareId, isHardware.getId())
+                        .set(JobTicketLocksetDO::getLocksetStatus, LocksetStatusEnum.RETURNED.status));
+            } else {
+                // 出现了多条对应
+                log.error("当前辅件找到多条关联的作业票, nfc: {}, name : {}", dto.getLocksetNfc(), lockset.getLocksetName());
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 获取作业票和关联数据
+     *
+     * @param ticketId
+     * @return
+     */
+    @Override
+    public JobTicketRespVO selectTicketDetailById(Long ticketId) {
+        Assert.notNull(ticketId, "作业票id不可为空!");
+        // 1.查询作业票信息
+        JobTicketDO isJobTicket = isJobTicketService.getById(ticketId);
+        Assert.notNull(isJobTicket, "作业票信息丢失!");
+        JobTicketRespVO jobTicketVO = BeanUtils.toBean(isJobTicket, JobTicketRespVO.class);
+        // 2.查询钥匙数据
+        /*List<JobTicketKeyDO> ticketKeyList = iIsJobTicketKeyService.list(Wrappers.<JobTicketKeyDO>lambdaQuery()
+                .eq(JobTicketKeyDO::getTicketId, ticketId));
+        List<JobTicketKeyRespVO> ticketKeyVOList = BeanUtils.toBean(ticketKeyList, JobTicketKeyRespVO.class);*/
+        List<JobTicketKeyRespVO> ticketKeyVOList = iIsJobTicketKeyService.getListByTicketId(ticketId);
+        // 3.查询挂锁数据
+        List<JobTicketLockRespVO> ticketLockVOList = iIsJobTicketLockService.getTicketLockByTicketId(ticketId);
+        // 4.查询辅件数据
+        List<JobTicketLocksetDO> jobTicketLocksetList = iIsJobTicketLocksetService.list(Wrappers.<JobTicketLocksetDO>lambdaQuery()
+                .eq(JobTicketLocksetDO::getJobTicketId, ticketId));
+        List<JobTicketLocksetRespVO> ticketLocksetVOList = BeanUtils.toBean(jobTicketLocksetList, JobTicketLocksetRespVO.class);
+        // 5.查询用户数据
+        List<JobTicketUserDO> jobTicketUserList = iIsJobTicketUserService.list(Wrappers.<JobTicketUserDO>lambdaQuery()
+                .eq(JobTicketUserDO::getTicketId, ticketId));
+        List<JobTicketUserRespVO> ticketUserVOList = BeanUtils.toBean(jobTicketUserList, JobTicketUserRespVO.class);
+        // 6.查询隔离点数据
+        List<JobTicketPointsRespVO> ticketPointsVOList = iIsJobTicketPointsService.listByTicketId(ticketId);
+        if (!ticketPointsVOList.isEmpty()) {
+            List<Long> pointIds = ticketPointsVOList.stream().map(JobTicketPointsRespVO::getPointId).collect(Collectors.toList());
+            List<PointDetailVO> pointDetailList = iIsIsolationPointService.getPointDetailList(pointIds);
+            for (JobTicketPointsRespVO jobTicketPointsVO : ticketPointsVOList) {
+                for (PointDetailVO pointDetailVO : pointDetailList) {
+                    if (jobTicketPointsVO.getPointId().equals(pointDetailVO.getId())) {
+                        // jobTicketPointsVO.setPointCode(pointDetailVO.getPointCode());
+                        jobTicketPointsVO.setPointName(pointDetailVO.getPointName());
+                        jobTicketPointsVO.setPointType(pointDetailVO.getPointType());
+                        jobTicketPointsVO.setPointTypeName(pointDetailVO.getPointTypeName());
+                        jobTicketPointsVO.setPointNfc(pointDetailVO.getPointNfc());
+                        jobTicketPointsVO.setWorkshopName(pointDetailVO.getWorkshopName());
+                        jobTicketPointsVO.setWorkareaName(pointDetailVO.getWorkareaName());
+                        jobTicketPointsVO.setWorkstationId(pointDetailVO.getWorkstationId());
+                        jobTicketPointsVO.setWorkstationName(pointDetailVO.getWorkstationName());
+                        jobTicketPointsVO.setLotoId(pointDetailVO.getLotoId());
+                        jobTicketPointsVO.setLotoName(pointDetailVO.getLotoName());
+                        jobTicketPointsVO.setPowerType(pointDetailVO.getPowerType());
+                        jobTicketPointsVO.setPowerTypeName(pointDetailVO.getPowerTypeName());
+                        jobTicketPointsVO.setIsolationMethod(pointDetailVO.getIsolationMethod());
+                        jobTicketPointsVO.setPointIcon(pointDetailVO.getPointIcon());
+                        jobTicketPointsVO.setPointPicture(pointDetailVO.getPointPicture());
+                        jobTicketPointsVO.setLockTypeId(pointDetailVO.getLockTypeId());
+                        jobTicketPointsVO.setLockTypeCode(pointDetailVO.getLockTypeCode());
+                        jobTicketPointsVO.setLockTypeName(pointDetailVO.getLockTypeName());
+                        jobTicketPointsVO.setLockTypeIcon(pointDetailVO.getLockTypeIcon());
+                        jobTicketPointsVO.setLockTypeImg(pointDetailVO.getLockTypeImg());
+                        // jobTicketPointsVO.setLockNfc(pointDetailVO.getLockNfc());
+                        jobTicketPointsVO.setLocksetTypeId(pointDetailVO.getLocksetTypeId());
+                    }
+                }
+            }
+        }
+        // 7.解锁时,提供的不可解锁的点位数据
+        Set<JobTicketPointsRespVO> noUnlockTicketPointsVOSet = new HashSet<>();
+        // if (isSystemAttributeService.getIsSystemAttributeByKey("sys.job.lock_type").getSysAttrValue().equals("1")) {
+        // 查找点位相同并且用了同一个锁没有解锁的作业点位(存在虚拟锁的冲突点位)
+        for (JobTicketPointsRespVO jobTicketPointsVO : ticketPointsVOList) {
+            List<JobTicketPointsDO> virtualLockConflictPoint = iIsJobTicketPointsService.getVirtualLockConflictPoint(jobTicketPointsVO.getPointId(), jobTicketPointsVO.getLockId(), jobTicketPointsVO.getTicketId());
+            if (!virtualLockConflictPoint.isEmpty()) {
+                noUnlockTicketPointsVOSet.add(jobTicketPointsVO);
+            }
+        }
+        // }
+
+        // 8.组装数据
+        jobTicketVO.setTicketKeyList(ticketKeyVOList);
+        jobTicketVO.setTicketLockList(ticketLockVOList);
+        // jobTicketVO.setTicketLocksetList(ticketLocksetVOList);
+        jobTicketVO.setTicketUserList(ticketUserVOList);
+        jobTicketVO.setTicketPointsList(ticketPointsVOList);
+        jobTicketVO.setNoUnlockTicketPointsVOSet(noUnlockTicketPointsVOSet);
+        return jobTicketVO;
+    }
+
+    @Override
+    public Boolean updateColockerStatus(UpdateColockerStatusDTO dto) {
+        Assert.notNull(dto.getTicketId(), "作业票id不能为空!");
+        Assert.notBlank(dto.getJobStatus(), "操作的共锁/解锁状态不能为空!");
+        Assert.notBlank(dto.getCardNfc(), "工作卡NFC不能为空!");
+        // 1.根据作业卡获取当前人员状态
+        JobCardDO card = iIsJobCardService.getOne(Wrappers.<JobCardDO>lambdaQuery().eq(JobCardDO::getCardNfc, dto.getCardNfc()));
+        Assert.isFalse(card == null, "该工作卡未绑定用户!");
+        // 2.检测获取这个人在该作业票中状态
+        JobTicketUserDO jobTicketUser = iIsJobTicketUserService.getOne(Wrappers.<JobTicketUserDO>lambdaQuery()
+                .eq(JobTicketUserDO::getUserId, card.getUserId())
+                .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtcolocker").getSysAttrValue())
+                .eq(JobTicketUserDO::getTicketId, dto.getTicketId()));
+        Assert.isFalse(jobTicketUser == null, "该员工卡绑定的员工暂无作业任务!");
+        // 2.1判断状态
+        JobTicketDO isJobTicket = isJobTicketService.getById(dto.getTicketId());
+        Assert.isFalse("0".equals(isJobTicket.getTicketStatus()), "该作业票未开始,请勿共锁!");
+        Assert.isFalse("4".equals(dto.getJobStatus()) && "4".equals(jobTicketUser.getJobStatus()), "您已共锁,请勿重复共锁!");
+        Assert.isFalse(Integer.parseInt(jobTicketUser.getJobStatus()) < 4 && "5".equals(dto.getJobStatus()), "您还未共锁,请勿操作解除共锁!");
+        Assert.isFalse("5".equals(jobTicketUser.getJobStatus()) && "5".equals(dto.getJobStatus()), "您已解除共锁,请勿重复解除锁!");
+        // 3.开始操作
+        iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                .eq(JobTicketUserDO::getTicketId, dto.getTicketId())
+                .eq(JobTicketUserDO::getUserId, card.getUserId())
+                .set(JobTicketUserDO::getJobStatus, dto.getJobStatus()));
+        // 添加共锁
+        if (dto.getJobStatus().equals("4")) {
+            isTicketOperLogService.addLog6(isJobTicket.getId(), isJobTicket.getTicketName(), jobTicketUser.getUserName());
+        }
+        // 解除共锁
+        if (dto.getJobStatus().equals("5")) {
+            isTicketOperLogService.addLog7(isJobTicket.getId(), isJobTicket.getTicketName(), jobTicketUser.getUserName());
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean updateSwitchList(UpdateSwitchParam dto) {
+        Assert.isFalse(dto.getList().isEmpty(), "点位开关数据不可为空!");
+        dto.getList().forEach(o -> {
+            Assert.notBlank(o.getPointSerialNumber(), "序列号不可为空!");
+        });
+        redisCacheUtil.setCacheList(ISCS_ATTR + "sys.points.switch.last", dto.getList());
+        redisCacheUtil.expire(ISCS_ATTR + "sys.points.switch.last", 60, TimeUnit.SECONDS);
+        redisCacheUtil.deleteObject(ISCS_ATTR + "sys.points.switch.records");
+        redisCacheUtil.setCacheList(ISCS_ATTR + "sys.points.switch.records", dto.getList());
+        return true;
+    }
+
+    @Transactional
+    @Override
+    public Boolean checkBeforeToLock(Long ticketId) {
+        Assert.notNull(ticketId, "当前作业票id不能为空!");
+        // 0.检查是不是取了锁 但是没有取钥匙,如果是说明数据有问题,断过网
+        JobTicketDO isJobTicket = isJobTicketService.getById(ticketId);
+        // 4.更新下作业票的状态,如果是上锁时的操作
+        isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate()
+                .eq(JobTicketDO::getId, ticketId)
+                .set(JobTicketDO::getTicketStatus, "2"));
+        // 启动上锁
+        isTicketOperLogService.addLog4(isJobTicket.getId(), isJobTicket.getTicketName());
+        return true;
+    }
+
+    /**
+     * 纠正异常取锁
+     */
+    private void checkExTakeLock(Long ticketId) {
+        // 检查是否取出钥匙去上锁,如果没有取到钥匙,但是取出了挂锁,说明有问题,则清空挂锁信息
+        JobTicketKeyDO one = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaQuery()
+                .eq(JobTicketKeyDO::getTicketId, ticketId)
+                .eq(JobTicketKeyDO::getTicketType, 0)
+                .isNull(JobTicketKeyDO::getKeyId));
+        List<JobTicketLockDO> list = iIsJobTicketLockService.list(Wrappers.<JobTicketLockDO>lambdaQuery()
+                .eq(JobTicketLockDO::getTicketId, ticketId)
+                .isNotNull(JobTicketLockDO::getLockId));
+        if (one != null && !list.isEmpty()) {
+            // 现在是上锁前检查,但是钥匙已经取出来了,有问题啊,现在开始置空
+            for (JobTicketLockDO isJobTicketLock : list) {
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getId, isJobTicketLock.getId())
+                        .set(JobTicketLockDO::getLockId, null)
+                        .set(JobTicketLockDO::getLockStatus, "0")
+                        .set(JobTicketLockDO::getFromHardwareId, null)
+                );
+            }
+        }
+    }
+
+    @Override
+    public Boolean checkBeforeToUnlock(Long ticketId) {
+        Assert.notNull(ticketId, "当前作业票id不能为空!");
+        // 1.查询当前作业票需要解锁的点位信息
+        List<JobTicketPointsDO> listByTicketId = iIsJobTicketPointsService.list(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                .eq(JobTicketPointsDO::getTicketId, ticketId));
+        if (!listByTicketId.isEmpty()) {
+            // 如果存在冲突的作业,检查下到了哪个阶段(取了钥匙上锁还未归还、上锁钥匙已归还、取了钥匙去解锁未归还、解锁完成钥匙已归还)
+            List<Long> points = listByTicketId.stream().map(JobTicketPointsDO::getPointId).collect(Collectors.toList());
+            // 2.如果有重复点位,取了钥匙去上锁没有归还的作业
+            List<JobTicketDetailVO> jobTicketDetailVOS1 = isJobTicketService.selectConflictTicket1(points, ticketId);
+            if (!jobTicketDetailVOS1.isEmpty()) {
+                Assert.isFalse(true, "请等待作业票[" + jobTicketDetailVOS1.get(0).getTicketName() + "]上锁完成!");
+            }
+            // 3.如果取了钥匙去上锁已经归还,代表别的上锁已经完成,我可以解除不是重复的点位,然后手动完成作业,这样别人作业结束以后可以直接解除物理锁
+            // List<JobTicketDetailVO> jobTicketDetailVOS2 = isJobTicketService.selectConflictTicket2(points, ticketId);
+            // 4.如果别人取了钥匙去解锁,说明都是去解锁,我可以解全部
+
+            // 5.如果别人解除完了回来完成了作业,我可以解除全部
+        }
+        // 启动解锁
+        isTicketOperLogService.addLog8(ticketId, isJobTicketService.getById(ticketId).getTicketName());
+        return true;
+    }
+
+    @Override
+    public Boolean updateCoincideToUnLock(CoincidePointToUnLockDTO dto) {
+        if (!dto.getNoUnlockTicketPointsVOSet().isEmpty()) {
+            Date date = new Date();
+            for (JobTicketPointsRespVO jobTicketPointsVO : dto.getNoUnlockTicketPointsVOSet()) {
+                iIsJobTicketPointsService.update(Wrappers.<JobTicketPointsDO>lambdaUpdate()
+                        .eq(JobTicketPointsDO::getId, jobTicketPointsVO.getId())
+                        .set(JobTicketPointsDO::getUnlockedByKeyId, jobTicketPointsVO.getLockedByKeyId())
+                        .set(JobTicketPointsDO::getUnlockTime, date)
+                        .set(JobTicketPointsDO::getPointStatus, PointStatusEnum.REMOVE_LOCK.status));
+                // 3.1开始更新解锁时挂锁信息
+                iIsJobTicketLockService.update(Wrappers.<JobTicketLockDO>lambdaUpdate()
+                        .eq(JobTicketLockDO::getTicketId, jobTicketPointsVO.getTicketId())
+                        .eq(JobTicketLockDO::getLockId, jobTicketPointsVO.getLockId())
+                        .set(JobTicketLockDO::getLockStatus, LockStatusEnum.REMOVED_LOCK.status));
+                // 4.1如果都解锁了,则更新作业负责人的任务状态
+                int count = (int) iIsJobTicketPointsService.count(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                        .eq(JobTicketPointsDO::getTicketId, jobTicketPointsVO.getTicketId())
+                        .ne(JobTicketPointsDO::getPointStatus, "2"));
+                if (count == 0) {
+                    iIsJobTicketUserService.update(Wrappers.<JobTicketUserDO>lambdaUpdate()
+                            .eq(JobTicketUserDO::getUserRole, isSystemAttributeService.getAttributeByKey("role.jtlocker").getSysAttrValue())
+                            .eq(JobTicketUserDO::getTicketId, jobTicketPointsVO.getTicketId())
+                            .set(JobTicketUserDO::getJobStatus, "5"));
+                }
+            }
+        }
+        return true;
+    }
+
+    @Transactional
+    @Override
+    public Boolean updateHardwareEsStatus(ExDTO dto) {
+        // 1.开始更新钥匙
+        if (!dto.getKeyExDTOList().isEmpty()) {
+            List<String> keyNfcList = dto.getKeyExDTOList().stream().map(IsKeyExDTO::getKeyNfc).collect(Collectors.toList());
+            List<KeyDO> isKeyList = isKeyService.list(Wrappers.<KeyDO>lambdaQuery()
+                    .in(KeyDO::getKeyNfc, keyNfcList));
+            for (KeyDO isKey : isKeyList) {
+                for (IsKeyExDTO isKeyExDTO : dto.getKeyExDTOList()) {
+                    if (isKey.getKeyNfc().equals(isKeyExDTO.getKeyNfc())) {
+                        isKey.setExStatus(isKeyExDTO.getExStatus());
+                        isKey.setExRemark(isKeyExDTO.getExRemark());
+                    }
+                }
+            }
+            isKeyService.updateBatchById(isKeyList);
+        }
+        // 2.开始更新挂锁
+        if (!dto.getLockExDTOList().isEmpty()) {
+            List<String> lockNfcList = dto.getLockExDTOList().stream().map(IsLockExDTO::getLockNfc).collect(Collectors.toList());
+            List<LockDO> isLockList = iIsLockService.list(Wrappers.<LockDO>lambdaQuery()
+                    .in(LockDO::getLockNfc, lockNfcList));
+            for (LockDO isLock : isLockList) {
+                for (IsLockExDTO isLockExDTO : dto.getLockExDTOList()) {
+                    if (isLock.getLockNfc().equals(isLockExDTO.getLockNfc())) {
+                        isLock.setExStatus(isLockExDTO.getExStatus());
+                        isLock.setExRemark(isLockExDTO.getExRemark());
+                    }
+                }
+            }
+            iIsLockService.updateBatchById(isLockList);
+        }
+        // 3.开始更新工卡
+        if (!dto.getJobCardExDTOList().isEmpty()) {
+            List<String> cardNfcList = dto.getJobCardExDTOList().stream().map(IsJobCardExDTO::getCardNfc).collect(Collectors.toList());
+            List<JobCardDO> cardList = iIsJobCardService.list(Wrappers.<JobCardDO>lambdaQuery()
+                    .in(JobCardDO::getCardNfc, cardNfcList));
+            for (JobCardDO isJobCard : cardList) {
+                for (IsJobCardExDTO isJobCardExDTO : dto.getJobCardExDTOList()) {
+                    if (isJobCard.getCardNfc().equals(isJobCardExDTO.getCardNfc())) {
+                        isJobCard.setExStatus(isJobCardExDTO.getExStatus());
+                        isJobCard.setExRemark(isJobCardExDTO.getExRemark());
+                    }
+                }
+            }
+            iIsJobCardService.updateBatchById(cardList);
+        }
+        // 4.开始更新锁仓
+        if (!dto.getSlotsExDTOList().isEmpty()) {
+            for (IsLockCabinetSlotsExDTO slotsExDTO : dto.getSlotsExDTOList()) {
+                if (StringUtils.isNotBlank(slotsExDTO.getRow()) && StringUtils.isNotBlank(slotsExDTO.getCol())) {
+                    iIsLockCabinetSlotsService.update(Wrappers.<LockCabinetSlotsDO>lambdaUpdate()
+                            .eq(LockCabinetSlotsDO::getRow, slotsExDTO.getRow())
+                            .eq(LockCabinetSlotsDO::getCol, slotsExDTO.getCol())
+                            .set(LockCabinetSlotsDO::getStatus, slotsExDTO.getStatus())
+                            .set(LockCabinetSlotsDO::getRemark, slotsExDTO.getRemark()));
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean getMySelfState() {
+        // 当前登陆人
+        Long userId = getLoginUserId();
+        // 获取当前登陆人未完成的作业
+        List<JobTicketUserDO> myJobs = iIsJobTicketUserService.getMyJob(userId);
+        System.out.println("myJobs=" + myJobs.toString());
+        if (myJobs.isEmpty()) {
+            return false;
+        }
+        // 如果有,检查一下这个人是否是需要去上锁
+        for (JobTicketUserDO myJob : myJobs) {
+            List<JobTicketStepDO> steps = iIsJobTicketStepService.list(Wrappers.<JobTicketStepDO>lambdaQuery()
+                    .eq(JobTicketStepDO::getTicketId, myJob.getTicketId())
+                    .eq(JobTicketStepDO::getStepIndex, "5")
+                    .eq(JobTicketStepDO::getStepStatus, "0"));
+            System.out.println("steps=" + steps.toString());
+            if (!steps.isEmpty()) {
+                return true;
+            }
+        }
+        // 检查是否有需要解锁的,如果共锁人都已经解锁,但是点位存在没解锁
+        for (JobTicketUserDO myJob : myJobs) {
+            List<JobTicketUserDO> list = iIsJobTicketUserService.list(Wrappers.<JobTicketUserDO>lambdaQuery()
+                    .eq(JobTicketUserDO::getTicketId, myJob.getTicketId())
+                    .eq(JobTicketUserDO::getUserRole, JobUserEnum.JTCOLOCKER)
+                    .eq(JobTicketUserDO::getJobStatus, "5"));
+            List<JobTicketPointsDO> list1 = iIsJobTicketPointsService.list(Wrappers.<JobTicketPointsDO>lambdaQuery()
+                    .eq(JobTicketPointsDO::getTicketId, myJob.getTicketId())
+                    .eq(JobTicketPointsDO::getPointStatus, "1"));
+            System.out.println("list=" + list.toString() + "----------list1=" + list1.toString());
+            if (list.isEmpty() && !list1.isEmpty()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 判断挂锁关联作业处于哪个阶段 0-上锁未取钥匙(可锁-需更改还锁逻辑) 1-上锁取了钥匙(不可锁) 2-上锁归还了钥匙(可锁) 3-解锁取了钥匙(可锁) 4-解锁归还了钥匙(可锁) 5-和作业无关(可锁)
+     *
+     * @param nfc
+     * @return
+     */
+    @Override
+    public Integer getLockStateByNfc(String nfc, Long ticketId) {
+        Assert.notBlank(nfc, "该锁nfc不能为空!");
+        // 查询当前锁是否存在
+        LockDO lock = iIsLockService.getOne(Wrappers.<LockDO>lambdaQuery()
+                .eq(LockDO::getLockNfc, nfc));
+        Assert.isFalse(lock == null, nfc + "对应的挂锁数据不存在!");
+        // 查询这个挂锁有没有不是完成或者取消的作业,然后判断作业能不能
+        JobTicketLockDO lockJobByBfc = iIsJobTicketLockService.getLockJobByBfc(nfc, ticketId);
+        if (lockJobByBfc != null) {
+            // 判断作业到了什么阶段
+            // 获取上锁时钥匙的最新一条数据
+            JobTicketKeyDO lockLast = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaQuery()
+                    .eq(JobTicketKeyDO::getTicketId, lockJobByBfc.getTicketId())
+                    .eq(JobTicketKeyDO::getTicketType, 0)
+                    .orderByDesc(JobTicketKeyDO::getId)
+                    .last("limit 1"));
+            // 获取解锁时钥匙的最新一条数据
+            JobTicketKeyDO unlockLast = iIsJobTicketKeyService.getOne(Wrappers.<JobTicketKeyDO>lambdaQuery()
+                    .eq(JobTicketKeyDO::getTicketId, lockJobByBfc.getTicketId())
+                    .eq(JobTicketKeyDO::getTicketType, 1)
+                    .orderByDesc(JobTicketKeyDO::getId)
+                    .last("limit 1"));
+            // 判断阶段
+            if (lockLast.getKeyStatus().equals("0")) {
+                return 0;
+            } else if (lockLast.getKeyStatus().equals("1")) {
+                return 1;
+            } else if (lockLast.getKeyStatus().equals("2") && unlockLast.getKeyStatus().equals("0")) {
+                return 2;
+            } else if (unlockLast.getKeyStatus().equals("1")) {
+                return 3;
+            } else if (unlockLast.getKeyStatus().equals("2")) {
+                return 4;
+            }
+        }
+        return 5;
+    }
+
+    @Override
+    public Boolean updateJobToFinish(JobTicketSaveReqVO isJobTicket) {
+        Assert.notNull(isJobTicket.getId(), "作业票ID不可为空!");
+        // 1.查询未完成的八大步骤
+        List<JobTicketStepDO> list = iIsJobTicketStepService.list(Wrappers.<JobTicketStepDO>lambdaQuery()
+                .eq(JobTicketStepDO::getTicketId, isJobTicket.getId())
+                .ne(JobTicketStepDO::getStepStatus, 1));
+        Assert.isTrue(list.isEmpty(), "存在未完成的步骤,暂不可完成!");
+        // 2.既然走到这了,说明可以完成了
+        isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate().eq(JobTicketDO::getId, isJobTicket.getId())
+                .set(JobTicketDO::getTicketStatus, FINISHED.status)
+                .set(JobTicketDO::getTicketEndTime, new Date()));
+        // 结束作业
+        isTicketOperLogService.addLog11(isJobTicket.getId(), isJobTicketService.getById(isJobTicket.getId()).getTicketName());
+        return true;
+    }
+
+    @Override
+    public Boolean updateJobToCancel(JobTicketSaveReqVO isJobTicket) {
+        Assert.notNull(isJobTicket.getId(), "作业票ID不可为空!");
+        // 1.检查第六步有没有被执行,被执行了不能取消
+        JobTicketStepDO jobTicketStep = iIsJobTicketStepService.getOne(Wrappers.<JobTicketStepDO>lambdaQuery()
+                .eq(JobTicketStepDO::getTicketId, isJobTicket.getId())
+                .eq(JobTicketStepDO::getStepIndex, 6)
+                .eq(JobTicketStepDO::getStepStatus, 1));
+        Assert.isFalse(jobTicketStep != null, "该作业票已执行至第六步,无法取消!");
+        // 2.既然走到这了,说明可以取消
+        isJobTicketService.update(Wrappers.<JobTicketDO>lambdaUpdate().eq(JobTicketDO::getId, isJobTicket.getId())
+                .set(JobTicketDO::getTicketStatus, 6));
+        // 取消作业
+        isTicketOperLogService.addLog10(isJobTicket.getId(), isJobTicketService.getById(isJobTicket.getId()).getTicketName());
+        return true;
+    }
+}

+ 179 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareMaterialApiService.java

@@ -0,0 +1,179 @@
+package cn.iocoder.yudao.module.iscs.service.hardwareapi;
+
+import cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi.*;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.cabinetopenrecord.CabinetOpenRecordDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi.*;
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import java.util.List;
+
+/**
+ * 硬件调用接口
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+public interface HardwareMaterialApiService {
+
+    /**
+     * 查询物资柜下物资类型,标注异常类型下的物资数量,展示异常物资
+     * @param cabinetId
+     * @return
+     */
+    List<ExMaterialTypeVO> selectExMaterialTypeById(Long cabinetId, String cabinetCode) throws JsonProcessingException;
+
+    /**
+     * 手动更换数据校验
+     * @param dto
+     * @return
+     */
+    Boolean checkReplaceData(ReplaceMaterialDTO dto);
+
+    /**
+     * 手动更换物资-校验后的提交
+     * @param dto
+     * @return
+     */
+    Boolean insertCheckedRecord(ReplaceMaterialParamDTO dto) throws JsonProcessingException;
+
+    /**
+     * 手动更换物资
+     * @param dto
+     * @return
+     */
+    Boolean insertReplaceRecord(ReplaceMaterialParamDTO dto) throws JsonProcessingException;
+
+    /**
+     * 手动更换物资-实体操作
+     * @param dto
+     * @return
+     */
+    Boolean updateMaterialsReplace(ReplaceMaterialsDTO dto);
+
+    /**
+     * 新增物资柜开门超时异常
+     * @param dto
+     * @return
+     */
+    Boolean insertCabinetOpenTimeout(OpenTimeoutDTO dto);
+
+    /**
+     * 解除柜开门超时异常
+     * @param dto
+     * @return
+     */
+    Boolean updateCabinetOpenTimeout(OpenTimeoutDTO dto);
+
+    /**
+     * 新增物资柜开门记录
+     * @param dto
+     * @return
+     */
+    Boolean insertCabinetOpenRecord(CabinetOpenRecordDO dto);
+
+    /**
+     * 物资柜关门
+     * @param dto
+     * @return
+     */
+    Boolean updateCabinetClose(CabinetOpenRecordDO dto);
+
+    /**
+     * 获取物资柜物品分类及分类下物资数量和列表
+     * @param cabinetId
+     * @return
+     */
+    List<CabinetMaterialVO> selectMaterialsByCabinetId(Long cabinetId, String cabinetCode) throws JsonProcessingException;
+
+    /**
+     * 通过RFID获取物资信息
+     * @param rfid
+     * @return
+     */
+    MaterialsDO selectMaterialByRfid(String rfid);
+
+    /**
+     * 通过RFID列表获取批量物资信息
+     * @param dto
+     * @return
+     */
+    List<MaterialsDO> selectMaterialsByRfidList(RfidListDTO dto);
+
+    /**
+     * 通过RFID列表获取批量物资信息
+     * @param dto
+     * @return
+     */
+    CabinetMaterialsVO selectCabinetMaterials(CabinetRfidListDTO dto);
+
+    /**
+     * 物资领取/归还
+     * @param dto
+     * @return
+     */
+    String updateMaterialReceiveReturn(RecRetParamDTO dto) throws Exception;
+
+    /**
+     * 查询物资使用说明
+     * @return
+     */
+    List<InstructionVO> getInstructionsList();
+
+    /**
+     * 我的在某个柜子上的最近一次物资检查计划
+     * @param cabinetCode
+     * @return
+     */
+    CabinetCheckVO getLastCheckPlanByCabinetCode(String cabinetCode);
+
+    /**
+     * 主界面
+     * @param cabinetCode
+     * @return
+     */
+    CabinetHomePageVO getCabinetHomePage(String cabinetCode);
+
+    /**
+     * 物资检查表
+     * @param cabinetCode
+     * @return
+     */
+    MaterialsCheckInitVO getCheckMaterialsByCabinetCode(String cabinetCode, Long planId);
+
+    /**
+     * 提交物资检查记录
+     * @param dto
+     * @return
+     */
+    Boolean insertCheckRecord(CheckParamDTO dto);
+
+    /**
+     * 最终提交物资检查记录
+     * @param dto
+     * @return
+     */
+    Boolean insertSubmitPlan(SubmitPlanDTO dto);
+
+    /**
+     * 检查签名
+     * @param dto
+     * @return
+     */
+    Boolean insertSign(SignDTO dto);
+
+    /**
+     * 自动更换
+     * @param dto
+     * @return
+     */
+    AutoReplaceReportVO insertAutoChange(AutoChangeDTO dto);
+
+    /**
+     * 开始检查
+     * @param dto
+     * @return
+     */
+    Boolean startCheckPlan(StartCheckPlanDTO dto);
+
+}

+ 1299 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareMaterialApiServiceImpl.java

@@ -0,0 +1,1299 @@
+package cn.iocoder.yudao.module.iscs.service.hardwareapi;
+
+import cn.hutool.core.lang.Assert;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.iscs.controller.admin.hardwareapi.hardwareMaterialApi.*;
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.MaterialsRespVO;
+import cn.iocoder.yudao.module.iscs.controller.admin.materials.vo.PropertyVO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.cabinetopenrecord.CabinetOpenRecordDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.exceptionmisplace.ExceptionMisplaceDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materials.MaterialsDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscabinet.MaterialsCabinetDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialschangerecord.MaterialsChangeRecordDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscheckplan.MaterialsCheckPlanDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialscheckrecord.MaterialsCheckRecordDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialsinstructions.MaterialsInstructionsDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialsloan.MaterialsLoanDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialsplancabinet.MaterialsPlanCabinetDO;
+import cn.iocoder.yudao.module.iscs.dal.dataobject.materialstype.MaterialsTypeDO;
+import cn.iocoder.yudao.module.iscs.dal.dto.hardwareMaterialApi.*;
+import cn.iocoder.yudao.module.iscs.service.cabinetopenrecord.CabinetOpenRecordService;
+import cn.iocoder.yudao.module.iscs.service.exceptionmisplace.ExceptionMisplaceService;
+import cn.iocoder.yudao.module.iscs.service.materials.MaterialsService;
+import cn.iocoder.yudao.module.iscs.service.materialscabinet.MaterialsCabinetService;
+import cn.iocoder.yudao.module.iscs.service.materialschangerecord.MaterialsChangeRecordService;
+import cn.iocoder.yudao.module.iscs.service.materialscheckplan.MaterialsCheckPlanService;
+import cn.iocoder.yudao.module.iscs.service.materialscheckrecord.MaterialsCheckRecordService;
+import cn.iocoder.yudao.module.iscs.service.materialsinstructions.MaterialsInstructionsService;
+import cn.iocoder.yudao.module.iscs.service.materialsloan.MaterialsLoanService;
+import cn.iocoder.yudao.module.iscs.service.materialsplancabinet.MaterialsPlanCabinetService;
+import cn.iocoder.yudao.module.iscs.service.materialstype.MaterialsTypeService;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
+
+/**
+ * 硬件Service业务层处理
+ *
+ * @author cgj
+ * @date 2024-10-16
+ */
+@Slf4j
+@Service
+public class HardwareMaterialApiServiceImpl implements HardwareMaterialApiService {
+    @Autowired
+    private MaterialsService materialsService;
+    @Autowired
+    private MaterialsCabinetService materialsCabinetService;
+    @Autowired
+    private MaterialsTypeService materialsTypeService;
+    @Lazy
+    @Autowired
+    private MaterialsChangeRecordService materialsChangeRecordService;
+    @Autowired
+    private ExceptionMisplaceService exceptionMisplaceService;
+    @Autowired
+    private CabinetOpenRecordService cabinetOpenRecordService;
+    @Lazy
+    @Autowired
+    private MaterialsCheckRecordService materialsCheckRecordService;
+    @Autowired
+    private MaterialsInstructionsService materialsInstructionsService;
+    @Lazy
+    @Autowired
+    private MaterialsCheckPlanService materialsCheckPlanService;
+    @Lazy
+    @Autowired
+    private MaterialsPlanCabinetService materialsPlanCabinetService;
+    @Autowired
+    private MaterialsLoanService materialsLoanService;
+
+
+    @Override
+    public List<ExMaterialTypeVO> selectExMaterialTypeById(Long cabinetId, String cabinetCode) throws JsonProcessingException {
+        // Assert.notNull(cabinetId, "物资柜ID不能为空!");
+        if (cabinetId != null) {
+        } else {
+            Assert.notBlank(cabinetCode, "物资柜code不能为空!");
+            MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                    .eq(MaterialsCabinetDO::getCabinetCode, cabinetCode));
+            Assert.isFalse(cabinet == null, "物资柜信息不存在!");
+            cabinetId = cabinet.getId();
+        }
+        // 0.构造返回值
+        ArrayList<ExMaterialTypeVO> exMaterialTypeVOS = new ArrayList<>();
+        // 1.查询物资柜下有哪些物资
+        List<MaterialsDO> materials = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinetId));
+        // 1.1如果柜子下有物资,才有继续的必要
+        if (!materials.isEmpty()) {
+            // 2.找出这些物资有哪些分类,去掉重复的
+            Set<Long> materialsTypeIdSet = materials.stream().map(MaterialsDO::getMaterialsTypeId).filter(materialsTypeId -> materialsTypeId != null).collect(Collectors.toSet());
+            // 2.1查询分类的数据,需要拼接name
+            List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(materialsTypeIdSet);
+            // 2.2如果这个类型有数据才有意义
+            if (!isMaterialsTypes.isEmpty()) {
+                // 3.构造’全部‘数据
+                ExMaterialTypeVO sumExMaterialTypeVO = new ExMaterialTypeVO();
+                sumExMaterialTypeVO.setMaterialsTypeId(0L);
+                sumExMaterialTypeVO.setMaterialsTypeName("全部");
+                // 承接’全部‘
+                int sumExNumber = 0;
+                ArrayList<MaterialsRespVO> isMaterials = new ArrayList<>();
+                // 解析物资规格
+                ObjectMapper objectMapper = new ObjectMapper();
+                // 3.1循环构造返回类
+                for (MaterialsTypeDO isMaterialsType : isMaterialsTypes) {
+                    ExMaterialTypeVO exMaterialTypeVO = new ExMaterialTypeVO();
+                    exMaterialTypeVO.setMaterialsTypeId(isMaterialsType.getId());
+                    exMaterialTypeVO.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                    exMaterialTypeVO.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                    exMaterialTypeVO.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                    // 过滤获取该类型下的异常物资,1表示损坏 2表示过期
+                    List<MaterialsDO> exMaterials = materials.stream().filter(o -> o.getMaterialsTypeId().equals(isMaterialsType.getId())
+                            && ("1".equals(o.getStatus()) || "2".equals(o.getStatus()))).collect(Collectors.toList());
+                    // 解析物资规格
+                    List<MaterialsRespVO> beans = BeanUtils.toBean(exMaterials, MaterialsRespVO.class);
+                    for (MaterialsRespVO record : beans) {
+                        // String propertiesValue = propertyVOS.stream().map(PropertyVO::getValueName).collect(Collectors.joining(","));
+                        // 目前最多一条
+                        if (StringUtils.isNotBlank(record.getProperties())) {
+                            List<PropertyVO> propertyVOS = objectMapper.readValue(record.getProperties(), new TypeReference<>() {
+                            });
+                            record.setPropertiesValueId(propertyVOS.get(0).getRecordId());
+                            record.setPropertiesValue(propertyVOS.get(0).getValueName());
+                            record.setPropertiesPropertyId(propertyVOS.get(0).getPropertyId());
+                            record.setPropertiesProperty(propertyVOS.get(0).getPropertyName());
+                        }
+                        record.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                        record.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                    }
+                    exMaterialTypeVO.setExNumber(exMaterials.size());
+                    exMaterialTypeVO.setMaterials(beans);
+                    exMaterialTypeVOS.add(exMaterialTypeVO);
+                    // ’全部‘累加
+                    sumExNumber = sumExNumber + exMaterials.size();
+                    // ’全部‘集合
+                    isMaterials.addAll(beans);
+                }
+                // 3.2将‘全部’的数据补充完整
+                sumExMaterialTypeVO.setExNumber(sumExNumber);
+                sumExMaterialTypeVO.setMaterials(isMaterials);
+                exMaterialTypeVOS.add(0, sumExMaterialTypeVO);
+            }
+        }
+        return exMaterialTypeVOS;
+    }
+
+    @Override
+    public Boolean checkReplaceData(ReplaceMaterialDTO dto) {
+        Assert.notNull(dto.getOldMaterialsId(), "旧物资ID不能为空!");
+        Assert.notBlank(dto.getMaterialsRfid(), "新物资RFID不能为空!");
+        // 1.获取旧物资信息
+        MaterialsDO oldMaterials = materialsService.getById(dto.getOldMaterialsId());
+        // 判断旧物资和新物资的rfid是否更换
+        if (dto.getMaterialsRfid().equals(oldMaterials.getMaterialsRfid())) {
+            // 2.没有更换rfid
+
+
+        } else {
+            // 3.更换rfid
+            // 判断是否在柜子外 判断rfid是否重复,如果重复,判断重复数据是否绑定物资柜,如果没有绑定直接用,如果绑定,报异常
+            Assert.isFalse(oldMaterials.getLoanState().equals("1"), "需要更换的物资未取出!");
+            // 判断新物资RFID是否被使用
+            MaterialsDO one = materialsService.getOne(Wrappers.<MaterialsDO>lambdaQuery()
+                    .eq(MaterialsDO::getMaterialsRfid, dto.getMaterialsRfid()));
+            Assert.isFalse(one != null && one.getMaterialsCabinetId() != null && one.getMaterialsCabinetId() != 0, "该RFID已被使用!");
+            // 判断新物资是否在物资当前柜子中
+            /*if (one != null) {
+                IsMaterialsLoanException one1 = isMaterialsLoanExceptionService.getOne(Wrappers.<IsMaterialsLoanException>lambdaQuery()
+                        .eq(IsMaterialsLoanException::getMaterialsRfid, dto.getMaterialsRfid())
+                        .eq(IsMaterialsLoanException::getStatus, 0)
+                        .eq(IsMaterialsLoanException::getRestitutionToId, oldMaterials.getMaterialsCabinetId())
+                        .orderByDesc(IsMaterialsLoanException::getMisplaceId)
+                        .last("limit 1"));
+                Assert.isTrue(one1 != null, "请在该柜中放入新物资!");
+            }*/
+
+        }
+        return true;
+    }
+
+    @Transactional
+    @Override
+    public Boolean insertCheckedRecord(ReplaceMaterialParamDTO dto) throws JsonProcessingException {
+        Assert.isFalse(dto.getList().isEmpty(), "没有确定要维修或更换的物资!");
+        Long cabinetId = null;
+        // 因为比较复杂,循环处理
+        for (ReplaceMaterialDTO replaceMaterialDTO : dto.getList()) {
+            Boolean b = checkReplaceData(replaceMaterialDTO);
+            if (!b) {
+                System.out.println("进来了-------------------");
+                continue;
+            }
+            Assert.notNull(replaceMaterialDTO.getOldMaterialsId(), "旧物资ID不能为空!");
+            MaterialsDO oldMaterial = materialsService.getById(replaceMaterialDTO.getOldMaterialsId());
+            cabinetId = oldMaterial.getMaterialsCabinetId();
+            // 查询该物资的最新报异常记录
+            MaterialsCheckRecordDO checkRecord = materialsCheckRecordService.getOne(Wrappers.<MaterialsCheckRecordDO>lambdaQuery()
+                    .eq(MaterialsCheckRecordDO::getMaterialsId, replaceMaterialDTO.getOldMaterialsId())
+                    .eq(MaterialsCheckRecordDO::getStatus, "1")
+                    .orderByDesc(MaterialsCheckRecordDO::getId)
+                    .last("limit 1"));
+            // 判断物资是不是维修,如果是维修,做维修处理
+            if (StringUtils.isNotBlank(replaceMaterialDTO.getMeasure()) && replaceMaterialDTO.getMeasure().equals("维修")) {
+                // 如果是维修直接更新物资状态
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, replaceMaterialDTO.getOldMaterialsId())
+                        .set(MaterialsDO::getStatus, "0"));
+                // 生成维修记录
+                MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+                isMaterialsChangeRecord.setOldMaterialsId(replaceMaterialDTO.getOldMaterialsId());
+                isMaterialsChangeRecord.setOldMaterialsRfid(oldMaterial.getMaterialsRfid());
+                isMaterialsChangeRecord.setNewMaterialsId(oldMaterial.getId());
+                isMaterialsChangeRecord.setNewMaterialsRfid(oldMaterial.getMaterialsRfid());
+                isMaterialsChangeRecord.setChangeUserId(getLoginUserId());
+                isMaterialsChangeRecord.setChangeDate(new Date());
+                isMaterialsChangeRecord.setChangeType("0");
+                isMaterialsChangeRecord.setOperateType("3");
+                isMaterialsChangeRecord.setCheckRecordId(checkRecord != null ? checkRecord.getId() : null);
+                materialsChangeRecordService.save(isMaterialsChangeRecord);
+                return true;
+            }
+
+            // 1.对旧物资进行处理,如果新物资需要使用旧物资的rfid,则把旧物资的rfid清理掉,然后绑定给新物资,最后开柜门拿出旧物资解绑就可以了
+            if (StringUtils.isNotBlank(oldMaterial.getMaterialsRfid()) && oldMaterial.getMaterialsRfid().equals(replaceMaterialDTO.getMaterialsRfid())) {
+                // 1.1该情况属于新物资需要使用旧物资的rfid
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, replaceMaterialDTO.getOldMaterialsId())
+                        .set(MaterialsDO::getMaterialsCabinetId, null)
+                        .set(MaterialsDO::getMaterialsRfid, null));
+            }
+            // 1.2无论是否更换rfid,新物资的数据都要存储到物资清单之中
+            MaterialsDO newMaterial = new MaterialsDO();
+            if (oldMaterial.getMaterialsRfid().equals(replaceMaterialDTO.getMaterialsRfid())) {
+                // 如果更换物资的rfid相同
+                newMaterial.setMaterialsName(replaceMaterialDTO.getMaterialsName());
+                newMaterial.setMaterialsTypeId(replaceMaterialDTO.getMaterialsTypeId());
+                newMaterial.setMaterialsCabinetId(oldMaterial.getMaterialsCabinetId());
+                newMaterial.setLoanState(oldMaterial.getLoanState());
+                newMaterial.setMaterialsRfid(replaceMaterialDTO.getMaterialsRfid());
+                newMaterial.setSupplier(oldMaterial.getSupplier());
+                newMaterial.setExpirationDate(replaceMaterialDTO.getExpirationDate());
+                newMaterial.setStatus("0");
+
+                PropertyVO propertyVO = new PropertyVO();
+                propertyVO.setPropertyId(String.valueOf(replaceMaterialDTO.getPropertiesPropertyId()));
+                propertyVO.setPropertyName(replaceMaterialDTO.getPropertiesProperty());
+                propertyVO.setRecordId(String.valueOf(replaceMaterialDTO.getPropertiesValueId()));
+                propertyVO.setValueName(replaceMaterialDTO.getPropertiesValue());
+                // 使用 ObjectMapper 将对象转换为 JSON 字符串
+                ObjectMapper objectMapper = new ObjectMapper();
+                String jsonString = objectMapper.writeValueAsString(propertyVO);
+                newMaterial.setProperties("[" + jsonString + "]");
+                materialsService.save(newMaterial);
+            }
+
+            MaterialsDO newMaterials = materialsService.getOne(Wrappers.<MaterialsDO>lambdaQuery()
+                    .eq(MaterialsDO::getMaterialsRfid, replaceMaterialDTO.getMaterialsRfid()));
+            if (!oldMaterial.getMaterialsRfid().equals(replaceMaterialDTO.getMaterialsRfid()) && newMaterials == null) {
+                // 如果更换rfid,并且不在系统内的数据
+                newMaterial.setMaterialsName(replaceMaterialDTO.getMaterialsName());
+                newMaterial.setMaterialsTypeId(replaceMaterialDTO.getMaterialsTypeId());
+                newMaterial.setMaterialsCabinetId(oldMaterial.getMaterialsCabinetId());
+                newMaterial.setLoanState("1");
+                newMaterial.setMaterialsRfid(replaceMaterialDTO.getMaterialsRfid());
+                newMaterial.setSupplier(oldMaterial.getSupplier());
+                newMaterial.setExpirationDate(replaceMaterialDTO.getExpirationDate());
+                newMaterial.setStatus("0");
+
+                PropertyVO propertyVO = new PropertyVO();
+                propertyVO.setPropertyId(String.valueOf(replaceMaterialDTO.getPropertiesPropertyId()));
+                propertyVO.setPropertyName(replaceMaterialDTO.getPropertiesProperty());
+                propertyVO.setRecordId(String.valueOf(replaceMaterialDTO.getPropertiesValueId()));
+                propertyVO.setValueName(replaceMaterialDTO.getPropertiesValue());
+                // 使用 ObjectMapper 将对象转换为 JSON 字符串
+                ObjectMapper objectMapper = new ObjectMapper();
+                String jsonString = objectMapper.writeValueAsString(propertyVO);
+                newMaterial.setProperties("[" + jsonString + "]");
+                materialsService.save(newMaterial);
+
+                // 将旧物资解绑
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getMaterialsRfid, oldMaterial.getMaterialsRfid())
+                        .set(MaterialsDO::getMaterialsCabinetId, null));
+            }
+
+            if (!oldMaterial.getMaterialsRfid().equals(replaceMaterialDTO.getMaterialsRfid()) && newMaterials != null) {
+                // 如果发现物资是存在的,判断下有没有绑定柜子
+                Assert.isFalse(newMaterials.getMaterialsCabinetId() != null && newMaterials.getMaterialsCabinetId() != 0, "该物资存在所属柜子,不可更换!");
+                Assert.isTrue(newMaterials.getStatus().equals("0"), "更换的物资异常,不可更换!");
+                // 如果没有绑定柜子,则可以开始绑定
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, newMaterials.getId())
+                        .set(MaterialsDO::getMaterialsCabinetId, oldMaterial.getMaterialsCabinetId()));
+                // 解绑老物资
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, oldMaterial.getId())
+                        .set(MaterialsDO::getMaterialsCabinetId, null));
+            }
+
+            // 2.新增物资更换记录
+            MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+            isMaterialsChangeRecord.setOldMaterialsId(replaceMaterialDTO.getOldMaterialsId());
+            isMaterialsChangeRecord.setOldMaterialsRfid(oldMaterial.getMaterialsRfid());
+            isMaterialsChangeRecord.setNewMaterialsId(newMaterial.getId());
+            isMaterialsChangeRecord.setNewMaterialsRfid(newMaterial.getMaterialsRfid());
+            isMaterialsChangeRecord.setChangeUserId(getLoginUserId());
+            isMaterialsChangeRecord.setChangeDate(new Date());
+            isMaterialsChangeRecord.setChangeType("0");
+
+            if (checkRecord != null) {
+                isMaterialsChangeRecord.setCheckRecordId(checkRecord.getId());
+            } else {
+                isMaterialsChangeRecord.setCheckRecordId(0L);
+            }
+            materialsChangeRecordService.save(isMaterialsChangeRecord);
+
+            // 删除旧物资的取出记录和新物资的存入异常---曹特殊要求,改成完成的数据
+            materialsLoanService.update(Wrappers.<MaterialsLoanDO>lambdaUpdate()
+                    .eq(MaterialsLoanDO::getMaterialsId, oldMaterial.getId())
+                    .ne(MaterialsLoanDO::getStatus, "1")
+                    .set(MaterialsLoanDO::getRemark, "物资更换")
+                    .set(MaterialsLoanDO::getStatus, "1")
+                    .set(MaterialsLoanDO::getRestitutionUserId, getLoginUserId())
+                    .set(MaterialsLoanDO::getActualRestitutionTime, new Date()));
+            // 删除新物资的存入异常---曹特殊要求,改成完成的数据
+            exceptionMisplaceService.update(Wrappers.<ExceptionMisplaceDO>lambdaUpdate()
+                    .eq(ExceptionMisplaceDO::getMaterialsRfid, replaceMaterialDTO.getMaterialsRfid())
+                    .eq(ExceptionMisplaceDO::getStatus, "0")
+                    .set(ExceptionMisplaceDO::getRemark, "物资更换")
+                    .set(ExceptionMisplaceDO::getStatus, "1")
+                    .set(ExceptionMisplaceDO::getHandleTime, new Date()));
+        }
+        // 更新检查记录
+        if (cabinetId != null) {
+            MaterialsCabinetDO byId = materialsCabinetService.getById(cabinetId);
+            if (byId != null) {
+                materialsPlanCabinetService.autoChangeCheckRecord(byId.getCabinetCode());
+            }
+        }
+        return true;
+    }
+
+    @Transactional
+    @Override
+    public Boolean insertReplaceRecord(ReplaceMaterialParamDTO dto) throws JsonProcessingException {
+        Assert.isFalse(dto.getList().isEmpty(), "没有确定要维修或更换的物资!");
+        // 因为比较复杂,循环处理
+        for (ReplaceMaterialDTO replaceMaterialDTO : dto.getList()) {
+            Assert.notNull(replaceMaterialDTO.getOldMaterialsId(), "旧物资ID不能为空!");
+            MaterialsDO oldMaterial = materialsService.getById(replaceMaterialDTO.getOldMaterialsId());
+            // 1.查询该物资的最新报异常记录
+            MaterialsCheckRecordDO checkRecord = materialsCheckRecordService.getOne(Wrappers.<MaterialsCheckRecordDO>lambdaQuery()
+                    .eq(MaterialsCheckRecordDO::getMaterialsId, replaceMaterialDTO.getOldMaterialsId())
+                    .eq(MaterialsCheckRecordDO::getStatus, "1")
+                    .orderByDesc(MaterialsCheckRecordDO::getId)
+                    .last("limit 1"));
+            if (checkRecord != null && StringUtils.isNotBlank(checkRecord.getMeasure()) && checkRecord.getMeasure().equals("维修")) {
+                // 如果是维修直接更新物资状态
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, replaceMaterialDTO.getOldMaterialsId())
+                        .set(MaterialsDO::getStatus, "0"));
+                // 生成维修记录
+                MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+                isMaterialsChangeRecord.setOldMaterialsId(replaceMaterialDTO.getOldMaterialsId());
+                isMaterialsChangeRecord.setOldMaterialsRfid(oldMaterial.getMaterialsRfid());
+                isMaterialsChangeRecord.setNewMaterialsId(oldMaterial.getId());
+                isMaterialsChangeRecord.setNewMaterialsRfid(oldMaterial.getMaterialsRfid());
+                isMaterialsChangeRecord.setChangeUserId(getLoginUserId());
+                isMaterialsChangeRecord.setChangeDate(new Date());
+                isMaterialsChangeRecord.setChangeType("0");
+                isMaterialsChangeRecord.setOperateType("3");
+                isMaterialsChangeRecord.setCheckRecordId(checkRecord.getId());
+                materialsChangeRecordService.save(isMaterialsChangeRecord);
+                return true;
+            }
+            // 2.对旧物资进行处理,如果新物资需要使用旧物资的rfid,则把旧物资的rfid清理掉,然后绑定给新物资,最后开柜门拿出旧物资解绑就可以了
+            if (StringUtils.isNotBlank(oldMaterial.getMaterialsRfid()) && oldMaterial.getMaterialsRfid().equals(replaceMaterialDTO.getMaterialsRfid())) {
+                // 2.1该情况属于新物资需要使用旧物资的rfid
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, replaceMaterialDTO.getOldMaterialsId())
+                        .set(MaterialsDO::getMaterialsCabinetId, null)
+                        .set(MaterialsDO::getMaterialsRfid, null));
+            }
+            // 2.2无论是否更换rfid,新物资的数据都要存储到物资清单之中
+            MaterialsDO newMaterial = new MaterialsDO();
+            newMaterial.setMaterialsName(replaceMaterialDTO.getMaterialsName());
+            newMaterial.setMaterialsTypeId(replaceMaterialDTO.getMaterialsTypeId());
+            newMaterial.setMaterialsCabinetId(oldMaterial.getMaterialsCabinetId());
+            newMaterial.setLoanState("0");
+            newMaterial.setMaterialsRfid(replaceMaterialDTO.getMaterialsRfid());
+            newMaterial.setSupplier(oldMaterial.getSupplier());
+            newMaterial.setExpirationDate(replaceMaterialDTO.getExpirationDate());
+            newMaterial.setStatus("0");
+
+            PropertyVO propertyVO = new PropertyVO();
+            propertyVO.setPropertyId(String.valueOf(replaceMaterialDTO.getPropertiesPropertyId()));
+            propertyVO.setPropertyName(replaceMaterialDTO.getPropertiesProperty());
+            propertyVO.setRecordId(String.valueOf(replaceMaterialDTO.getPropertiesValueId()));
+            propertyVO.setValueName(replaceMaterialDTO.getPropertiesValue());
+            // 使用 ObjectMapper 将对象转换为 JSON 字符串
+            ObjectMapper objectMapper = new ObjectMapper();
+            String jsonString = objectMapper.writeValueAsString(propertyVO);
+            newMaterial.setProperties("[" + jsonString + "]");
+            materialsService.save(newMaterial);
+
+            // 3.新增物资更换记录
+            MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+            isMaterialsChangeRecord.setOldMaterialsId(replaceMaterialDTO.getOldMaterialsId());
+            isMaterialsChangeRecord.setOldMaterialsRfid(oldMaterial.getMaterialsRfid());
+            isMaterialsChangeRecord.setNewMaterialsId(newMaterial.getId());
+            isMaterialsChangeRecord.setNewMaterialsRfid(newMaterial.getMaterialsRfid());
+            isMaterialsChangeRecord.setChangeUserId(getLoginUserId());
+            isMaterialsChangeRecord.setChangeDate(new Date());
+            isMaterialsChangeRecord.setChangeType("0");
+            if (checkRecord != null) {
+                isMaterialsChangeRecord.setCheckRecordId(checkRecord.getId());
+            } else {
+                isMaterialsChangeRecord.setCheckRecordId(0L);
+            }
+            materialsChangeRecordService.save(isMaterialsChangeRecord);
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean updateMaterialsReplace(ReplaceMaterialsDTO dto) {
+        Assert.notBlank(dto.getCabinetCode(), "物资柜不能为空!");
+        MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getCabinetCode());
+        // 1.开始解绑
+        if (!dto.getUnbindMaterialRfidList().isEmpty()) {
+            materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                    .in(MaterialsDO::getMaterialsRfid, dto.getUnbindMaterialRfidList())
+                    .set(MaterialsDO::getMaterialsCabinetId, null)
+                    .set(MaterialsDO::getLoanState, "0"));
+        }
+        // 2.开始绑定
+        if (!dto.getBindingMaterialRfidList().isEmpty()) {
+            materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                    .in(MaterialsDO::getMaterialsRfid, dto.getBindingMaterialRfidList())
+                    .set(MaterialsDO::getMaterialsCabinetId, cabinetByCode.getId())
+                    .set(MaterialsDO::getLoanState, "1")
+                    .set(MaterialsDO::getStatus, "0"));
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean insertCabinetOpenTimeout(OpenTimeoutDTO dto) {
+        // Assert.notNull(dto.getLoanFromId(), "物资柜不能为空");
+        if (dto.getLoanFromId() != null) {
+        } else {
+            Assert.notBlank(dto.getLoanFromCode(), "物资柜code不能空!");
+            MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getLoanFromCode());
+            Assert.isTrue(cabinetByCode != null, "物资柜不存在!");
+            dto.setLoanFromId(cabinetByCode.getId());
+        }
+        ExceptionMisplaceDO loanException = new ExceptionMisplaceDO();
+        loanException.setLoanFromId(dto.getLoanFromId());
+        loanException.setRestitutionUserId(getLoginUserId());
+        loanException.setOccurTime(new Date());
+        loanException.setExceptionType("1");
+        exceptionMisplaceService.save(loanException);
+        return true;
+    }
+
+    @Override
+    public Boolean updateCabinetOpenTimeout(OpenTimeoutDTO dto) {
+        // Assert.notNull(dto.getLoanFromId(), "物资柜不能为空");
+        if (dto.getLoanFromId() != null) {
+        } else {
+            Assert.notBlank(dto.getLoanFromCode(), "物资柜code不能空!");
+            MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getLoanFromCode());
+            Assert.isTrue(cabinetByCode != null, "物资柜不存在!");
+            dto.setLoanFromId(cabinetByCode.getId());
+        }
+        exceptionMisplaceService.update(Wrappers.<ExceptionMisplaceDO>lambdaUpdate()
+                .eq(ExceptionMisplaceDO::getLoanFromId, dto.getLoanFromId())
+                .eq(ExceptionMisplaceDO::getExceptionType, "1")
+                .eq(ExceptionMisplaceDO::getStatus, "0")
+                .set(ExceptionMisplaceDO::getStatus, "1")
+                .set(ExceptionMisplaceDO::getHandleTime, new Date()));
+        return true;
+    }
+
+    @Override
+    public Boolean insertCabinetOpenRecord(CabinetOpenRecordDO dto) {
+        // Assert.notNull(dto.getCabinetId(), "物资柜ID不能为空!");
+        if (dto.getCabinetId() != null) {
+        } else {
+            Assert.notBlank(dto.getCabinetCode(), "请告诉我物资柜code!");
+            MaterialsCabinetDO one = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                    .eq(MaterialsCabinetDO::getCabinetCode, dto.getCabinetCode()));
+            Assert.isFalse(one == null, "物资柜信息不存在!");
+            dto.setCabinetId(one.getId());
+        }
+        Assert.notBlank(dto.getOpenType(), "开门类型不可为空!");
+        dto.setOpenTime(new Date());
+        dto.setUserId(String.valueOf(getLoginUserId()));
+        cabinetOpenRecordService.save(dto);
+        return true;
+    }
+
+    @Override
+    public Boolean updateCabinetClose(CabinetOpenRecordDO dto) {
+        // Assert.notNull(dto.getCabinetId(), "物资柜ID不能为空!");
+        if (dto.getCabinetId() != null) {
+        } else {
+            Assert.notBlank(dto.getCabinetCode(), "请告诉我物资柜code!");
+            MaterialsCabinetDO one = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                    .eq(MaterialsCabinetDO::getCabinetCode, dto.getCabinetCode()));
+            Assert.isFalse(one == null, "物资柜信息不存在!");
+            dto.setCabinetId(one.getId());
+        }
+        cabinetOpenRecordService.update(Wrappers.<CabinetOpenRecordDO>lambdaUpdate()
+                .eq(CabinetOpenRecordDO::getCabinetId, dto.getCabinetId())
+                .isNull(CabinetOpenRecordDO::getCloseTime)
+                .set(CabinetOpenRecordDO::getCloseTime, new Date()));
+        // 检查该柜子有没有关门异常,如果有现在解除一下
+        exceptionMisplaceService.update(Wrappers.<ExceptionMisplaceDO>lambdaUpdate()
+                .eq(ExceptionMisplaceDO::getLoanFromId, dto.getCabinetId())
+                .eq(ExceptionMisplaceDO::getExceptionType, "1")
+                .eq(ExceptionMisplaceDO::getStatus, "0")
+                .set(ExceptionMisplaceDO::getStatus, "1")
+                .set(ExceptionMisplaceDO::getHandleTime, new Date()));
+        return true;
+    }
+
+    @Override
+    public List<CabinetMaterialVO> selectMaterialsByCabinetId(Long cabinetId, String cabinetCode) {
+        Assert.isFalse(cabinetId == null && StringUtils.isBlank(cabinetCode), "请告诉我物资柜身份(cabinetId / cabinetCode)!");
+        if (cabinetId != null) {
+        } else {
+            MaterialsCabinetDO one = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                    .eq(MaterialsCabinetDO::getCabinetCode, cabinetCode));
+            Assert.isFalse(one == null, "无法识别" + cabinetCode + "物资柜身份!");
+            cabinetId = one.getId();
+        }
+        // 0.构造返回值
+        ArrayList<CabinetMaterialVO> vo = new ArrayList<>();
+        // 1.查询物资柜下有哪些物资
+        List<MaterialsDO> materials = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinetId));
+        // 1.1如果柜子下有物资,才有继续的必要
+        if (!materials.isEmpty()) {
+            // 4.给物资赋值最新一次借取人员的数据
+            List<MaterialsDO> collect = materials.stream().filter(o -> StringUtils.isNotBlank(o.getLoanState()) && o.getLoanState().equals("0")).collect(Collectors.toList());
+            if (!collect.isEmpty()) {
+                List<Long> collect1 = collect.stream().map(MaterialsDO::getId).collect(Collectors.toList());
+                List<Long> lastLoanRecordIds = materialsLoanService.getLastLoanRecord(collect1);
+                if (!lastLoanRecordIds.isEmpty()) {
+                    List<MaterialsLoanDO> isMaterialsLoans = materialsLoanService.listByIds(lastLoanRecordIds);
+                    for (MaterialsLoanDO isMaterialsLoan : isMaterialsLoans) {
+                        for (MaterialsDO material : materials) {
+                            if (isMaterialsLoan.getMaterialsId().equals(material.getId())) {
+                                material.setLoanUserId(isMaterialsLoan.getLoanUserId());
+                            }
+                        }
+                    }
+                }
+            }
+
+            // 2.找出这些物资有哪些分类,去掉重复的
+            Set<Long> materialsTypeIdSet = materials.stream().map(MaterialsDO::getMaterialsTypeId).filter(materialsTypeId -> materialsTypeId != null).collect(Collectors.toSet());
+            // 2.1查询分类的数据,需要拼接name
+            List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(materialsTypeIdSet);
+            // 2.2如果这个类型有数据才有意义
+            if (!isMaterialsTypes.isEmpty()) {
+                // 3.构造’全部‘数据
+                CabinetMaterialVO sumExMaterialTypeVO = new CabinetMaterialVO();
+                sumExMaterialTypeVO.setMaterialsTypeId(0L);
+                sumExMaterialTypeVO.setMaterialsTypeName("全部");
+                // 承接’全部‘
+                int sumNumber = 0;
+                ArrayList<MaterialsRespVO> isMaterials = new ArrayList<>();
+                // 3.1循环构造返回类
+                for (MaterialsTypeDO isMaterialsType : isMaterialsTypes) {
+                    CabinetMaterialVO cabinetMaterialVO = new CabinetMaterialVO();
+                    cabinetMaterialVO.setMaterialsTypeId(isMaterialsType.getId());
+                    cabinetMaterialVO.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                    // 过滤获取该类型下的异常物资,1表示损坏 2表示过期
+                    List<MaterialsDO> exMaterials = materials.stream().filter(o -> o.getMaterialsTypeId() != null
+                            && isMaterialsType.getId() != null
+                            && o.getMaterialsTypeId().equals(isMaterialsType.getId())).collect(Collectors.toList());
+                    // 解析物资规格
+                    List<MaterialsRespVO> beans = BeanUtils.toBean(exMaterials, MaterialsRespVO.class);
+                    for (MaterialsRespVO record : beans) {
+                        record.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                        record.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                        record.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                    }
+                    cabinetMaterialVO.setNumber(exMaterials.size());
+                    cabinetMaterialVO.setBorrowableNumber((int) exMaterials.stream().filter(o -> o.getStatus().equals("0") && o.getLoanState().equals("1")).count());
+                    cabinetMaterialVO.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                    cabinetMaterialVO.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                    cabinetMaterialVO.setMaterials(beans);
+                    vo.add(cabinetMaterialVO);
+                    // ’全部‘累加
+                    sumNumber = sumNumber + exMaterials.size();
+                    // ’全部‘集合
+                    isMaterials.addAll(beans);
+                }
+                // 3.2将‘全部’的数据补充完整
+                sumExMaterialTypeVO.setNumber(sumNumber);
+                sumExMaterialTypeVO.setMaterials(isMaterials);
+                vo.add(0, sumExMaterialTypeVO);
+            }
+        }
+        return vo;
+    }
+
+    @Override
+    public MaterialsDO selectMaterialByRfid(String rfid) {
+        Assert.notBlank(rfid, "物资RFID不能为空!");
+        MaterialsDO materials = materialsService.getOne(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsRfid, rfid));
+        if (materials != null && materials.getMaterialsTypeId() != null) {
+            MaterialsTypeDO materialsType = materialsTypeService.getById(materials.getMaterialsTypeId());
+            if (materialsType != null) {
+                materials.setMaterialsTypeIcon(materialsType.getMaterialsTypeIcon());
+                materials.setMaterialsTypePicture(materialsType.getMaterialsTypePicture());
+                materials.setPropertyIds(materialsType.getPropertyIds());
+            }
+        }
+        return materials;
+    }
+
+    @Override
+    public List<MaterialsDO> selectMaterialsByRfidList(RfidListDTO dto) {
+        Assert.isFalse(dto.getList().isEmpty(), "物资RFID不能为空!");
+        List<MaterialsDO> materialsList = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .in(MaterialsDO::getMaterialsRfid, dto.getList()));
+        if (!materialsList.isEmpty()) {
+            List<Long> materialsTypeIds = materialsList.stream().map(MaterialsDO::getMaterialsTypeId).distinct().collect(Collectors.toList());
+            if (!materialsTypeIds.isEmpty()) {
+                List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(materialsTypeIds);
+                for (MaterialsDO materials : materialsList) {
+                    for (MaterialsTypeDO materialsType : isMaterialsTypes) {
+                        if (materials.getMaterialsTypeId().equals(materialsType.getId())) {
+                            materials.setMaterialsTypeIcon(materialsType.getMaterialsTypeIcon());
+                            materials.setMaterialsTypePicture(materialsType.getMaterialsTypePicture());
+                            materials.setPropertyIds(materialsType.getPropertyIds());
+                        }
+                    }
+                }
+            }
+        }
+        return materialsList;
+    }
+
+    @Override
+    public CabinetMaterialsVO selectCabinetMaterials(CabinetRfidListDTO dto) {
+        Assert.notBlank(dto.getCabinetCode(), "物资柜子code不能为空!");
+        Assert.isFalse(dto.getList().isEmpty(), "物资中无物资!");
+        MaterialsCabinetDO cabinet = materialsCabinetService.getCabinetByCode(dto.getCabinetCode());
+        Assert.isFalse(cabinet == null, dto.getCabinetCode() + "物资柜code不存在!");
+        List<MaterialsDO> list = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinet.getId())
+                .in(MaterialsDO::getMaterialsRfid, dto.getList()));
+        // 假设都是不属于该柜子的
+        List<String> notCabinetRfidList = dto.getList();
+        // 属于该柜子的rfid
+        List<String> cabinetRfidList = new ArrayList<>();
+        if (!list.isEmpty()) {
+            cabinetRfidList = list.stream().map(MaterialsDO::getMaterialsRfid).collect(Collectors.toList());
+            // 把假设的里面的是属于该柜子的删除掉
+            notCabinetRfidList.removeIf(cabinetRfidList::contains);
+        }
+        CabinetMaterialsVO cabinetMaterialsVO = new CabinetMaterialsVO();
+        cabinetMaterialsVO.setIsMaterialsCabinet(cabinet);
+        cabinetMaterialsVO.setCabinetRfidList(cabinetRfidList);
+        cabinetMaterialsVO.setNotCabinetRfidList(notCabinetRfidList);
+        return cabinetMaterialsVO;
+    }
+
+    @Override
+    public String updateMaterialReceiveReturn(RecRetParamDTO recRetParamDTO) {
+        if (!recRetParamDTO.getList().isEmpty()) {
+            Long userId = getLoginUserId();
+            List<String> failRfidList = new ArrayList<>();
+            for (RecRetMaterialDTO dto : recRetParamDTO.getList()) {
+                // 1.断言判断
+                Assert.notBlank(dto.getMaterialsRfid(), "请告诉我物资的rfid!");
+                Assert.notBlank(dto.getLoanState(), "请告诉我是借出还是归还!");
+                try {
+                    // 1.1 开始查询物资,物资柜传的rfid
+                    MaterialsDO materials = materialsService.getOne(Wrappers.<MaterialsDO>lambdaQuery()
+                            .eq(MaterialsDO::getMaterialsRfid, dto.getMaterialsRfid()));
+                    Assert.isFalse(materials == null, "通过RFID:" + dto.getMaterialsRfid() + "未查询到物资!");
+                    // 如果物资是借出状态,又来借出就报错
+                    if ("0".equals(materials.getLoanState()) && "0".equals(dto.getLoanState())) {
+                        failRfidList.add(dto.getMaterialsRfid() + "物资已经是借出状态,无法再借出!");
+                        Assert.isFalse(true, dto.getMaterialsRfid() + "物资已经是借出状态,无法再借出!");
+                    }
+                    // 如果已经再柜中,又来放入
+                    if ("1".equals(materials.getLoanState()) && "1".equals(dto.getLoanState())) {
+                        failRfidList.add(dto.getMaterialsRfid() + "物资已经是柜中状态,无法再放入!");
+                        Assert.isFalse(true, dto.getMaterialsRfid() + "物资已经是柜中状态,无法再放入!");
+                    }
+                    // 2.开始更新物资状态
+                    materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                            .eq(MaterialsDO::getMaterialsRfid, dto.getMaterialsRfid())
+                            .set(MaterialsDO::getLoanState, dto.getLoanState())
+                            .set(MaterialsDO::getUpdateTime, new Date()));
+                    // 4.开始更新借出表信息
+                    if ("0".equals(dto.getLoanState())) {
+                        // 4.1开始新增借出记录表
+                        AddLoanDTO addMaterialsLoan = new AddLoanDTO();
+                        addMaterialsLoan.setMaterialsId(materials.getId());
+                        addMaterialsLoan.setLoanUserId(userId);
+                        materialsLoanService.createMaterialsLoan(addMaterialsLoan);
+                    } else if ("1".equals(dto.getLoanState())) {
+                        // 1.2 开始查询物资柜子,物资柜传的code
+                        MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                                .eq(MaterialsCabinetDO::getCabinetCode, dto.getRestitutionToCabinetCode()));
+                        Assert.isFalse(cabinet == null, "通过物资柜code:" + dto.getRestitutionToCabinetCode() + "未查询到物资柜信息!");
+                        // 4.2开始更新归还记录表
+                        ReturnLoanDTO returnLoanDTO = new ReturnLoanDTO();
+                        returnLoanDTO.setMaterialsId(materials.getId());
+                        returnLoanDTO.setRestitutionUserId(userId);
+                        returnLoanDTO.setRestitutionToId(cabinet.getId());
+                        materialsLoanService.returnIsMaterialsLoan(returnLoanDTO);
+                    }
+                } catch (Exception e) {
+                    log.error("存在异常的存取数据:{}", e);
+                    failRfidList.add(dto.getMaterialsRfid());
+                }
+            }
+            // 5.检查有没有异常的物资,如果有,则返回提示
+            if (!failRfidList.isEmpty()) {
+                return "以下RFID本次存取失败:" + failRfidList;
+            }
+        }
+        return "true";
+    }
+
+    @Override
+    public List<InstructionVO> getInstructionsList() {
+        // 1.获取所有使用说明
+        List<MaterialsInstructionsDO> instructions = materialsInstructionsService.list();
+        ArrayList<InstructionVO> instructionVOS = new ArrayList<>();
+        ArrayList<MaterialsInstructionsDO> isMaterialsInstructions = new ArrayList<>();
+        int allSum = 0;
+        if (!instructions.isEmpty()) {
+            // 2.有值才有意义,获取所属的物资类型
+            List<Long> typeIds = instructions.stream().map(MaterialsInstructionsDO::getMaterialsTypeId).distinct().collect(Collectors.toList());
+            if (!typeIds.isEmpty()) {
+                // 3.查询物资分类数据
+                List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(typeIds);
+                if (!isMaterialsTypes.isEmpty()) {
+                    for (MaterialsTypeDO isMaterialsType : isMaterialsTypes) {
+                        InstructionVO instructionVO = new InstructionVO();
+                        instructionVO.setMaterialsTypeId(isMaterialsType.getId());
+                        instructionVO.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                        instructionVO.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                        instructionVO.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                        List<MaterialsInstructionsDO> instructionsList = instructions.stream().filter(o -> o.getMaterialsTypeId().equals(isMaterialsType.getId())).collect(Collectors.toList());
+                        instructionVO.setInstructions(instructionsList);
+                        instructionVO.setNumber(instructionsList.size());
+                        allSum = allSum + instructionsList.size();
+                        instructionVOS.add(instructionVO);
+                        isMaterialsInstructions.addAll(instructionsList);
+                    }
+                }
+            }
+        }
+        InstructionVO instructionVOAll = new InstructionVO();
+        instructionVOAll.setMaterialsTypeId(0L);
+        instructionVOAll.setMaterialsTypeName("全部");
+        instructionVOAll.setInstructions(isMaterialsInstructions);
+        instructionVOAll.setNumber(allSum);
+        instructionVOS.add(0, instructionVOAll);
+        return instructionVOS;
+    }
+
+    @Override
+    public CabinetCheckVO getLastCheckPlanByCabinetCode(String cabinetCode) {
+        Assert.notBlank(cabinetCode, "请告诉我这是哪台物资柜!");
+        // 1.获取物资柜信息
+        MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                .eq(MaterialsCabinetDO::getCabinetCode, cabinetCode)
+                .orderByDesc(MaterialsCabinetDO::getId)
+                .last("limit 1"));
+        Assert.isFalse(cabinet == null, "物资柜信息不存在!");
+        // 2.获取用户信息
+        Long userId = getLoginUserId();
+        // 3.获取这个物资柜当前最近一次未完成的检查计划
+        MaterialsPlanCabinetDO planCabinet = materialsPlanCabinetService.getOne(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinet.getId())
+                .eq(MaterialsPlanCabinetDO::getCheckUserId, userId)
+                .ne(MaterialsPlanCabinetDO::getStatus, "1")
+                .orderByDesc(MaterialsPlanCabinetDO::getPlanId)
+                .last("limit 1"));
+        Assert.isFalse(planCabinet == null, "该物资柜当前无您的检查计划!");
+        // 3.1检查当前登陆人的账号是否有检查计划
+        MaterialsCheckPlanDO checkPlan = materialsCheckPlanService.getOne(Wrappers.<MaterialsCheckPlanDO>lambdaQuery()
+                .eq(MaterialsCheckPlanDO::getId, planCabinet.getPlanId())
+                .eq(MaterialsCheckPlanDO::getCheckUserId, userId));
+        Assert.isFalse(checkPlan == null, "当前物资柜无需您执行的检查计划!");
+        // 3.2查询此次检查记录
+        List<MaterialsCheckRecordDO> checkRecords = materialsCheckRecordService.list(Wrappers.<MaterialsCheckRecordDO>lambdaQuery()
+                .eq(MaterialsCheckRecordDO::getPlanId, planCabinet.getPlanId()));
+        List<Long> checkMaterialsIds = null;
+        if (!checkRecords.isEmpty()) {
+            checkMaterialsIds = checkRecords.stream().map(MaterialsCheckRecordDO::getMaterialsId).collect(Collectors.toList());
+
+        }
+        // 4.确实都存在,那就开始查数据了
+        // 4.1 开始更新这个检查计划的状态,分为总状态和该物资柜的状态
+        // updateCheckPlanStatus(planCabinet, checkPlan);
+        // 4.2查询该物资柜的所有物资
+        List<MaterialsDO> materials = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .in(checkMaterialsIds != null && !checkMaterialsIds.isEmpty(), MaterialsDO::getId, checkMaterialsIds)
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinet.getId())
+        );
+        List<MaterialsCheckVO> materialsCheckVOS = new ArrayList<>();
+        if (!materials.isEmpty()) {
+            List<Long> typeIds = materials.stream().map(MaterialsDO::getMaterialsTypeId).distinct().collect(Collectors.toList());
+            if (!typeIds.isEmpty()) {
+                List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(typeIds);
+                if (!isMaterialsTypes.isEmpty()) {
+                    for (MaterialsTypeDO isMaterialsType : isMaterialsTypes) {
+                        // 该分类下所有的物资
+                        List<MaterialsDO> allMaterials = materials.stream().filter(o -> o.getMaterialsTypeId() != null && o.getMaterialsTypeId().equals(isMaterialsType.getId())).toList();
+                        // 该分类下借出数量
+                        int loanNumber = (int) allMaterials.stream().filter(o -> "0".equals(o.getLoanState())).count();
+                        // 该分类下待检数量
+                        int checkNumber = 0;
+                        // 该分类下正常数量
+                        Integer normalNumber = null;
+                        // 该分类下过期数量
+                        Integer timeoutNumber = null;
+                        // 该分类下损坏数量
+                        Integer badNumber = null;
+                        // --获取所有在柜子里的,在柜子需要检查
+                        List<MaterialsDO> checkMaterials = allMaterials.stream().filter(o -> "1".equals(o.getLoanState())).collect(Collectors.toList());
+                        // --查询已经检测的
+                        if (!checkMaterials.isEmpty()) {
+                            List<Long> checkMaterialIds = checkMaterials.stream().map(MaterialsDO::getId).collect(Collectors.toList());
+                            List<MaterialsCheckRecordDO> checkedMaterials = materialsCheckRecordService.list(Wrappers.<MaterialsCheckRecordDO>lambdaQuery()
+                                    .eq(MaterialsCheckRecordDO::getCabinetId, cabinet.getId())
+                                    .eq(MaterialsCheckRecordDO::getPlanId, checkPlan.getId())
+                                    .isNotNull(MaterialsCheckRecordDO::getStatus)
+                                    .ne(MaterialsCheckRecordDO::getStatus, "")
+                                    .in(MaterialsCheckRecordDO::getMaterialsId, checkMaterialIds));
+                            int checkedNumber = checkedMaterials.isEmpty() ? 0 : checkedMaterials.size();
+                            // --所有的在柜子中的物资 - 这些物资已经在这次计划中检查过的
+                            checkNumber = checkMaterials.size() - checkedNumber;
+                            // 该分类下正常数量
+                            normalNumber = (int) checkedMaterials.stream().filter(o -> "0".equals(o.getStatus())).count();
+                            // 该分类下过期数量
+                            timeoutNumber = (int) checkedMaterials.stream().filter(o -> "1".equals(o.getStatus()) && "2".equals(o.getReason())).count();
+                            // 该分类下损坏数量
+                            badNumber = (int) checkedMaterials.stream().filter(o -> "1".equals(o.getStatus()) && "1".equals(o.getReason())).count();
+                        }
+                        MaterialsCheckVO materialsCheckVO = new MaterialsCheckVO();
+                        materialsCheckVO.setMaterialsTypeId(isMaterialsType.getId());
+                        materialsCheckVO.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                        materialsCheckVO.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                        materialsCheckVO.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                        materialsCheckVO.setAllNumber(allMaterials.size());
+                        materialsCheckVO.setLoanNumber(loanNumber);
+                        materialsCheckVO.setCheckNumber(checkNumber);
+                        materialsCheckVO.setNormalNumber(normalNumber);
+                        materialsCheckVO.setTimeoutNumber(timeoutNumber);
+                        materialsCheckVO.setBadNumber(badNumber);
+                        materialsCheckVOS.add(materialsCheckVO);
+                    }
+                }
+            }
+        }
+        CabinetCheckVO cabinetCheckVO = new CabinetCheckVO();
+        cabinetCheckVO.setPlanId(checkPlan.getId());
+        cabinetCheckVO.setPlanName(checkPlan.getPlanName());
+        cabinetCheckVO.setPlanDate(checkPlan.getPlanDate());
+        cabinetCheckVO.setStatus(checkPlan.getStatus());
+        cabinetCheckVO.setSignatureTime(planCabinet.getSignatureTime());
+        cabinetCheckVO.setSignatureImg(planCabinet.getSignatureImg());
+        cabinetCheckVO.setList(materialsCheckVOS);
+        return cabinetCheckVO;
+    }
+
+    private Boolean updateCheckPlanStatus(MaterialsPlanCabinetDO planCabinet, MaterialsCheckPlanDO checkPlan) {
+        // 1.如果柜子的检查状态是未开始,则更新成进行中
+        if (checkPlan.getStatus().equals(0)) {
+            materialsCheckPlanService.update(Wrappers.<MaterialsCheckPlanDO>lambdaUpdate()
+                    .eq(MaterialsCheckPlanDO::getId, checkPlan.getId())
+                    .set(MaterialsCheckPlanDO::getStatus, "2"));
+            if (planCabinet.getStatus().equals("0")) {
+                materialsPlanCabinetService.update(Wrappers.<MaterialsPlanCabinetDO>lambdaUpdate()
+                        .eq(MaterialsPlanCabinetDO::getPlanId, planCabinet.getPlanId())
+                        .eq(MaterialsPlanCabinetDO::getCabinetId, planCabinet.getCabinetId())
+                        .set(MaterialsPlanCabinetDO::getStatus, "2"));
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public CabinetHomePageVO getCabinetHomePage(String cabinetCode) {
+        Assert.notBlank(cabinetCode, "请告诉我这是哪台物资柜!");
+        // 1.获取物资柜信息
+        MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                .eq(MaterialsCabinetDO::getCabinetCode, cabinetCode)
+                .orderByDesc(MaterialsCabinetDO::getId)
+                .last("limit 1"));
+        Assert.isFalse(cabinet == null, "物资柜信息不存在!");
+        // 1.1柜子中的物资信息
+        List<MaterialsDO> isMaterials = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinet.getId()));
+        // 2.获取用户信息
+        Long userId = getLoginUserId();
+        // 3.获取本人在该物资柜子上有效取还数据
+        Integer rarNumber = null;
+        if (isMaterials.isEmpty()) {
+            rarNumber = 0;
+        } else {
+            List<Long> materialsIds = isMaterials.stream()
+                    .filter(o -> StringUtils.isNotBlank(o.getLoanState()) && o.getLoanState().equals("0"))
+                    .map(MaterialsDO::getId).collect(Collectors.toList());
+            if (!materialsIds.isEmpty()) {
+                List<MaterialsLoanDO> loanList = materialsLoanService.list(Wrappers.<MaterialsLoanDO>lambdaQuery()
+                        .in(MaterialsLoanDO::getMaterialsId, materialsIds)
+                        .eq(MaterialsLoanDO::getLoanFromId, cabinet.getId())
+                        .eq(MaterialsLoanDO::getLoanUserId, userId)
+                        .ne(MaterialsLoanDO::getStatus, "1"));
+                if (!loanList.isEmpty()) {
+                    rarNumber = loanList.size();
+                }
+            }
+        }
+        // 4.获取该物资柜的需要更换数量,在柜子里,损坏或者过期
+        int changeNumber = (int) isMaterials.stream().filter(o ->
+                StringUtils.isNotBlank(o.getLoanState()) && StringUtils.isNotBlank(o.getStatus()) && (o.getStatus().equals("1") || o.getStatus().equals("2"))
+        ).count();
+        // 5.获取本人在该物资柜上未完成的检查计划
+        Integer checkNumber = null;
+        /*List<IsMaterialsPlanCabinet> planCabinets = materialsPlanCabinetService.list(Wrappers.<IsMaterialsPlanCabinet>lambdaQuery()
+                .eq(IsMaterialsPlanCabinet::getCabinetId, cabinet.getCabinetId())
+                .isNull(IsMaterialsPlanCabinet::getSignatureImg)
+                .isNull(IsMaterialsPlanCabinet::getSignatureTime));
+        if (!planCabinets.isEmpty()) {
+            List<Long> planIds = planCabinets.stream().map(IsMaterialsPlanCabinet::getPlanId).distinct().collect(Collectors.toList());
+            List<IsMaterialsCheckPlan> myCheckPlans = materialsCheckPlanService.list(Wrappers.<IsMaterialsCheckPlan>lambdaQuery()
+                    .eq(IsMaterialsCheckPlan::getCheckUserId, userId)
+                    .in(IsMaterialsCheckPlan::getPlanId, planIds)
+                    .eq(IsMaterialsCheckPlan::getStatus, "0"));
+            if (!myCheckPlans.isEmpty()) {
+                checkNumber = myCheckPlans.size();
+            }
+        }*/
+        List<MaterialsPlanCabinetDO> myNotFinishPlans = materialsPlanCabinetService.list(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getCheckUserId, userId)
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinet.getId())
+                .ne(MaterialsPlanCabinetDO::getSubmit, "1")
+                .ne(MaterialsPlanCabinetDO::getStatus, "1"));
+        if (!myNotFinishPlans.isEmpty()) {
+            checkNumber = 1;
+        }
+        // 6.获取物资分类下的可借数据
+        List<MaterialsHomeVO> materialsHomeVOS = new ArrayList<>();
+        List<MaterialsDO> materials = materialsService.list(Wrappers.<MaterialsDO>lambdaQuery()
+                .eq(MaterialsDO::getMaterialsCabinetId, cabinet.getId()));
+        if (!materials.isEmpty()) {
+            List<Long> typeIds = materials.stream().map(MaterialsDO::getMaterialsTypeId).distinct().collect(Collectors.toList());
+            if (!typeIds.isEmpty()) {
+                List<MaterialsTypeDO> isMaterialsTypes = materialsTypeService.listByIds(typeIds);
+                if (!isMaterialsTypes.isEmpty()) {
+                    for (MaterialsTypeDO isMaterialsType : isMaterialsTypes) {
+                        MaterialsHomeVO materialsHomeVO = new MaterialsHomeVO();
+                        materialsHomeVO.setMaterialsTypeId(isMaterialsType.getId());
+                        materialsHomeVO.setMaterialsTypeName(isMaterialsType.getMaterialsTypeName());
+                        materialsHomeVO.setMaterialsTypeIcon(isMaterialsType.getMaterialsTypeIcon());
+                        materialsHomeVO.setMaterialsTypePicture(isMaterialsType.getMaterialsTypePicture());
+                        List<MaterialsDO> allMaterials = materials.stream().filter(o -> o.getMaterialsTypeId() != null && o.getMaterialsTypeId().equals(isMaterialsType.getId())).toList();
+                        materialsHomeVO.setAllNumber(allMaterials.size());
+                        int borrowableNumber = (int) allMaterials.stream().filter(o -> "1".equals(o.getLoanState()) && "0".equals(o.getStatus())).count();
+                        materialsHomeVO.setBorrowableNumber(borrowableNumber);
+                        materialsHomeVOS.add(materialsHomeVO);
+                    }
+                }
+            }
+        }
+        CabinetHomePageVO cabinetHomePageVO = new CabinetHomePageVO();
+        cabinetHomePageVO.setRarNumber(rarNumber);
+        cabinetHomePageVO.setCheckNumber(checkNumber);
+        cabinetHomePageVO.setChangeNumber(changeNumber);
+        cabinetHomePageVO.setList(materialsHomeVOS);
+        return cabinetHomePageVO;
+    }
+
+    @Override
+    public MaterialsCheckInitVO getCheckMaterialsByCabinetCode(String cabinetCode, Long planId) {
+        Assert.notBlank(cabinetCode, "cabinetCode不能为空!");
+        Assert.notNull(planId, "检查计划planId不能为空!");
+        MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                .eq(MaterialsCabinetDO::getCabinetCode, cabinetCode));
+        Assert.isFalse(cabinet == null, "物资柜信息不存在!");
+        MaterialsCheckInitVO materialsCheckInitVO = new MaterialsCheckInitVO();
+        // 检查此次数据是否初始化,初始化了,就不用生成直接查
+        List<MaterialsCheckRecordDO> checkRecords = materialsCheckRecordService.getCheckMaterialsByCabinetCode(planId, cabinet.getId());
+        ArrayList<MaterialsCheckRecordDO> checkRecordArrayList = new ArrayList<>();
+        List<CheckMaterialsDateVO> vos = materialsService.getCheckMaterialsByCabinetId(cabinet.getId());
+        if (!checkRecords.isEmpty()) {
+            materialsCheckInitVO.setList(checkRecords);
+        } else {
+            for (CheckMaterialsDateVO vo : vos) {
+                MaterialsCheckRecordDO checkRecord = new MaterialsCheckRecordDO();
+                checkRecord.setPlanId(planId);
+                checkRecord.setCabinetId(cabinet.getId());
+                checkRecord.setMaterialsId(vo.getMaterialsId());
+                checkRecord.setCheckUserId(getLoginUserId());
+                checkRecord.setCheckDate(new Date());
+                checkRecord.setMaterialsRfid(vo.getMaterialsRfid());
+                checkRecord.setMaterialsTypeIcon(vo.getMaterialsTypeIcon());
+                checkRecord.setMaterialsTypePicture(vo.getMaterialsTypePicture());
+                checkRecord.setMaterialsTypeName(vo.getMaterialsTypeName());
+                checkRecord.setMaterialsName(vo.getMaterialsName());
+                checkRecordArrayList.add(checkRecord);
+                materialsCheckRecordService.save(checkRecord);
+            }
+            materialsCheckInitVO.setList(checkRecordArrayList);
+        }
+
+        // 查询物资检查标准
+        Set<CheckStandardVO> sets = new HashSet<>();
+        for (CheckMaterialsDateVO vo : vos) {
+            CheckStandardVO checkStandardVO = new CheckStandardVO();
+            checkStandardVO.setMaterialsTypeId(vo.getMaterialsTypeId());
+            checkStandardVO.setMaterialsTypeName(vo.getMaterialsTypeName());
+            checkStandardVO.setMaterialsTypeIcon(vo.getMaterialsTypeIcon());
+            checkStandardVO.setMaterialsTypePicture(vo.getMaterialsTypePicture());
+            checkStandardVO.setCheckStandard(vo.getCheckStandard());
+            sets.add(checkStandardVO);
+        }
+        materialsCheckInitVO.setStandards(new ArrayList<>(sets));
+        // 获取下方检查统计
+        CheckProgressVO checkProgressVO = new CheckProgressVO();
+        checkProgressVO.setCheckNum(0);
+        checkProgressVO.setNormalNum(0);
+        checkProgressVO.setTimeOutNum(0);
+        checkProgressVO.setBadNum(0);
+        if (checkRecords.isEmpty()) {
+            checkProgressVO.setCheckNum(materialsCheckInitVO.getList().size());
+        } else {
+            int checkNum = (int) checkRecords.stream().filter(o -> StringUtils.isBlank(o.getStatus())).count();
+            int normalNum = (int) checkRecords.stream().filter(o -> StringUtils.isNotBlank(o.getStatus()) && "0".equals(o.getStatus())).count();
+            int timeOutNum = (int) checkRecords.stream().filter(o -> StringUtils.isNotBlank(o.getStatus()) && "1".equals(o.getStatus())
+                    && "2".equals(o.getReason())).count();
+            int badNum = (int) checkRecords.stream().filter(o -> StringUtils.isNotBlank(o.getStatus()) && "1".equals(o.getStatus())
+                    && "1".equals(o.getReason())).count();
+            checkProgressVO.setCheckNum(checkNum);
+            checkProgressVO.setNormalNum(normalNum);
+            checkProgressVO.setTimeOutNum(timeOutNum);
+            checkProgressVO.setBadNum(badNum);
+        }
+        materialsCheckInitVO.setCheckProgressVO(checkProgressVO);
+        return materialsCheckInitVO;
+    }
+
+    @Override
+    public Boolean insertCheckRecord(CheckParamDTO dto) {
+        if (!dto.getList().isEmpty()) {
+            Long userId = getLoginUserId();
+            // 0.检查是否已经提交,如果已经提交则不允许再次提交
+            List<Long> cabinetIds = dto.getList().stream().map(MaterialsCheckRecordDO::getCabinetId).distinct().collect(Collectors.toList());
+            Assert.isFalse(cabinetIds.isEmpty(), "物资柜不能为空!");
+            Assert.notNull(dto.getList().get(0).getPlanId(), "检查计划ID不能为空!");
+            List<MaterialsPlanCabinetDO> list1 = materialsPlanCabinetService.list(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                    .eq(MaterialsPlanCabinetDO::getPlanId, dto.getList().get(0).getPlanId())
+                    .in(MaterialsPlanCabinetDO::getCabinetId, cabinetIds)
+                    .eq(MaterialsPlanCabinetDO::getSubmit, "1"));
+            Assert.isTrue(list1.isEmpty(), "存在重复提交检查记录,请检查!");
+
+            for (MaterialsCheckRecordDO isMaterialsCheckRecord : dto.getList()) {
+                Assert.notNull(isMaterialsCheckRecord.getId(), "记录id不能为空!");
+                isMaterialsCheckRecord.setCheckDate(new Date());
+                isMaterialsCheckRecord.setCheckUserId(userId);
+                materialsCheckRecordService.updateById(isMaterialsCheckRecord);
+            }
+        }
+        return true;
+    }
+
+    @Transactional
+    @Override
+    public Boolean insertSubmitPlan(SubmitPlanDTO dto) {
+        Assert.notNull(dto.getPlanId(), "计划id不能空!");
+        Assert.notBlank(dto.getCabinetCode(), "物资柜code不能为空!");
+        MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getCabinetCode());
+        Assert.isFalse(cabinetByCode == null, "物资柜信息不存在!");
+        // 1.检查初始化的物资检查数据有没有检查完毕
+        List<MaterialsCheckRecordDO> list = materialsCheckRecordService.list(Wrappers.<MaterialsCheckRecordDO>lambdaQuery()
+                .eq(MaterialsCheckRecordDO::getCabinetId, cabinetByCode.getId())
+                .eq(MaterialsCheckRecordDO::getPlanId, dto.getPlanId()));
+        Assert.isFalse(list.isEmpty(), "暂无检查数据需要提交!");
+        List<MaterialsCheckRecordDO> collect = list.stream().filter(o -> o.getStatus() == null || StringUtils.isBlank(o.getStatus())).collect(Collectors.toList());
+        Assert.isTrue(collect.isEmpty(), "存在未检查的物资,请重新盘查!");
+        // 2.检查签名是否上传
+        MaterialsPlanCabinetDO one = materialsPlanCabinetService.getOne(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinetByCode.getId())
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId()));
+        Assert.notBlank(one.getSignatureImg(), "您的签名暂未上传,不可提交!");
+        // 3.都完事了,开始更新物资的状态,该物资柜的提交状态,物资计划的状态
+        for (MaterialsCheckRecordDO checkRecord : list) {
+            // 3.1.开始更新物资本身状态
+            if ("1".equals(checkRecord.getStatus()) && StringUtils.isNotBlank(checkRecord.getReason())) {
+                //  reason字典值exceptions_status 对应调整material_info_status  损坏和过期时对应的,所以直接set
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, checkRecord.getMaterialsId())
+                        .set(MaterialsDO::getStatus, checkRecord.getReason()));
+            } else {
+                materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                        .eq(MaterialsDO::getId, checkRecord.getMaterialsId())
+                        .set(MaterialsDO::getStatus, "0"));
+            }
+        }
+        // 4.提交该物资柜的提交状态
+        materialsPlanCabinetService.update(Wrappers.<MaterialsPlanCabinetDO>lambdaUpdate()
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinetByCode.getId())
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId())
+                .set(MaterialsPlanCabinetDO::getSubmit, "1")
+                .set(MaterialsPlanCabinetDO::getStatus, "1")
+        );
+        // 5.检查此次计划所有的物资柜是不是都提交了,如果都提交了,则可以直接更新计划完成
+        List<MaterialsPlanCabinetDO> list1 = materialsPlanCabinetService.list(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId())
+                .ne(MaterialsPlanCabinetDO::getStatus, "1"));
+        if (list1.isEmpty()) {
+            materialsCheckPlanService.update(Wrappers.<MaterialsCheckPlanDO>lambdaUpdate()
+                    .eq(MaterialsCheckPlanDO::getId, dto.getPlanId())
+                    .set(MaterialsCheckPlanDO::getStatus, "1"));
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean insertSign(SignDTO dto) {
+        Assert.notBlank(dto.getCabinetCode(), "物资柜code不能为空!");
+        Assert.notNull(dto.getPlanId(), "计划id不能为空!");
+        Assert.notBlank(dto.getSignatureImg(), "签名不能为空!");
+        MaterialsCabinetDO cabinet = materialsCabinetService.getOne(Wrappers.<MaterialsCabinetDO>lambdaQuery()
+                .eq(MaterialsCabinetDO::getCabinetCode, dto.getCabinetCode()));
+        Assert.isFalse(cabinet == null, "物资柜信息不存在!");
+        /*MaterialsPlanCabinetDO one = materialsPlanCabinetService.getOne(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId())
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinet.getCabinetId()));
+        Assert.isFalse(StringUtils.isNoneBlank(one.getSignatureImg()), "您已签名,请勿重复!");*/
+        materialsPlanCabinetService.update(Wrappers.<MaterialsPlanCabinetDO>lambdaUpdate()
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId())
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinet.getId())
+                .set(MaterialsPlanCabinetDO::getSignatureImg, dto.getSignatureImg())
+                .set(MaterialsPlanCabinetDO::getSignatureTime, new Date()));
+        return true;
+    }
+
+    @Override
+    public AutoReplaceReportVO insertAutoChange(AutoChangeDTO dto) {
+        Assert.notBlank(dto.getCabinetCode(), "物资柜CODE不能为空!");
+        MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getCabinetCode());
+        // 0.构造记录的集合
+        List<MaterialsChangeRecordDO> isMaterialsChangeRecords = new ArrayList<>();
+        Long userId = getLoginUserId();
+        Date date = new Date();
+        List<MaterialsDO> unbingdingList = new ArrayList<>();
+        List<MaterialsDO> bingdingList = new ArrayList<>();
+        // 1.开始解绑
+        if (!dto.getUnbindMaterialRfidList().isEmpty()) {
+            materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                    .in(MaterialsDO::getMaterialsRfid, dto.getUnbindMaterialRfidList())
+                    .set(MaterialsDO::getMaterialsCabinetId, null)
+                    .set(MaterialsDO::getLoanState, "0"));
+            unbingdingList = materialsService.getMaterialListByRfid(dto.getUnbindMaterialRfidList());
+            for (MaterialsDO materials : unbingdingList) {
+                MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+                isMaterialsChangeRecord.setOldMaterialsId(materials.getId());
+                isMaterialsChangeRecord.setOldMaterialsRfid(materials.getMaterialsRfid());
+                isMaterialsChangeRecord.setChangeUserId(userId);
+                isMaterialsChangeRecord.setChangeDate(date);
+                isMaterialsChangeRecord.setChangeType("1");
+                isMaterialsChangeRecord.setOperateType("0");
+                isMaterialsChangeRecords.add(isMaterialsChangeRecord);
+            }
+        }
+        // 2.开始绑定
+        if (!dto.getBindingMaterialRfidList().isEmpty()) {
+            // 判定绑定的物资数据是否存在,存在的话是不是异常的数据
+            materialsService.update(Wrappers.<MaterialsDO>lambdaUpdate()
+                    .in(MaterialsDO::getMaterialsRfid, dto.getBindingMaterialRfidList())
+                    .set(MaterialsDO::getMaterialsCabinetId, cabinetByCode.getId())
+                    .set(MaterialsDO::getLoanState, "1"));
+                    // .set(IsMaterials::getStatus, "0"));
+            bingdingList = materialsService.getMaterialListByRfid(dto.getBindingMaterialRfidList());
+            // Assert.isFalse(bingdingList.size() != dto.getBindingMaterialRfidList().size(), "缺邵需要绑定的物资");
+            for (MaterialsDO materials : bingdingList) {
+                Assert.isTrue(materials.getStatus().equals("0"), "存在异常的替换物资!");
+                MaterialsChangeRecordDO isMaterialsChangeRecord = new MaterialsChangeRecordDO();
+                isMaterialsChangeRecord.setNewMaterialsId(materials.getId());
+                isMaterialsChangeRecord.setNewMaterialsRfid(materials.getMaterialsRfid());
+                isMaterialsChangeRecord.setChangeUserId(userId);
+                isMaterialsChangeRecord.setChangeDate(date);
+                isMaterialsChangeRecord.setChangeType("1");
+                isMaterialsChangeRecord.setOperateType("1");
+                isMaterialsChangeRecords.add(isMaterialsChangeRecord);
+                // 处理绑定入柜的物资的借取记录
+                materialsLoanService.update(Wrappers.<MaterialsLoanDO>lambdaUpdate()
+                        .eq(MaterialsLoanDO::getMaterialsId, materials.getId())
+                        .set(MaterialsLoanDO::getRestitutionUserId, getLoginUserId())
+                        .set(MaterialsLoanDO::getActualRestitutionTime, new Date())
+                        .set(MaterialsLoanDO::getStatus, "1"));
+                // 处理归还异常
+                exceptionMisplaceService.update(Wrappers.<ExceptionMisplaceDO>lambdaUpdate()
+                        .eq(ExceptionMisplaceDO::getMaterialsId, materials.getId())
+                        .set(ExceptionMisplaceDO::getRestitutionUserId, getLoginUserId())
+                        .set(ExceptionMisplaceDO::getHandleTime, new Date())
+                        .set(ExceptionMisplaceDO::getStatus, "1"));
+            }
+        }
+        // 3.如果有数据则插入
+        if (!isMaterialsChangeRecords.isEmpty()) {
+            materialsChangeRecordService.saveBatch(isMaterialsChangeRecords);
+        }
+        // 4.开始整理此次的总结
+        AutoReplaceReportVO autoReplaceReportVO = new AutoReplaceReportVO();
+        autoReplaceReportVO.setCreateTime(date);
+        autoReplaceReportVO.setNikeName(getLoginUserNickname());
+        // 4.1放入物资
+        List<AutoReplaceMaterialVO> bindingMaterialVOS = new ArrayList<>();
+        if (!bingdingList.isEmpty()) {
+            for (MaterialsDO materials : bingdingList) {
+                AutoReplaceMaterialVO autoReplaceMaterialVO = new AutoReplaceMaterialVO();
+                autoReplaceMaterialVO.setMaterialsName(materials.getMaterialsName());
+                autoReplaceMaterialVO.setMaterialsTypeIcon(materials.getMaterialsTypeIcon());
+                autoReplaceMaterialVO.setMaterialsTypePicture(materials.getMaterialsTypePicture());
+                autoReplaceMaterialVO.setMaterialsRfid(materials.getMaterialsRfid());
+                autoReplaceMaterialVO.setStatus(materials.getStatus());
+                bindingMaterialVOS.add(autoReplaceMaterialVO);
+            }
+        }
+        autoReplaceReportVO.setBindingList(bindingMaterialVOS);
+        // 4.2取出物资
+        List<AutoReplaceMaterialVO> unbindingMaterialVOS = new ArrayList<>();
+        if (!unbingdingList.isEmpty()) {
+            for (MaterialsDO materials : unbingdingList) {
+                AutoReplaceMaterialVO autoReplaceMaterialVO = new AutoReplaceMaterialVO();
+                autoReplaceMaterialVO.setMaterialsName(materials.getMaterialsName());
+                autoReplaceMaterialVO.setMaterialsTypeIcon(materials.getMaterialsTypeIcon());
+                autoReplaceMaterialVO.setMaterialsTypePicture(materials.getMaterialsTypePicture());
+                autoReplaceMaterialVO.setMaterialsRfid(materials.getMaterialsRfid());
+                autoReplaceMaterialVO.setStatus(materials.getStatus());
+                unbindingMaterialVOS.add(autoReplaceMaterialVO);
+            }
+        }
+        autoReplaceReportVO.setUnbindingList(unbindingMaterialVOS);
+        // 更新检查记录
+        materialsPlanCabinetService.autoChangeCheckRecord(dto.getCabinetCode());
+        return autoReplaceReportVO;
+    }
+
+    @Override
+    public Boolean startCheckPlan(StartCheckPlanDTO dto) {
+        Assert.notNull(dto.getPlanId(), "planId不可为空!");
+        Assert.notBlank(dto.getCabinetCode(), "物资柜code不可为空!");
+        MaterialsCabinetDO cabinetByCode = materialsCabinetService.getCabinetByCode(dto.getCabinetCode());
+        Assert.isTrue(cabinetByCode != null, dto.getCabinetCode() + "物资柜不存在!");
+        MaterialsCheckPlanDO checkPlan = materialsCheckPlanService.getOne(Wrappers.<MaterialsCheckPlanDO>lambdaQuery()
+                .eq(MaterialsCheckPlanDO::getId, dto.getPlanId()));
+        MaterialsPlanCabinetDO planCabinet = materialsPlanCabinetService.getOne(Wrappers.<MaterialsPlanCabinetDO>lambdaQuery()
+                .eq(MaterialsPlanCabinetDO::getPlanId, dto.getPlanId())
+                .eq(MaterialsPlanCabinetDO::getCabinetId, cabinetByCode.getId()));
+
+        // 1.如果柜子的检查状态是未开始,则更新成进行中
+        if (checkPlan.getStatus().equals(0)) {
+            materialsCheckPlanService.update(Wrappers.<MaterialsCheckPlanDO>lambdaUpdate()
+                    .eq(MaterialsCheckPlanDO::getId, checkPlan.getId())
+                    .set(MaterialsCheckPlanDO::getStatus, "2"));
+            if (planCabinet.getStatus().equals("0")) {
+                materialsPlanCabinetService.update(Wrappers.<MaterialsPlanCabinetDO>lambdaUpdate()
+                        .eq(MaterialsPlanCabinetDO::getPlanId, planCabinet.getPlanId())
+                        .eq(MaterialsPlanCabinetDO::getCabinetId, planCabinet.getCabinetId())
+                        .set(MaterialsPlanCabinetDO::getStatus, "2"));
+            }
+        }
+        return true;
+    }
+}

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.