Kaynağa Gözat

新增锁控机柜api

车车 2 ay önce
ebeveyn
işleme
3097202b5a
56 değiştirilmiş dosya ile 2661 ekleme ve 19 silme
  1. 146 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/hardwareapi/HardwareApiController.java
  2. 94 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketDetailVO.java
  3. 84 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketPointsRespVO.java
  4. 4 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/controller/admin/jobticket/vo/JobTicketRespVO.java
  5. 8 9
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dataobject/jobticket/JobTicketLocksetDO.java
  6. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/ExDTO.java
  7. 30 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsJobCardExDTO.java
  8. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsKeyExDTO.java
  9. 31 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockCabinetSlotsExDTO.java
  10. 29 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/exUpdate/IsLockExDTO.java
  11. 26 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/CoincidePointToUnLockDTO.java
  12. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LPBParamDTO.java
  13. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LTParamDTO.java
  14. 38 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanMaterialDTO.java
  15. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LoanParamDTO.java
  16. 33 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointBatchDTO.java
  17. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LockPointDTO.java
  18. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/LocksetPointDTO.java
  19. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ParamDTO.java
  20. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnKeyDTO.java
  21. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnLocksetDTO.java
  22. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/ReturnTicketLockDTO.java
  23. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeLocksetDTO.java
  24. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeOutKeyDTO.java
  25. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/TakeTicketLockDTO.java
  26. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateColockerStatusDTO.java
  27. 27 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateKeyStatusDTO.java
  28. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateSwitchParam.java
  29. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/dto/hardwareApi/UpdateTicketStatusDTO.java
  30. 2 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/isolationpoint/IsolationPointMapper.java
  31. 7 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketLockMapper.java
  32. 16 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketMapper.java
  33. 8 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketPointsMapper.java
  34. 2 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/dal/mysql/jobticket/JobTicketUserMapper.java
  35. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/KeyStatusEnum.java
  36. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LockStatusEnum.java
  37. 24 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/LocksetStatusEnum.java
  38. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/PointStatusEnum.java
  39. 23 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/enums/TicketStatusEnum.java
  40. 140 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiService.java
  41. 1142 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/hardwareapi/HardwareApiServiceImpl.java
  42. 2 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/isolationpoint/IsolationPointService.java
  43. 5 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/isolationpoint/IsolationPointServiceImpl.java
  44. 17 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketLockService.java
  45. 16 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketLockServiceImpl.java
  46. 30 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketPointsService.java
  47. 20 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketPointsServiceImpl.java
  48. 4 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketService.java
  49. 11 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketServiceImpl.java
  50. 7 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketUserService.java
  51. 5 0
      yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketUserServiceImpl.java
  52. 8 0
      yudao-module-iscs/src/main/resources/mapper/IsolationPointMapper.xml
  53. 21 0
      yudao-module-iscs/src/main/resources/mapper/JobTicketLockMapper.xml
  54. 48 0
      yudao-module-iscs/src/main/resources/mapper/JobTicketMapper.xml
  55. 70 10
      yudao-module-iscs/src/main/resources/mapper/JobTicketPointsMapper.xml
  56. 12 0
      yudao-module-iscs/src/main/resources/mapper/JobTicketUserMapper.xml

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

@@ -0,0 +1,146 @@
+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.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 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));
+    }
+
+
+}

+ 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;
+
+}

+ 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;
+
 }

+ 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;
     /**
      * 备注
      */

+ 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;
+
+}

+ 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);
+
 }

+ 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);
+
 
 }

+ 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;
+}

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

@@ -0,0 +1,140 @@
+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.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);
+
+}

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

@@ -0,0 +1,1142 @@
+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.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"));
+        // 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"));
+            // 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())
+                .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())
+                    .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);
+        // 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;
+    }
+}

+ 2 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/isolationpoint/IsolationPointService.java

@@ -65,4 +65,6 @@ public interface IsolationPointService extends IService<IsolationPointDO> {
 
     List<PointDetailVO> getPointDetailList(List<Long> pointIds);
 
+    IsolationPointRespVO getOneByNfc(String nfc);
+
 }

+ 5 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/isolationpoint/IsolationPointServiceImpl.java

@@ -173,4 +173,9 @@ public class IsolationPointServiceImpl extends ServiceImpl<IsolationPointMapper,
         return isIsolationPoints;
     }
 
+    @Override
+    public IsolationPointRespVO getOneByNfc(String nfc) {
+        return isolationPointMapper.getOneByNfc(nfc);
+    }
+
 }

+ 17 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketLockService.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.iscs.service.jobticket;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 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.controller.admin.jobticket.vo.JobTicketLockSaveReqVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketLockDO;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -54,4 +55,20 @@ public interface JobTicketLockService extends IService<JobTicketLockDO> {
      */
     PageResult<JobTicketLockDO> getJobTicketLockPage(JobTicketLockPageReqVO pageReqVO);
 
+    List<JobTicketLockRespVO> getTicketLockByTicketId(Long ticketId);
+
+    /**
+     * 通过锁的nfc查询当前关联的未完成的作业
+     * @param nfc
+     * @return
+     */
+    JobTicketLockDO getLockJobByBfc(String nfc, Long ticketId);
+
+    /**
+     * 查一下哪个作业票用了这个挂锁,而且还没有完成
+     * @param lockId
+     * @return
+     */
+    List<JobTicketLockDO> getLockJob(Long lockId);
+
 }

+ 16 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketLockServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.iscs.service.jobticket;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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.controller.admin.jobticket.vo.JobTicketLockSaveReqVO;
 import cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketLockDO;
 import cn.iocoder.yudao.module.iscs.dal.mysql.jobticket.JobTicketLockMapper;
@@ -68,4 +69,19 @@ public class JobTicketLockServiceImpl extends ServiceImpl<JobTicketLockMapper, J
         return jobTicketLockMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public List<JobTicketLockRespVO> getTicketLockByTicketId(Long ticketId) {
+        return jobTicketLockMapper.getTicketLockByTicketId(ticketId);
+    }
+
+    @Override
+    public JobTicketLockDO getLockJobByBfc(String nfc, Long ticketId) {
+        return jobTicketLockMapper.getLockJobByBfc(nfc, ticketId);
+    }
+
+    @Override
+    public List<JobTicketLockDO> getLockJob(Long lockId) {
+        return jobTicketLockMapper.getLockJob(lockId);
+    }
+
 }

+ 30 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketPointsService.java

@@ -62,4 +62,34 @@ public interface JobTicketPointsService extends IService<JobTicketPointsDO> {
      */
     List<JobTicketPointsRespVO> listByTicketId(Long ticketId);
 
+    /**
+     * 查询已经完成的作业,但是存在有的点位没有解锁
+     * @param pointId
+     * @param lockId  点位的上锁属性
+     * @return
+     */
+    List<JobTicketPointsDO> getFinishConflictJob(Long pointId, Long lockId);
+
+    /**
+     * 查询未完成的作业,但是去了钥匙去解锁
+     * @param pointId
+     * @param lockId  点位的上锁属性
+     * @return
+     */
+    List<JobTicketPointsDO> getNotFinishConflictJob(Long pointId, Long lockId);
+
+    /**
+     * 根据点位查询上锁信息,已经上锁的数据
+     * @param pointId 点位信息
+     * @return
+     */
+    JobTicketPointsDO getLockingData(Long pointId);
+
+    /**
+     * 虚拟所冲突点位
+     * @param pointId 点位信息
+     * @return
+     */
+    List<JobTicketPointsDO> getVirtualLockConflictPoint(Long pointId, Long lockId, Long ticketId);
+
 }

+ 20 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketPointsServiceImpl.java

@@ -102,4 +102,24 @@ public class JobTicketPointsServiceImpl extends ServiceImpl<JobTicketPointsMappe
         return jobTicketPointsMapper.listByTicketId(ticketId);
     }
 
+    @Override
+    public List<JobTicketPointsDO> getFinishConflictJob(Long pointId, Long lockId) {
+        return jobTicketPointsMapper.getFinishConflictJob(pointId, lockId);
+    }
+
+    @Override
+    public List<JobTicketPointsDO> getNotFinishConflictJob(Long pointId, Long lockId) {
+        return jobTicketPointsMapper.getNotFinishConflictJob(pointId, lockId);
+    }
+
+    @Override
+    public JobTicketPointsDO getLockingData(Long pointId) {
+        return jobTicketPointsMapper.getLockingData(pointId);
+    }
+
+    @Override
+    public List<JobTicketPointsDO> getVirtualLockConflictPoint(Long pointId, Long lockId, Long ticketId) {
+        return jobTicketPointsMapper.getVirtualLockConflictPoint(pointId, lockId, ticketId);
+    }
+
 }

+ 4 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketService.java

@@ -65,4 +65,8 @@ public interface JobTicketService extends IService<JobTicketDO> {
 
     MyAgentRespVO getMyAgent(String startTime, String endTime);
 
+    List<JobTicketDetailVO> selectConflictTicket1(List<Long> points, Long ticketId);
+
+    List<JobTicketDetailVO> selectConflictTicket2(List<Long> points, Long ticketId);
+
 }

+ 11 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketServiceImpl.java

@@ -950,4 +950,15 @@ public class JobTicketServiceImpl extends ServiceImpl<JobTicketMapper, JobTicket
     }
 
 
+    @Override
+    public List<JobTicketDetailVO> selectConflictTicket1(List<Long> pointIds, Long ticketId) {
+        return jobTicketMapper.selectConflictTicket1(pointIds, ticketId);
+    }
+
+    @Override
+    public List<JobTicketDetailVO> selectConflictTicket2(List<Long> pointIds, Long ticketId) {
+        return jobTicketMapper.selectConflictTicket2(pointIds, ticketId);
+    }
+
+
 }

+ 7 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketUserService.java

@@ -57,4 +57,11 @@ public interface JobTicketUserService extends IService<JobTicketUserDO> {
 
     List<JobTicketUserRespVO> listByTicketId(Long ticketId);
 
+    /**
+     * 获取我的需要去上锁或者去解锁的作业
+     * @param userId
+     * @return
+     */
+    List<JobTicketUserDO> getMyJob(Long userId);
+
 }

+ 5 - 0
yudao-module-iscs/src/main/java/cn/iocoder/yudao/module/iscs/service/jobticket/JobTicketUserServiceImpl.java

@@ -109,4 +109,9 @@ public class JobTicketUserServiceImpl extends ServiceImpl<JobTicketUserMapper, J
         return jobTicketUserMapper.listByTicketId(ticketId);
     }
 
+    @Override
+    public List<JobTicketUserDO> getMyJob(Long userId) {
+        return jobTicketUserMapper.getMyJob(userId);
+    }
+
 }

+ 8 - 0
yudao-module-iscs/src/main/resources/mapper/IsolationPointMapper.xml

@@ -90,4 +90,12 @@
         group by p.id
         order by p.id desc
     </select>
+    <select id="getOneByNfc"
+            resultType="cn.iocoder.yudao.module.iscs.controller.admin.isolationpoint.vo.IsolationPointRespVO">\
+        select p.*,
+               r.rfid as point_nfc
+        from is_isolation_point p
+                 LEFT JOIN is_rfid_token r on r.rfid_id = p.rfid_id
+        where r.rfid = #{nfc}
+    </select>
 </mapper>

+ 21 - 0
yudao-module-iscs/src/main/resources/mapper/JobTicketLockMapper.xml

@@ -9,4 +9,25 @@
         文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
      -->
 
+    <select id="getLockJob" resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketLockDO">
+        SELECT
+        t.*
+        FROM
+        isc_job_ticket_lock t left join isc_job_ticket t1 on t1.id = t.ticket_id
+        <where>
+            t.lock_status != "5"
+            and t1.ticket_status != "5"
+            and t1.ticket_status != "6"
+            <if test="lockId != null">
+                AND t.lock_id = #{lockId}
+            </if>
+        </where>
+    </select>
+    <select id="getTicketLockByTicketId"
+            resultType="cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketLockRespVO">
+        select j.*, l.lock_nfc
+        from isc_job_ticket_lock j
+                 left join isc_lock l on l.id = j.lock_id
+        where j.ticket_id = #{ticketId}
+    </select>
 </mapper>

+ 48 - 0
yudao-module-iscs/src/main/resources/mapper/JobTicketMapper.xml

@@ -115,4 +115,52 @@
                 left join isc_sop s ON s.id = j.sop_id
         where j.deleted = 0 and j.id = #{id}
     </select>
+
+    <select id="selectConflictTicket1"
+            resultType="cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketDetailVO">
+        SELECT
+        j.*
+        FROM
+        `isc_job_ticket` j
+        LEFT JOIN isc_job_ticket_points p ON p.ticket_id = j.id
+        LEFT JOIN isc_job_ticket_key k ON k.ticket_id = j.id
+        WHERE
+        j.ticket_status &lt; 5
+        AND p.point_id IN
+        <foreach collection="pointIds" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        AND k.collect_time is not null
+        and k.give_back_time is null
+        and k.ticket_type = 0
+        and j.id != #{ticketId}
+        GROUP BY
+        j.id
+    </select>
+
+    <select id="selectConflictTicket2"
+            resultType="cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketDetailVO">
+        SELECT
+        j.*
+        FROM
+        `isc_job_ticket` j
+        LEFT JOIN isc_job_ticket_points p ON p.ticket_id = j.id
+        LEFT JOIN isc_job_ticket_key k1 ON k1.ticket_id = j.id and k1.ticket_type = 0
+        LEFT JOIN isc_job_ticket_key k2 ON k2.ticket_id = j.id and k2.ticket_type = 1
+        WHERE
+        j.ticket_status &lt; 5
+        AND p.point_id IN
+        <foreach collection="pointIds" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+        AND k1.collect_time is not null
+        and k1.give_back_time is not null
+        AND k2.collect_time is null
+        and k2.give_back_time is null
+        and j.id != #{ticketId}
+        and p.point_status = 1
+        GROUP BY
+        j.id
+    </select>
+
 </mapper>

+ 70 - 10
yudao-module-iscs/src/main/resources/mapper/JobTicketPointsMapper.xml

@@ -11,15 +11,75 @@
 
     <select id="listByTicketId"
             resultType="cn.iocoder.yudao.module.iscs.controller.admin.jobticket.vo.JobTicketPointsRespVO">
-        SELECT
-            tp.*,
-            p.point_name,
-            p.remark AS ability,
-            s.nickname AS lockUserName
-        FROM
-            isc_job_ticket_points tp
-                LEFT JOIN isc_isolation_point p ON p.id = tp.point_id
-                LEFT JOIN system_users s ON s.id = tp.lock_user_id
-        where tp.deleted = 0 and tp.ticket_id = #{ticketId}
+        SELECT tp.*,
+               p.point_name,
+               p.remark AS ability,
+               s.nickname AS lockUserName,
+               p.point_name,
+               r.rfid AS point_nfc,
+               p.point_serial_number,
+               l.lock_name,
+               l.lock_nfc
+        FROM isc_job_ticket_points tp
+                 LEFT JOIN isc_isolation_point p ON p.id = tp.point_id
+                 LEFT JOIN system_users s ON s.id = tp.lock_user_id
+                 left join isc_rfid_token r on r.id = p.rfid_id
+                 LEFT JOIN isc_lock l ON tp.lock_id = l.id
+        where tp.deleted = 0
+          and tp.ticket_id = #{ticketId}
     </select>
+
+    <select id="getFinishConflictJob"
+            resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketPointsDO">
+        SELECT p.*
+        FROM isc_job_ticket_points p
+                 LEFT JOIN isc_job_ticket t ON t.id = p.ticket_id
+        WHERE t.ticket_status = "5"
+          AND p.point_status = "1"
+          AND p.unlocked_by_key_id IS NULL
+          AND p.point_id = #{pointId}
+          AND p.lock_id = #{lockId}
+    </select>
+
+    <select id="getNotFinishConflictJob"
+            resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketPointsDO">
+        SELECT p.*
+        FROM isc_job_ticket_points p
+                 LEFT JOIN isc_job_ticket t ON t.id = p.ticket_id
+                 LEFT JOIN isc_job_ticket_key k ON k.ticket_id = p.ticket_id and k.ticket_type = "1"
+        WHERE t.ticket_status &lt; 5
+          AND p.point_status = "1"
+          AND p.unlocked_by_key_id IS NULL
+          AND p.point_id = #{pointId}
+          AND p.lock_id = #{lockId}
+          AND k.collect_time IS NOT NULL
+    </select>
+
+    <select id="getLockingData" resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketPointsDO">
+        SELECT p.*
+        FROM isc_job_ticket_points p
+                 LEFT JOIN isc_job_ticket t ON t.id = p.ticket_id
+                 LEFT JOIN isc_job_ticket_key k ON k.ticket_id = p.ticket_id and k.ticket_type = "1"
+        WHERE t.ticket_status &lt; 5
+          AND p.point_status = "1"
+          AND p.unlocked_by_key_id IS NULL
+          AND p.point_id = #{pointId}
+          AND k.collect_time IS NULL limit 1
+    </select>
+
+    <select id="getVirtualLockConflictPoint"
+            resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketPointsDO">
+        SELECT p.*
+        FROM isc_job_ticket_points p
+                 LEFT JOIN isc_job_ticket t ON t.id = p.ticket_id
+                 LEFT JOIN isc_job_ticket_key k ON k.ticket_id = p.ticket_id and k.ticket_type = "1"
+        WHERE t.ticket_status &lt; 5
+          AND p.point_status = "1"
+          AND p.unlocked_by_key_id IS NULL
+          AND p.point_id = #{pointId}
+          AND p.lock_id = #{lockId}
+          AND p.ticket_id != #{ticketId}
+          AND k.collect_time IS NULL
+    </select>
+
 </mapper>

+ 12 - 0
yudao-module-iscs/src/main/resources/mapper/JobTicketUserMapper.xml

@@ -19,4 +19,16 @@
                 LEFT JOIN system_users u ON tu.user_id = u.id
         where tu.deleted = 0 and tu.ticket_id = #{ticketId}
     </select>
+    <select id="getMyJob" resultType="cn.iocoder.yudao.module.iscs.dal.dataobject.jobticket.JobTicketUserDO">
+        SELECT
+            u.*
+        FROM
+            isc_job_ticket_user u
+                LEFT JOIN isc_job_ticket t ON t.id = u.user_id
+        WHERE
+            u.user_id = #{userId}
+          AND u.user_role = "jtlocker"
+          AND t.ticket_status != "5"
+          AND t.ticket_status != "6"
+    </select>
 </mapper>