diff --git a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainDormAuthServiceImpl.java b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainDormAuthServiceImpl.java index da81a9820..94c93a2e5 100644 --- a/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainDormAuthServiceImpl.java +++ b/RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/impl/TrainDormAuthServiceImpl.java @@ -184,9 +184,19 @@ public class TrainDormAuthServiceImpl implements ITrainDormAuthService * @return 结果 */ @Override + @Transactional(rollbackFor = Exception.class) public int deleteTrainDormAuthByAuthIds(Long[] authIds) { - return trainDormAuthMapper.deleteTrainDormAuthByAuthIds(authIds); + if (authIds == null || authIds.length == 0) + { + return 0; + } + int count = 0; + for (Long authId : authIds) + { + count += deleteTrainDormAuthByAuthId(authId); + } + return count; } /** @@ -198,6 +208,17 @@ public class TrainDormAuthServiceImpl implements ITrainDormAuthService @Override public int deleteTrainDormAuthByAuthId(Long authId) { + TrainDormAuth exist = trainDormAuthMapper.selectTrainDormAuthByAuthId(authId); + if (exist == null) + { + return 0; + } + if (TrainDormAuth.STATUS_ACTIVE.equals(exist.getFaceSyncStatus()) + || TrainDormAuth.AUTH_STATUS_ACTIVE.equals(exist.getAuthStatus()) + || TrainDormAuth.AUTH_STATUS_GRANTING.equals(exist.getAuthStatus())) + { + throw new ServiceException("当前门禁授权处于生效或授权中状态,请先执行注销后再清理"); + } return trainDormAuthMapper.deleteTrainDormAuthByAuthId(authId); } diff --git a/RuoYi-Vue/ruoyi-train/src/test/java/com/ruoyi/train/service/impl/DormAuthAlignmentTest.java b/RuoYi-Vue/ruoyi-train/src/test/java/com/ruoyi/train/service/impl/DormAuthAlignmentTest.java index be70640f5..4e721001b 100644 --- a/RuoYi-Vue/ruoyi-train/src/test/java/com/ruoyi/train/service/impl/DormAuthAlignmentTest.java +++ b/RuoYi-Vue/ruoyi-train/src/test/java/com/ruoyi/train/service/impl/DormAuthAlignmentTest.java @@ -297,6 +297,60 @@ public class DormAuthAlignmentTest assertEquals(newAccId, queriedNew.getAccommodationId()); } + /** + * 验证活跃生效中(ACTIVE)门禁授权禁止直接物理删除,必须先注销 + */ + @Test + public void testDeleteTrainDormAuth_ActiveStatusBlocked() + { + TrainAccommodation acc = new TrainAccommodation(); + acc.setAccommodationId(5003L); + acc.setAccommodationStatus(TrainAccommodation.STATUS_CHECKED_IN); + mockAccommodationMapper.save(acc); + + TrainDormAuth activeAuth = new TrainDormAuth(); + activeAuth.setAccommodationId(5003L); + dormAuthService.insertTrainDormAuth(activeAuth); + Long authId = activeAuth.getAuthId(); + + // 模拟外部设备同步成功,更新状态为 ACTIVE + mockDormAuthMapper.updateSyncStatus(authId, TrainDormAuth.STATUS_ACTIVE, null, "admin", new Date()); + + try + { + dormAuthService.deleteTrainDormAuthByAuthId(authId); + fail("应拦截活跃门禁授权删除并抛出 ServiceException"); + } + catch (ServiceException e) + { + assertTrue(e.getMessage().contains("当前门禁授权处于生效或授权中状态")); + } + } + + /** + * 验证已注销(REVOKED)门禁授权可以安全物理清理 + */ + @Test + public void testDeleteTrainDormAuth_RevokedCanBeDeleted() + { + TrainAccommodation acc = new TrainAccommodation(); + acc.setAccommodationId(5004L); + acc.setAccommodationStatus(TrainAccommodation.STATUS_CHECKED_IN); + mockAccommodationMapper.save(acc); + + TrainDormAuth auth = new TrainDormAuth(); + auth.setAccommodationId(5004L); + dormAuthService.insertTrainDormAuth(auth); + Long authId = auth.getAuthId(); + + // 办理注销 + dormAuthService.revokeAuth(authId, "admin"); + + int deleted = dormAuthService.deleteTrainDormAuthByAuthId(authId); + assertEquals(1, deleted); + assertNull(dormAuthService.selectTrainDormAuthByAuthId(authId)); + } + // ================================= 内部 Mock 类 ================================= private static class MockDormAuthMapper implements TrainDormAuthMapper