diff --git a/ruoyi-asset/src/main/java/com/ruoyi/asset/mapper/AmsRfidTagMapper.java b/ruoyi-asset/src/main/java/com/ruoyi/asset/mapper/AmsRfidTagMapper.java index b1a6d6c..4f13527 100644 --- a/ruoyi-asset/src/main/java/com/ruoyi/asset/mapper/AmsRfidTagMapper.java +++ b/ruoyi-asset/src/main/java/com/ruoyi/asset/mapper/AmsRfidTagMapper.java @@ -37,6 +37,14 @@ public interface AmsRfidTagMapper */ public AmsRfidTag selectAmsRfidTagByEpcForUpdate(String epcCode); + /** + * 按EPC查询RFID标签 + * + * @param epcCode EPC编码 + * @return RFID标签 + */ + public AmsRfidTag selectAmsRfidTagByEpc(String epcCode); + /** * 查询RFID标签列表 * @@ -53,6 +61,14 @@ public interface AmsRfidTagMapper */ public List selectAmsRfidTagByEpcCodes(@Param("epcCodes") List epcCodes); + /** + * 按资产ID批量锁定当前已绑定的RFID标签 + * + * @param assetIds 资产ID集合 + * @return RFID标签集合 + */ + public List selectBoundAmsRfidTagsByAssetIdsForUpdate(@Param("assetIds") List assetIds); + /** * 校验标签编码是否唯一 * @@ -105,6 +121,20 @@ public interface AmsRfidTagMapper @Param("updateBy") String updateBy, @Param("updateTime") Date updateTime); + /** + * 报废资产时作废当前绑定的RFID标签,保留绑定快照 + * + * @param tagId RFID标签主键 + * @param assetId 当前绑定资产ID + * @param updateBy 更新人 + * @param updateTime 更新时间 + * @return 结果 + */ + public int voidBoundAmsRfidTagByAssetId(@Param("tagId") Long tagId, + @Param("assetId") Long assetId, + @Param("updateBy") String updateBy, + @Param("updateTime") Date updateTime); + /** * 清空RFID标签当前绑定资产 * diff --git a/ruoyi-asset/src/main/java/com/ruoyi/asset/service/IAssetStatusTransitionService.java b/ruoyi-asset/src/main/java/com/ruoyi/asset/service/IAssetStatusTransitionService.java index 918d8b0..3649be7 100644 --- a/ruoyi-asset/src/main/java/com/ruoyi/asset/service/IAssetStatusTransitionService.java +++ b/ruoyi-asset/src/main/java/com/ruoyi/asset/service/IAssetStatusTransitionService.java @@ -106,7 +106,7 @@ public interface IAssetStatusTransitionService /** * 确认资产报废:IN_STOCK/IN_USE → DISPOSED - *

报废不清除 RFID 绑定关系,保留标签溯源能力。

+ *

本服务只负责资产状态流转并保留 RFID 绑定快照;绑定标签作废由报废单服务统一处理。

* * @param assetId 资产ID * @param context 流转操作上下文 diff --git a/ruoyi-asset/src/main/java/com/ruoyi/asset/service/impl/AmsDisposalOrderServiceImpl.java b/ruoyi-asset/src/main/java/com/ruoyi/asset/service/impl/AmsDisposalOrderServiceImpl.java index 713621a..6425b9f 100644 --- a/ruoyi-asset/src/main/java/com/ruoyi/asset/service/impl/AmsDisposalOrderServiceImpl.java +++ b/ruoyi-asset/src/main/java/com/ruoyi/asset/service/impl/AmsDisposalOrderServiceImpl.java @@ -2,8 +2,10 @@ package com.ruoyi.asset.service.impl; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,9 +15,11 @@ import com.ruoyi.asset.domain.AmsAsset; import com.ruoyi.asset.domain.AmsDisposalOperateContext; import com.ruoyi.asset.domain.AmsDisposalOrder; import com.ruoyi.asset.domain.AmsDisposalOrderItem; +import com.ruoyi.asset.domain.AmsRfidTag; import com.ruoyi.asset.domain.AssetTransitionContext; import com.ruoyi.asset.mapper.AmsAssetMapper; import com.ruoyi.asset.mapper.AmsDisposalOrderMapper; +import com.ruoyi.asset.mapper.AmsRfidTagMapper; import com.ruoyi.asset.service.IAmsDisposalOrderService; import com.ruoyi.asset.service.IAssetStatusTransitionService; import com.ruoyi.common.core.text.Convert; @@ -48,6 +52,9 @@ public class AmsDisposalOrderServiceImpl implements IAmsDisposalOrderService @Autowired private AmsAssetMapper amsAssetMapper; + @Autowired + private AmsRfidTagMapper amsRfidTagMapper; + @Autowired private ISysCodeRuleService sysCodeRuleService; @@ -264,6 +271,7 @@ public class AmsDisposalOrderServiceImpl implements IAmsDisposalOrderService AmsDisposalOrder order = requireOrderForUpdate(orderId, DisposalOrderStatus.PENDING_CONFIRM, "仅待确认状态的报废单允许确认报废"); // 2. 升序加锁校验资产状态及跨单占用 + List boundTags = lockBoundRfidTags(order); validateOrderAssetsReady(order); Date now = DateUtils.getNowDate(); @@ -281,11 +289,14 @@ public class AmsDisposalOrderServiceImpl implements IAmsDisposalOrderService context.setChangeSummary("确认资产报废"); context.setRemark(item.getDisposalRemark()); - // 变更资产状态为 DISPOSED 写入资产履历,报废不清除 RFID 绑定 + // 报废只终止标签继续流转,不清空绑定快照,便于后续追溯报废资产原 RFID 标签。 assetStatusTransitionService.confirmDisposal(item.getAssetId(), context); } - // 4. 回填确认属性,变更为已报废状态 + // 4. 同步作废当前绑定标签,保留标签与报废资产的绑定快照用于追溯。 + voidBoundRfidTags(boundTags, operateContext, now); + + // 5. 回填确认属性,变更为已报废状态 order.setConfirmUserId(operateContext.getOperateUserId()); order.setConfirmUserName(StringUtils.trim(operateContext.getOperateUserName())); order.setConfirmTime(now); @@ -385,6 +396,52 @@ public class AmsDisposalOrderServiceImpl implements IAmsDisposalOrderService return 1; } + private List lockBoundRfidTags(AmsDisposalOrder order) + { + List assetIds = collectSortedAssetIds(order); + if (assetIds.isEmpty()) + { + return Collections.emptyList(); + } + List tags = amsRfidTagMapper.selectBoundAmsRfidTagsByAssetIdsForUpdate(assetIds); + return tags == null ? Collections.emptyList() : tags; + } + + private List collectSortedAssetIds(AmsDisposalOrder order) + { + if (order == null || order.getAmsDisposalOrderItemList() == null) + { + return Collections.emptyList(); + } + return order.getAmsDisposalOrderItemList().stream() + .filter(item -> item != null && item.getAssetId() != null) + .map(AmsDisposalOrderItem::getAssetId) + .distinct() + .sorted() + .collect(Collectors.toList()); + } + + private void voidBoundRfidTags(List boundTags, + AmsDisposalOperateContext operateContext, Date operateTime) + { + if (boundTags == null || boundTags.isEmpty()) + { + return; + } + for (AmsRfidTag tag : boundTags) + { + if (tag == null || tag.getTagId() == null || tag.getAssetId() == null) + { + throw new ServiceException("RFID标签绑定信息不完整,报废确认失败"); + } + if (amsRfidTagMapper.voidBoundAmsRfidTagByAssetId(tag.getTagId(), tag.getAssetId(), + operateContext.getOperateLoginName(), operateTime) != 1) + { + throw new ServiceException(StringUtils.format("RFID标签【{}】状态已变化,报废确认失败", tag.getTagCode())); + } + } + } + private void validateOrderRequest(AmsDisposalOrder order) { if (order == null) diff --git a/ruoyi-asset/src/main/resources/mapper/asset/AmsRfidTagMapper.xml b/ruoyi-asset/src/main/resources/mapper/asset/AmsRfidTagMapper.xml index 68df626..41744d5 100644 --- a/ruoyi-asset/src/main/resources/mapper/asset/AmsRfidTagMapper.xml +++ b/ruoyi-asset/src/main/resources/mapper/asset/AmsRfidTagMapper.xml @@ -62,6 +62,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" for update + + + +