From 4c67ec0ed0fb74709526bb9e5e58e5f3db636e6d Mon Sep 17 00:00:00 2001 From: chenxing Date: Wed, 19 Aug 2026 17:22:38 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=88=A0=E9=99=A4=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userbase/service/impl/SysUserService.java | 7 +--- .../userbase/service/push/PushDispatcher.java | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java b/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java index f493621..3d87eb5 100644 --- a/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java +++ b/src/main/java/com/yunhai/userbase/service/impl/SysUserService.java @@ -229,7 +229,6 @@ public class SysUserService implements ISysUserService { throw new DException("存在无效用户"); } - List deletedUserIds = new ArrayList<>(); for (Integer userId : userIds) { // 删除当前组关联 sysUserGroupRelRepository.deleteByUserIdAndGroupId(userId, groupId); @@ -237,12 +236,10 @@ public class SysUserService implements ISysUserService { if (sysUserGroupRelRepository.countByUserId(userId) == 0) { sysUserAppRoleRelRepository.deleteByUserIdBulk(userId); sysUserRepository.deleteById(userId); - deletedUserIds.add(userId); } } - if (!deletedUserIds.isEmpty()) { - publishUserEvent(PushInterfaceType.DELETE_USER, deletedUserIds); - } + // 业务语义:从组移除 = 对子应用即删除(不论是否真删账户),统一推送 DELETE_USER + publishUserEvent(PushInterfaceType.DELETE_USER, userIds); } @Override diff --git a/src/main/java/com/yunhai/userbase/service/push/PushDispatcher.java b/src/main/java/com/yunhai/userbase/service/push/PushDispatcher.java index c69e0cd..5092623 100644 --- a/src/main/java/com/yunhai/userbase/service/push/PushDispatcher.java +++ b/src/main/java/com/yunhai/userbase/service/push/PushDispatcher.java @@ -65,6 +65,16 @@ public class PushDispatcher { if (type == null) { return; } + // 删除类事件:实体已从库中删除,AFTER_COMMIT 阶段重载必然为空, + // 直接用事件携带的 id 构建删除体;删除幂等,绕过范围过滤全量投递给已开启删除事件的订阅方 + if (type == PushInterfaceType.DELETE_GROUP || type == PushInterfaceType.DELETE_USER) { + List ids = (type == PushInterfaceType.DELETE_GROUP) + ? event.getGroupIds() : event.getUserIds(); + for (ApplicationInfo app : applicationInfoRepository.findByPushEnabled(1)) { + dispatchDeleteToOne(app, type, ids, "auto"); + } + return; + } List groups = (event.getGroupIds() != null && !event.getGroupIds().isEmpty()) ? sysGroupRepository.findAllById(event.getGroupIds()) : Collections.emptyList(); List users = (event.getUserIds() != null && !event.getUserIds().isEmpty()) @@ -177,6 +187,36 @@ public class PushDispatcher { // ===================== 核心 ===================== + /** 删除类事件专用投递:跳过 DB 重载与范围过滤,直接用事件携带的 id 构建删除体。 */ + private void dispatchDeleteToOne(ApplicationInfo app, PushInterfaceType type, List ids, String triggerType) { + if (app.getPushEnabled() == null || app.getPushEnabled() != 1) { + return; + } + // 仍校验订阅方是否勾选了删除接口 + if (!containsEventType(app.getPushEventTypes(), type.getPath())) { + return; + } + if (ids == null || ids.isEmpty()) { + return; + } + for (Object bodyObj : buildDeleteBodies(type, ids)) { + sendMessage(app, type, bodyObj, triggerType); + } + } + + /** 删除类接口 body 形态:DELETE_GROUP 每个 id 一条 {id};DELETE_USER 整体一条数组 [id,...]。 */ + private List buildDeleteBodies(PushInterfaceType type, List ids) { + if (type == PushInterfaceType.DELETE_GROUP) { + return ids.stream() + .map(id -> Collections.singletonMap("id", id)) + .collect(Collectors.toList()); + } + if (type == PushInterfaceType.DELETE_USER) { + return Collections.singletonList(new ArrayList<>(ids)); + } + return Collections.emptyList(); + } + private void dispatchToOne(ApplicationInfo app, PushInterfaceType type, List groups, List users, String triggerType, boolean force) { if (app.getPushEnabled() == null || app.getPushEnabled() != 1) {