From df41e0c8ce76f4f7f3f1c5833014e448e5730f62 Mon Sep 17 00:00:00 2001 From: pengjie <2413927716@qq.com> Date: Wed, 22 Jul 2026 11:01:23 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(emergency):=20getActualGroupMemberList?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E8=A1=A5=E6=8B=89=E9=A2=84=E8=AE=BE=E6=88=90?= =?UTF-8?q?=E5=91=98=20+=20addGroupUser=E5=8A=A09=E4=BA=BA=E4=B8=8A?= =?UTF-8?q?=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - getActualGroupMemberList: 查询群成员时自动检查预设成员(被救助人、操作人员、专业人员、紧急联系人、健康联络员),不在群中则自动补拉 - addGroupUser: 邀请前校验群成员总数不超过9人,超限返回提示 Co-Authored-By: Claude --- .../service/impl/EmergencyApiServiceImpl.java | 8 ++ .../impl/EmergencyOrderApiServiceImpl.java | 74 ++++++++++++++++++- 2 files changed, 78 insertions(+), 4 deletions(-) diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java index fe0537a..7038249 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java @@ -1355,6 +1355,14 @@ public class EmergencyApiServiceImpl implements EmergencyApiService { log.warn("获取腾讯IM群成员失败,仅使用本地数据进行去重, groupId: {}", groupId, e); } + // 2. 群成员上限校验:最多9人 + int currentGroupSize = alreadyInGroup.size(); + int newMemberCount = (int) candidateList.stream() + .filter(userId -> !alreadyInGroup.contains(userId)).count(); + if (currentGroupSize + newMemberCount > 9) { + ExceptionAssertsUtil.fail("群成员已达上限,当前" + currentGroupSize + "人,最多邀请" + (9 - currentGroupSize) + "人"); + } + // memberType: 0=专家/专业人员(默认), 1=员工 Integer memberType = dto.getMemberType(); Integer operatorType = (memberType != null && memberType == 1) ? 2 : 1; diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java index 7b01790..35b4794 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java @@ -28,7 +28,9 @@ import com.renkang.emergency.mapper.*; import com.renkang.emergency.service.IOrderDetailService; import com.renkang.emergency.service.IOrderService; import com.renkang.im.api.IMHelloApi; +import com.renkang.im.dto.AddGroupMemberDTO; import com.renkang.im.entity.ImGroupMsgTextReqDO; +import com.renkang.im.vo.AddGroupMemberVO; import com.renkang.im.vo.GetGroupMemberInfoVO; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -760,13 +762,18 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { log.error("获取腾讯IM群成员失败,sessionId: {},降级使用本地参与人员", sessionId, e); } - // 4. 如果IM调用失败,降级使用本地成员全集 + // 4. 自动补拉预设成员入群(仅IM可用时) + if (imSuccess) { + autoInvitePresetMembers(sessionId, order, imMemberAccounts, localUserIds, loginUser); + } + + // 5. 如果IM调用失败,降级使用本地成员全集 final Set validAccounts = imSuccess ? imMemberAccounts : new HashSet<>(localUserIds); if (!imSuccess) { log.warn("腾讯IM调用失败,降级返回本地参与人员 {} 人, sessionId: {}", localUserIds.size(), sessionId); } - // 5. 发起人:匹配验证集 + // 6. 发起人:匹配验证集 if (validAccounts.contains(order.getInitiatorUserId())) { handleGroupMember(groupMemberVos, orderId, order.getInitiatorUserId(), @@ -776,7 +783,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { 1, -1); } - // 6. 查order_operator表,匹配验证集 + // 7. 查order_operator表,匹配验证集 if (CollectionUtils.isNotEmpty(orderOperators)) { // 查询专业用户信息 Map profUserMap = new HashMap<>(); @@ -824,7 +831,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { } } - // 7. 标记本人 + // 8. 标记本人 String currentUserId = loginUser.getId(); groupMemberVos.forEach(vo -> vo.setIsSelf(currentUserId.equals(vo.getUserId()) ? 1 : 0)); return groupMemberVos; @@ -843,6 +850,65 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { groupMemberVos.add(groupMemberVO); } + /** + * 自动补拉预设成员入群 + * 预设成员:被救助人 + order_operator 中所有参与人员(操作人员、专业人员、紧急联系人、健康联络员) + * 群成员总数不超过9人 + */ + private void autoInvitePresetMembers(String sessionId, Order order, Set imMemberAccounts, + List localUserIds, LoginUser loginUser) { + Set presetMemberIds = new LinkedHashSet<>(); + // 被救助人 + if (StrUtil.isNotBlank(order.getSalvageUserId())) { + presetMemberIds.add(order.getSalvageUserId()); + } + // order_operator 中所有参与人员(操作人员、专业人员、紧急联系人、健康联络员) + if (CollectionUtils.isNotEmpty(localUserIds)) { + presetMemberIds.addAll(localUserIds); + } + // 排除当前登录用户(不能邀请自己) + presetMemberIds.remove(loginUser.getId()); + + // 找出不在群中的预设成员 + List missingPresetMembers = presetMemberIds.stream() + .filter(id -> !imMemberAccounts.contains(id)) + .collect(Collectors.toList()); + if (missingPresetMembers.isEmpty()) { + return; + } + + // 控制群成员不超过9人 + int currentCount = imMemberAccounts.size(); + int maxInvite = Math.max(0, 9 - currentCount); + if (maxInvite <= 0) { + log.warn("群成员已达上限9人,无法自动补拉预设成员, sessionId={}, current={}", sessionId, currentCount); + return; + } + List toInvite = missingPresetMembers.subList(0, Math.min(missingPresetMembers.size(), maxInvite)); + + try { + AddGroupMemberDTO addDto = new AddGroupMemberDTO(); + addDto.setGroupId(sessionId); + addDto.setSilence(1); + addDto.setMemberList(toInvite.stream().map(userId -> { + AddGroupMemberDTO.MemberListDTO m = new AddGroupMemberDTO.MemberListDTO(); + m.setMemberAccount(userId); + return m; + }).collect(Collectors.toList())); + Result result = imHelloApi.addGroupMember(addDto); + if (result != null && result.isSuccess() && result.getResult() != null + && "OK".equals(result.getResult().getActionStatus())) { + imMemberAccounts.addAll(toInvite); + log.info("自动补拉预设成员入群成功, sessionId={}, userIds={}, currentCount={}", + sessionId, toInvite, currentCount + toInvite.size()); + } else { + log.warn("自动补拉预设成员入群失败, sessionId={}, userIds={}", sessionId, toInvite); + } + } catch (Exception e) { + log.error("自动补拉预设成员入群异常, sessionId={}", sessionId, e); + } + } + @Override public IPage searchExpert(String realname, String centerId, String excludeSessionId, Integer pageNo, Integer pageSize) { LambdaQueryWrapper query = new LambdaQueryWrapper<>(); From 1167ac792e123e6de2cfb6f8174f884fa8816007 Mon Sep 17 00:00:00 2001 From: pengjie <2413927716@qq.com> Date: Wed, 22 Jul 2026 11:13:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(emergency):=20getActualGroupMemberList?= =?UTF-8?q?=E5=85=9C=E5=BA=95=E8=A1=A5=E6=8B=89=E5=85=B3=E7=88=B1/?= =?UTF-8?q?=E6=80=A5=E6=95=91=E4=BA=BA=E5=91=98=20+=20addGroupUser?= =?UTF-8?q?=E5=8A=A09=E4=BA=BA=E4=B8=8A=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调用getActualGroupMemberList时先执行addCareUsersToGroup重新查询安眼系统,兜底补拉发起应急时未注册的关爱联络员/急救人员 - addCareUsersToGroup改为public,暴露给EmergencyOrderApiService调用 - addGroupUser增加9人群成员上限校验 Co-Authored-By: Claude --- .../api/service/EmergencyApiService.java | 5 ++++ .../service/impl/EmergencyApiServiceImpl.java | 2 +- .../impl/EmergencyOrderApiServiceImpl.java | 26 +++++++++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/EmergencyApiService.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/EmergencyApiService.java index f2ce0b0..cc918ae 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/EmergencyApiService.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/EmergencyApiService.java @@ -45,5 +45,10 @@ public interface EmergencyApiService { boolean addGroupUser(AddOtherMemberDTO dto); + /** + * 拉入关爱联络员和急救人员到群聊(兜底补拉用,失败不抛异常) + */ + void addCareUsersToGroup(String userId, String groupId, String orderId); + boolean removeGroupUser(RemoveGroupMemberDTO dto); } diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java index 7038249..ad4cd76 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java @@ -1001,7 +1001,7 @@ public class EmergencyApiServiceImpl implements EmergencyApiService { * @param groupId IM群组ID * @param orderId 应急工单ID */ - private void addCareUsersToGroup(String userId, String groupId, String orderId) { + public void addCareUsersToGroup(String userId, String groupId, String orderId) { try { // 1. 获取发起人工号 List employeeInfos = sysBaseAPI.queryBaseEmployeeInfo(Collections.singleton(userId)); diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java index 35b4794..463ddea 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyOrderApiServiceImpl.java @@ -83,6 +83,8 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { private ISysBaseAPI sysBaseAPI; @Autowired private EmergencyCloudManager emergencyCloudManager; + @Autowired + private com.renkang.emergency.api.service.EmergencyApiService emergencyApiService; @Override public IPage initUserOrderPage(Page page) { @@ -735,7 +737,15 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { } String orderId = order.getId(); - // 2. 查order_operator表获取本地参与人员 + // 2. 兜底补拉关爱联络员+急救人员1+急救人员2(重新查询安眼系统) + // 发起应急时这些人员可能还未注册,此处兜底 + try { + emergencyApiService.addCareUsersToGroup(order.getInitiatorUserId(), sessionId, orderId); + } catch (Exception e) { + log.warn("兜底补拉关爱/急救人员异常, sessionId={}", sessionId, e); + } + + // 3. 查order_operator表获取本地参与人员 List orderOperators = orderOperatorMapper.selectList( new LambdaQueryWrapper() .eq(OrderOperator::getOrderId, orderId)); @@ -746,7 +756,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { .collect(Collectors.toList()); } - // 3. 调腾讯IM获取实际群成员 + // 4. 调腾讯IM获取实际群成员 Set imMemberAccounts = new HashSet<>(); boolean imSuccess = false; try { @@ -762,18 +772,18 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { log.error("获取腾讯IM群成员失败,sessionId: {},降级使用本地参与人员", sessionId, e); } - // 4. 自动补拉预设成员入群(仅IM可用时) + // 5. 自动补拉其他遗漏的预设成员(仅IM可用时) if (imSuccess) { autoInvitePresetMembers(sessionId, order, imMemberAccounts, localUserIds, loginUser); } - // 5. 如果IM调用失败,降级使用本地成员全集 + // 6. 如果IM调用失败,降级使用本地成员全集 final Set validAccounts = imSuccess ? imMemberAccounts : new HashSet<>(localUserIds); if (!imSuccess) { log.warn("腾讯IM调用失败,降级返回本地参与人员 {} 人, sessionId: {}", localUserIds.size(), sessionId); } - // 6. 发起人:匹配验证集 + // 7. 发起人:匹配验证集 if (validAccounts.contains(order.getInitiatorUserId())) { handleGroupMember(groupMemberVos, orderId, order.getInitiatorUserId(), @@ -783,7 +793,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { 1, -1); } - // 7. 查order_operator表,匹配验证集 + // 8. 查order_operator表,匹配验证集 if (CollectionUtils.isNotEmpty(orderOperators)) { // 查询专业用户信息 Map profUserMap = new HashMap<>(); @@ -831,7 +841,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { } } - // 8. 标记本人 + // 9. 标记本人 String currentUserId = loginUser.getId(); groupMemberVos.forEach(vo -> vo.setIsSelf(currentUserId.equals(vo.getUserId()) ? 1 : 0)); return groupMemberVos; @@ -852,7 +862,7 @@ public class EmergencyOrderApiServiceImpl implements EmergencyOrderApiService { /** * 自动补拉预设成员入群 - * 预设成员:被救助人 + order_operator 中所有参与人员(操作人员、专业人员、紧急联系人、健康联络员) + * 预设成员:被救助人 + order_operator 所有参与人员 * 群成员总数不超过9人 */ private void autoInvitePresetMembers(String sessionId, Order order, Set imMemberAccounts, From 44e8ac7da5c20ac0e6096cf19b14eb9f34e80279 Mon Sep 17 00:00:00 2001 From: pengjie <2413927716@qq.com> Date: Wed, 22 Jul 2026 11:24:46 +0800 Subject: [PATCH 3/3] =?UTF-8?q?chore(emergency):=20=E7=AE=80=E5=8C=96?= =?UTF-8?q?=E7=BE=A4=E6=88=90=E5=91=98=E4=B8=8A=E9=99=90=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- .../emergency/api/service/impl/EmergencyApiServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java index ad4cd76..0034161 100644 --- a/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java +++ b/health-emergency/health-emergency-biz/src/main/java/com/renkang/emergency/api/service/impl/EmergencyApiServiceImpl.java @@ -1360,7 +1360,7 @@ public class EmergencyApiServiceImpl implements EmergencyApiService { int newMemberCount = (int) candidateList.stream() .filter(userId -> !alreadyInGroup.contains(userId)).count(); if (currentGroupSize + newMemberCount > 9) { - ExceptionAssertsUtil.fail("群成员已达上限,当前" + currentGroupSize + "人,最多邀请" + (9 - currentGroupSize) + "人"); + ExceptionAssertsUtil.fail("群成员已达上限"); } // memberType: 0=专家/专业人员(默认), 1=员工