Commit 07f3bab72acd11b3469ff708ac5b2a1e71430616

Authored by YunaiV
1 parent d0aac382

✨ feat(im): 将后端的 roomName 和 callId 融合,简化字段和逻辑(一致性更好、概念更简洁)

Showing 17 changed files with 150 additions and 192 deletions
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/rtc/ImRtcCallController.java
@@ -26,7 +26,6 @@ import java.util.Set; @@ -26,7 +26,6 @@ import java.util.Set;
26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
27 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 27 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
28 28
29 -// TODO @AI:需要讨论,到底使用 roomName 还是 callId 更好?前端传参;然后,DO 那种,是不是只存储 callId,roomName 二选 1,是不是就行了。或者统一成 room?uuid 完事;callid 还给 call.id 更好理解;  
30 @Tag(name = "管理后台 - IM 实时通话") 29 @Tag(name = "管理后台 - IM 实时通话")
31 @RestController 30 @RestController
32 @RequestMapping("/im/rtc") 31 @RequestMapping("/im/rtc")
@@ -47,9 +46,9 @@ public class ImRtcCallController { @@ -47,9 +46,9 @@ public class ImRtcCallController {
47 46
48 @PostMapping("/join") 47 @PostMapping("/join")
49 @Operation(summary = "加入已有群通话;用于胶囊条「加入」按钮") 48 @Operation(summary = "加入已有群通话;用于胶囊条「加入」按钮")
50 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "im_rtc_call_xxxx")  
51 - public CommonResult<ImRtcCallRespVO> joinCall(@RequestParam("roomName") String roomName) {  
52 - ImRtcCallDO call = rtcCallService.joinCall(getLoginUserId(), roomName); 49 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  50 + public CommonResult<ImRtcCallRespVO> joinCall(@RequestParam("room") String room) {
  51 + ImRtcCallDO call = rtcCallService.joinCall(getLoginUserId(), room);
53 return success(buildCallResp(call, getLoginUserId())); 52 return success(buildCallResp(call, getLoginUserId()));
54 } 53 }
55 54
@@ -62,41 +61,41 @@ public class ImRtcCallController { @@ -62,41 +61,41 @@ public class ImRtcCallController {
62 61
63 @PostMapping("/accept") 62 @PostMapping("/accept")
64 @Operation(summary = "接听通话") 63 @Operation(summary = "接听通话")
65 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "call_friend_1_2")  
66 - public CommonResult<ImRtcCallRespVO> accept(@RequestParam("roomName") String roomName) {  
67 - ImRtcCallDO call = rtcCallService.acceptCall(getLoginUserId(), roomName); 64 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  65 + public CommonResult<ImRtcCallRespVO> accept(@RequestParam("room") String room) {
  66 + ImRtcCallDO call = rtcCallService.acceptCall(getLoginUserId(), room);
68 return success(buildCallResp(call, getLoginUserId())); 67 return success(buildCallResp(call, getLoginUserId()));
69 } 68 }
70 69
71 @PostMapping("/reject") 70 @PostMapping("/reject")
72 @Operation(summary = "拒绝通话") 71 @Operation(summary = "拒绝通话")
73 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "call_friend_1_2")  
74 - public CommonResult<Boolean> reject(@RequestParam("roomName") String roomName) {  
75 - rtcCallService.rejectCall(getLoginUserId(), roomName); 72 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  73 + public CommonResult<Boolean> reject(@RequestParam("room") String room) {
  74 + rtcCallService.rejectCall(getLoginUserId(), room);
76 return success(true); 75 return success(true);
77 } 76 }
78 77
79 @PostMapping("/cancel") 78 @PostMapping("/cancel")
80 @Operation(summary = "取消邀请;主叫接通前调用") 79 @Operation(summary = "取消邀请;主叫接通前调用")
81 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "call_friend_1_2")  
82 - public CommonResult<Boolean> cancel(@RequestParam("roomName") String roomName) {  
83 - rtcCallService.cancelCall(getLoginUserId(), roomName); 80 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  81 + public CommonResult<Boolean> cancel(@RequestParam("room") String room) {
  82 + rtcCallService.cancelCall(getLoginUserId(), room);
84 return success(true); 83 return success(true);
85 } 84 }
86 85
87 @PostMapping("/leave") 86 @PostMapping("/leave")
88 @Operation(summary = "离开通话;接通后调用") 87 @Operation(summary = "离开通话;接通后调用")
89 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "call_friend_1_2")  
90 - public CommonResult<Boolean> leave(@RequestParam("roomName") String roomName) {  
91 - rtcCallService.leaveCall(getLoginUserId(), roomName); 88 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  89 + public CommonResult<Boolean> leave(@RequestParam("room") String room) {
  90 + rtcCallService.leaveCall(getLoginUserId(), room);
92 return success(true); 91 return success(true);
93 } 92 }
94 93
95 @GetMapping("/refresh-token") 94 @GetMapping("/refresh-token")
96 @Operation(summary = "重新签发 Token;客户端重连或 Token 过期续期") 95 @Operation(summary = "重新签发 Token;客户端重连或 Token 过期续期")
97 - @Parameter(name = "roomName", description = "LiveKit 房间名", required = true, example = "call_friend_1_2")  
98 - public CommonResult<ImRtcCallRespVO> refreshToken(@RequestParam("roomName") String roomName) {  
99 - ImRtcCallDO call = rtcCallService.refreshCallToken(getLoginUserId(), roomName); 96 + @Parameter(name = "room", description = "业务通话编号", required = true, example = "f47ac10b58cc4372a567")
  97 + public CommonResult<ImRtcCallRespVO> refreshToken(@RequestParam("room") String room) {
  98 + ImRtcCallDO call = rtcCallService.refreshCallToken(getLoginUserId(), room);
100 return success(buildCallResp(call, getLoginUserId())); 99 return success(buildCallResp(call, getLoginUserId()));
101 } 100 }
102 101
@@ -114,11 +113,11 @@ public class ImRtcCallController { @@ -114,11 +113,11 @@ public class ImRtcCallController {
114 if (call == null) { 113 if (call == null) {
115 return null; 114 return null;
116 } 115 }
117 - List<ImRtcParticipantDO> participants = rtcCallService.getCallParticipants(call.getCallId()); 116 + List<ImRtcParticipantDO> participants = rtcCallService.getCallParticipants(call.getRoom());
118 return new ImRtcCallRespVO() 117 return new ImRtcCallRespVO()
119 - .setCallId(call.getCallId()).setRoomName(call.getRoomName()) 118 + .setRoom(call.getRoom())
120 .setLivekitUrl(imProperties.getRtc().getLivekitUrl()) 119 .setLivekitUrl(imProperties.getRtc().getLivekitUrl())
121 - .setToken(rtcCallService.signCallToken(userId, call.getRoomName())) 120 + .setToken(rtcCallService.signCallToken(userId, call.getRoom()))
122 .setScene(call.getConversationType()).setMediaType(call.getMediaType()) 121 .setScene(call.getConversationType()).setMediaType(call.getMediaType())
123 .setStatus(call.getStatus()).setInviterId(call.getInviterUserId()) 122 .setStatus(call.getStatus()).setInviterId(call.getInviterUserId())
124 .setGroupId(call.getGroupId()) 123 .setGroupId(call.getGroupId())
@@ -130,9 +129,9 @@ public class ImRtcCallController { @@ -130,9 +129,9 @@ public class ImRtcCallController {
130 if (call == null) { 129 if (call == null) {
131 return null; 130 return null;
132 } 131 }
133 - List<ImRtcParticipantDO> participants = rtcCallService.getCallParticipants(call.getCallId()); 132 + List<ImRtcParticipantDO> participants = rtcCallService.getCallParticipants(call.getRoom());
134 return new ImRtcGroupCallRespVO() 133 return new ImRtcGroupCallRespVO()
135 - .setCallId(call.getCallId()).setRoomName(call.getRoomName()) 134 + .setRoom(call.getRoom())
136 .setGroupId(call.getGroupId()).setMediaType(call.getMediaType()) 135 .setGroupId(call.getGroupId()).setMediaType(call.getMediaType())
137 .setInviterId(call.getInviterUserId()) 136 .setInviterId(call.getInviterUserId())
138 .setJoinedUserIds(filterUserIds(participants, ImRtcParticipantStatusEnum.JOINED)) 137 .setJoinedUserIds(filterUserIds(participants, ImRtcParticipantStatusEnum.JOINED))
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/rtc/ImRtcLiveKitController.java
@@ -57,7 +57,7 @@ public class ImRtcLiveKitController { @@ -57,7 +57,7 @@ public class ImRtcLiveKitController {
57 } 57 }
58 58
59 // 2. 交给 service 处理;幂等由 service 自己保证 59 // 2. 交给 service 处理;幂等由 service 自己保证
60 - log.info("[webhook][事件处理 event={} roomName={}]", event.getEvent(), 60 + log.info("[webhook][事件处理 event={} room={}]", event.getEvent(),
61 event.getRoom() == null ? null : event.getRoom().getName()); 61 event.getRoom() == null ? null : event.getRoom().getName());
62 try { 62 try {
63 rtcCallService.handleLiveKitEvent(event); 63 rtcCallService.handleLiveKitEvent(event);
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/rtc/vo/ImRtcCallInviteMoreReqVO.java
@@ -11,11 +11,10 @@ import java.util.Set; @@ -11,11 +11,10 @@ import java.util.Set;
11 @Data 11 @Data
12 public class ImRtcCallInviteMoreReqVO { 12 public class ImRtcCallInviteMoreReqVO {
13 13
14 - @Schema(description = "LiveKit 房间名", requiredMode = Schema.RequiredMode.REQUIRED, example = "call_group_2048")  
15 - @NotBlank(message = "房间名不能为空")  
16 - private String roomName; 14 + @Schema(description = "业务通话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "f47ac10b58cc4372a567")
  15 + @NotBlank(message = "通话编号不能为空")
  16 + private String room;
17 17
18 - // TODO @AI:targetIds?  
19 @Schema(description = "新邀请的用户编号集合", requiredMode = Schema.RequiredMode.REQUIRED) 18 @Schema(description = "新邀请的用户编号集合", requiredMode = Schema.RequiredMode.REQUIRED)
20 @NotEmpty(message = "请至少选择一位成员") 19 @NotEmpty(message = "请至少选择一位成员")
21 private Set<Long> inviteeIds; 20 private Set<Long> inviteeIds;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/rtc/vo/ImRtcCallRespVO.java
@@ -10,10 +10,7 @@ import java.util.Set; @@ -10,10 +10,7 @@ import java.util.Set;
10 public class ImRtcCallRespVO { 10 public class ImRtcCallRespVO {
11 11
12 @Schema(description = "业务通话编号") 12 @Schema(description = "业务通话编号")
13 - private String callId;  
14 -  
15 - @Schema(description = "LiveKit 房间名")  
16 - private String roomName; 13 + private String room;
17 14
18 @Schema(description = "LiveKit Server WebSocket 地址;前端 connect 用") 15 @Schema(description = "LiveKit Server WebSocket 地址;前端 connect 用")
19 private String livekitUrl; 16 private String livekitUrl;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/rtc/vo/ImRtcGroupCallRespVO.java
@@ -10,10 +10,7 @@ import java.util.Set; @@ -10,10 +10,7 @@ import java.util.Set;
10 public class ImRtcGroupCallRespVO { 10 public class ImRtcGroupCallRespVO {
11 11
12 @Schema(description = "业务通话编号") 12 @Schema(description = "业务通话编号")
13 - private String callId;  
14 -  
15 - @Schema(description = "LiveKit 房间名")  
16 - private String roomName; 13 + private String room;
17 14
18 @Schema(description = "群编号") 15 @Schema(description = "群编号")
19 private Long groupId; 16 private Long groupId;
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/rtc/ImRtcCallDO.java
@@ -16,7 +16,7 @@ import java.time.LocalDateTime; @@ -16,7 +16,7 @@ import java.time.LocalDateTime;
16 /** 16 /**
17 * IM 通话记录 DO(房间级 / 主表) 17 * IM 通话记录 DO(房间级 / 主表)
18 * <p> 18 * <p>
19 - * 一通通话一行;状态机 CREATED → RUNNING → ENDED;和明细表 {@link ImRtcParticipantDO} 通过 callId 关联 19 + * 一通通话一行;状态机 CREATED → RUNNING → ENDED;和明细表 {@link ImRtcParticipantDO} 通过 {@link #room} 关联
20 * 20 *
21 * @author 芋道源码 21 * @author 芋道源码
22 */ 22 */
@@ -31,25 +31,14 @@ import java.time.LocalDateTime; @@ -31,25 +31,14 @@ import java.time.LocalDateTime;
31 public class ImRtcCallDO extends BaseDO { 31 public class ImRtcCallDO extends BaseDO {
32 32
33 /** 33 /**
34 - * LiveKit 房间名前缀;roomName 格式固定为 {@code ROOM_NAME_PREFIX + callId}  
35 - */  
36 - public static final String ROOM_NAME_PREFIX = "im_rtc_call_";  
37 -  
38 - /**  
39 * 编号 34 * 编号
40 */ 35 */
41 @TableId 36 @TableId
42 private Long id; 37 private Long id;
43 /** 38 /**
44 - * 业务通话编号;唯一;UUID 生成  
45 - */  
46 - private String callId;  
47 - /**  
48 - * LiveKit 房间名  
49 - *  
50 - * 格式 {@code im_rtc_call_{callId}} 39 + * 业务通话编号(UUID,同时作为 LiveKit 房间名);唯一
51 */ 40 */
52 - private String roomName; 41 + private String room;
53 /** 42 /**
54 * 会话类型 43 * 会话类型
55 * 44 *
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/rtc/ImRtcParticipantDO.java
@@ -13,7 +13,7 @@ import java.time.LocalDateTime; @@ -13,7 +13,7 @@ import java.time.LocalDateTime;
13 /** 13 /**
14 * IM 通话参与者 DO(用户级 / 明细表) 14 * IM 通话参与者 DO(用户级 / 明细表)
15 * <p> 15 * <p>
16 - * 一通通话每个参与者一行;通过 callId 关联主表 {@link ImRtcCallDO} 16 + * 一通通话每个参与者一行;通过 {@link #room} 关联主表 {@link ImRtcCallDO}
17 * <p> 17 * <p>
18 * 终态闭合:通话 ENDED 时所有明细 status 必属 {LEFT / REJECTED / NO_ANSWER} 之一 18 * 终态闭合:通话 ENDED 时所有明细 status 必属 {LEFT / REJECTED / NO_ANSWER} 之一
19 * 19 *
@@ -37,9 +37,9 @@ public class ImRtcParticipantDO extends BaseDO { @@ -37,9 +37,9 @@ public class ImRtcParticipantDO extends BaseDO {
37 /** 37 /**
38 * 业务通话编号 38 * 业务通话编号
39 * <p> 39 * <p>
40 - * 关联 {@link ImRtcCallDO#getCallId()} 40 + * 关联 {@link ImRtcCallDO#getRoom()}
41 */ 41 */
42 - private String callId; 42 + private String room;
43 /** 43 /**
44 * 参与者用户编号 44 * 参与者用户编号
45 * <p> 45 * <p>
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/rtc/ImRtcCallMapper.java
@@ -18,12 +18,8 @@ import java.util.List; @@ -18,12 +18,8 @@ import java.util.List;
18 @Mapper 18 @Mapper
19 public interface ImRtcCallMapper extends BaseMapperX<ImRtcCallDO> { 19 public interface ImRtcCallMapper extends BaseMapperX<ImRtcCallDO> {
20 20
21 - default ImRtcCallDO selectByCallId(String callId) {  
22 - return selectOne(ImRtcCallDO::getCallId, callId);  
23 - }  
24 -  
25 - default ImRtcCallDO selectByRoomName(String roomName) {  
26 - return selectOne(ImRtcCallDO::getRoomName, roomName); 21 + default ImRtcCallDO selectByRoom(String room) {
  22 + return selectOne(ImRtcCallDO::getRoom, room);
27 } 23 }
28 24
29 default ImRtcCallDO selectLastOneByGroupIdAndStatusIn(Long groupId, Collection<Integer> statuses) { 25 default ImRtcCallDO selectLastOneByGroupIdAndStatusIn(Long groupId, Collection<Integer> statuses) {
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/rtc/ImRtcParticipantMapper.java
@@ -17,19 +17,19 @@ import java.util.List; @@ -17,19 +17,19 @@ import java.util.List;
17 @Mapper 17 @Mapper
18 public interface ImRtcParticipantMapper extends BaseMapperX<ImRtcParticipantDO> { 18 public interface ImRtcParticipantMapper extends BaseMapperX<ImRtcParticipantDO> {
19 19
20 - default ImRtcParticipantDO selectByCallIdAndUserId(String callId, Long userId) { 20 + default ImRtcParticipantDO selectByRoomAndUserId(String room, Long userId) {
21 return selectOne(new LambdaQueryWrapperX<ImRtcParticipantDO>() 21 return selectOne(new LambdaQueryWrapperX<ImRtcParticipantDO>()
22 - .eq(ImRtcParticipantDO::getCallId, callId) 22 + .eq(ImRtcParticipantDO::getRoom, room)
23 .eq(ImRtcParticipantDO::getUserId, userId)); 23 .eq(ImRtcParticipantDO::getUserId, userId));
24 } 24 }
25 25
26 - default List<ImRtcParticipantDO> selectListByCallId(String callId) {  
27 - return selectList(ImRtcParticipantDO::getCallId, callId); 26 + default List<ImRtcParticipantDO> selectListByRoom(String room) {
  27 + return selectList(ImRtcParticipantDO::getRoom, room);
28 } 28 }
29 29
30 - default List<ImRtcParticipantDO> selectListByCallIdAndStatus(String callId, Integer status) { 30 + default List<ImRtcParticipantDO> selectListByRoomAndStatus(String room, Integer status) {
31 return selectList(new LambdaQueryWrapperX<ImRtcParticipantDO>() 31 return selectList(new LambdaQueryWrapperX<ImRtcParticipantDO>()
32 - .eq(ImRtcParticipantDO::getCallId, callId) 32 + .eq(ImRtcParticipantDO::getRoom, room)
33 .eq(ImRtcParticipantDO::getStatus, status)); 33 .eq(ImRtcParticipantDO::getStatus, status));
34 } 34 }
35 35
@@ -47,9 +47,9 @@ public interface ImRtcParticipantMapper extends BaseMapperX&lt;ImRtcParticipantDO&gt; @@ -47,9 +47,9 @@ public interface ImRtcParticipantMapper extends BaseMapperX&lt;ImRtcParticipantDO&gt;
47 } 47 }
48 48
49 @SuppressWarnings("UnusedReturnValue") 49 @SuppressWarnings("UnusedReturnValue")
50 - default int updateByCallIdAndStatus(String callId, Integer oldStatus, ImRtcParticipantDO updateObj) { 50 + default int updateByRoomAndStatus(String room, Integer oldStatus, ImRtcParticipantDO updateObj) {
51 return update(updateObj, Wrappers.<ImRtcParticipantDO>lambdaUpdate() 51 return update(updateObj, Wrappers.<ImRtcParticipantDO>lambdaUpdate()
52 - .eq(ImRtcParticipantDO::getCallId, callId) 52 + .eq(ImRtcParticipantDO::getRoom, room)
53 .eq(ImRtcParticipantDO::getStatus, oldStatus)); 53 .eq(ImRtcParticipantDO::getStatus, oldStatus));
54 } 54 }
55 55
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/framework/rtc/core/LiveKitClient.java
@@ -62,18 +62,18 @@ public class LiveKitClient { @@ -62,18 +62,18 @@ public class LiveKitClient {
62 * 62 *
63 * @param identity 用户唯一标识;写入 sub claim;同 identity 重连会踢前一个连接 63 * @param identity 用户唯一标识;写入 sub claim;同 identity 重连会踢前一个连接
64 * @param displayName 客户端展示名;可空 64 * @param displayName 客户端展示名;可空
65 - * @param roomName 房间名 65 + * @param room 房间名
66 * @return JWT 字符串 66 * @return JWT 字符串
67 */ 67 */
68 - public String signJoinToken(String identity, String displayName, String roomName) { 68 + public String signJoinToken(String identity, String displayName, String room) {
69 Assert.notBlank(identity, "identity 不可为空"); 69 Assert.notBlank(identity, "identity 不可为空");
70 - Assert.notBlank(roomName, "roomName 不可为空"); 70 + Assert.notBlank(room, "room 不可为空");
71 ImProperties.Rtc cfg = imProperties.getRtc(); 71 ImProperties.Rtc cfg = imProperties.getRtc();
72 72
73 // video claim:限定客户端能在该房间内做什么 73 // video claim:限定客户端能在该房间内做什么
74 Map<String, Object> video = new HashMap<>(); 74 Map<String, Object> video = new HashMap<>();
75 video.put("roomJoin", true); // 允许加入房间 75 video.put("roomJoin", true); // 允许加入房间
76 - video.put("room", roomName); // 限定只能加入这个房间 76 + video.put("room", room); // 限定只能加入这个房间
77 video.put("canPublish", true); // 允许发布媒体(推流) 77 video.put("canPublish", true); // 允许发布媒体(推流)
78 video.put("canSubscribe", true); // 允许订阅媒体(拉流) 78 video.put("canSubscribe", true); // 允许订阅媒体(拉流)
79 video.put("canPublishData", true); // 允许发送 data channel 消息 79 video.put("canPublishData", true); // 允许发送 data channel 消息
@@ -96,11 +96,11 @@ public class LiveKitClient { @@ -96,11 +96,11 @@ public class LiveKitClient {
96 /** 96 /**
97 * 调用 LiveKit Server API 删除房间:用于通话结束时,强制断开异常残留客户端 97 * 调用 LiveKit Server API 删除房间:用于通话结束时,强制断开异常残留客户端
98 * 98 *
99 - * @param roomName 房间名 99 + * @param room 房间名
100 */ 100 */
101 @SuppressWarnings("EmptyTryBlock") 101 @SuppressWarnings("EmptyTryBlock")
102 - public void deleteRoom(String roomName) {  
103 - try (HttpResponse ignored = postTwirp(TWIRP_DELETE_ROOM, roomName)) { 102 + public void deleteRoom(String room) {
  103 + try (HttpResponse ignored = postTwirp(TWIRP_DELETE_ROOM, room)) {
104 // 状态码不区分;调用方失败即兜底 104 // 状态码不区分;调用方失败即兜底
105 } 105 }
106 } 106 }
@@ -110,17 +110,17 @@ public class LiveKitClient { @@ -110,17 +110,17 @@ public class LiveKitClient {
110 * <p> 110 * <p>
111 * 房间不存在 LiveKit 返回 404,视同 0 人 111 * 房间不存在 LiveKit 返回 404,视同 0 人
112 * 112 *
113 - * @param roomName 房间名 113 + * @param room 房间名
114 * @return 参与者数量;HTTP 失败返回 -1 114 * @return 参与者数量;HTTP 失败返回 -1
115 */ 115 */
116 - public int listParticipants(String roomName) {  
117 - try (HttpResponse response = postTwirp(TWIRP_LIST_PARTICIPANTS, roomName)) { 116 + public int listParticipants(String room) {
  117 + try (HttpResponse response = postTwirp(TWIRP_LIST_PARTICIPANTS, room)) {
118 if (response.getStatus() == 404) { 118 if (response.getStatus() == 404) {
119 return 0; 119 return 0;
120 } 120 }
121 if (!response.isOk()) { 121 if (!response.isOk()) {
122 - log.warn("[listParticipants][LiveKit 返回非 2xx status={} roomName={} body={}]",  
123 - response.getStatus(), roomName, response.body()); 122 + log.warn("[listParticipants][LiveKit 返回非 2xx status={} room={} body={}]",
  123 + response.getStatus(), room, response.body());
124 return -1; 124 return -1;
125 } 125 }
126 JSONArray participants = JSONUtil.parseObj(response.body()).getJSONArray("participants"); 126 JSONArray participants = JSONUtil.parseObj(response.body()).getJSONArray("participants");
@@ -223,16 +223,16 @@ public class LiveKitClient { @@ -223,16 +223,16 @@ public class LiveKitClient {
223 * Twirp 协议 POST 调用;统一处理 ws→http 协议切换、签 admin token、Bearer 头、JSON body、超时 223 * Twirp 协议 POST 调用;统一处理 ws→http 协议切换、签 admin token、Bearer 头、JSON body、超时
224 * 224 *
225 * @param path Twirp 端点路径,例如 {@code /twirp/livekit.RoomService/DeleteRoom} 225 * @param path Twirp 端点路径,例如 {@code /twirp/livekit.RoomService/DeleteRoom}
226 - * @param roomName 房间名;写入 JSON body 的 room 字段 226 + * @param room 房间名;写入 JSON body 的 room 字段
227 * @return HTTP 响应;调用方负责 close 与状态码判断 227 * @return HTTP 响应;调用方负责 close 与状态码判断
228 */ 228 */
229 - private HttpResponse postTwirp(String path, String roomName) {  
230 - Assert.notBlank(roomName, "roomName 不可为空"); 229 + private HttpResponse postTwirp(String path, String room) {
  230 + Assert.notBlank(room, "room 不可为空");
231 String token = signAdminToken(); 231 String token = signAdminToken();
232 return HttpRequest.post(HttpUtils.wsUrlToHttp(imProperties.getRtc().getLivekitUrl()) + path) 232 return HttpRequest.post(HttpUtils.wsUrlToHttp(imProperties.getRtc().getLivekitUrl()) + path)
233 .header("Authorization", "Bearer " + token) 233 .header("Authorization", "Bearer " + token)
234 .header("Content-Type", "application/json") 234 .header("Content-Type", "application/json")
235 - .body(JSONUtil.toJsonStr(Map.of("room", roomName))) 235 + .body(JSONUtil.toJsonStr(Map.of("room", room)))
236 .timeout(SERVER_API_TIMEOUT_MS) 236 .timeout(SERVER_API_TIMEOUT_MS)
237 .execute(); 237 .execute();
238 } 238 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/rtc/ImRtcCallService.java
@@ -28,17 +28,17 @@ public interface ImRtcCallService { @@ -28,17 +28,17 @@ public interface ImRtcCallService {
28 /** 28 /**
29 * 加入已有群通话:用于群胶囊条「加入」按钮;旁观者作为 ACTIVE_JOIN 加入,邀请池内成员转 JOINED 29 * 加入已有群通话:用于群胶囊条「加入」按钮;旁观者作为 ACTIVE_JOIN 加入,邀请池内成员转 JOINED
30 * 30 *
31 - * @param userId 加入者用户编号  
32 - * @param roomName LiveKit 房间名;从胶囊条 activeCall 拿 31 + * @param userId 加入者用户编号
  32 + * @param room 业务通话编号;从胶囊条 activeCall 拿
33 * @return 通话主表 33 * @return 通话主表
34 */ 34 */
35 - ImRtcCallDO joinCall(Long userId, String roomName); 35 + ImRtcCallDO joinCall(Long userId, String room);
36 36
37 /** 37 /**
38 * 通话中追加成员:仅群通话场景可用;给新邀请人推 RTC_CALL(INVITE) 38 * 通话中追加成员:仅群通话场景可用;给新邀请人推 RTC_CALL(INVITE)
39 * 39 *
40 * @param userId 操作人编号;必须是当前会话参与者 40 * @param userId 操作人编号;必须是当前会话参与者
41 - * @param reqVO 房间名 + 新邀请的用户编号集合 41 + * @param reqVO room + 新邀请的用户编号集合
42 */ 42 */
43 void inviteMoreCall(Long userId, ImRtcCallInviteMoreReqVO reqVO); 43 void inviteMoreCall(Long userId, ImRtcCallInviteMoreReqVO reqVO);
44 44
@@ -47,22 +47,22 @@ public interface ImRtcCallService { @@ -47,22 +47,22 @@ public interface ImRtcCallService {
47 * 47 *
48 * @return 通话主表 48 * @return 通话主表
49 */ 49 */
50 - ImRtcCallDO acceptCall(Long userId, String roomName); 50 + ImRtcCallDO acceptCall(Long userId, String room);
51 51
52 /** 52 /**
53 * 拒绝通话;仅 INVITING 状态可拒;群通话拒绝等同于不参与,房间仍存在 53 * 拒绝通话;仅 INVITING 状态可拒;群通话拒绝等同于不参与,房间仍存在
54 */ 54 */
55 - void rejectCall(Long userId, String roomName); 55 + void rejectCall(Long userId, String room);
56 56
57 /** 57 /**
58 * 取消邀请;主叫在 INVITING 状态主动取消 58 * 取消邀请;主叫在 INVITING 状态主动取消
59 */ 59 */
60 - void cancelCall(Long userId, String roomName); 60 + void cancelCall(Long userId, String room);
61 61
62 /** 62 /**
63 * 离开通话;RUNNING 状态下离开;私聊任一方离开 = 通话结束;群通话最后一人离开才结束 63 * 离开通话;RUNNING 状态下离开;私聊任一方离开 = 通话结束;群通话最后一人离开才结束
64 */ 64 */
65 - void leaveCall(Long userId, String roomName); 65 + void leaveCall(Long userId, String room);
66 66
67 /** 67 /**
68 * 校验用户仍是该通话的参与者,用于客户端重连或 Token 过期续期前的合法性检查; 68 * 校验用户仍是该通话的参与者,用于客户端重连或 Token 过期续期前的合法性检查;
@@ -70,7 +70,7 @@ public interface ImRtcCallService { @@ -70,7 +70,7 @@ public interface ImRtcCallService {
70 * 70 *
71 * @return 通话主表 71 * @return 通话主表
72 */ 72 */
73 - ImRtcCallDO refreshCallToken(Long userId, String roomName); 73 + ImRtcCallDO refreshCallToken(Long userId, String room);
74 74
75 /** 75 /**
76 * 查询当前正在进行的通话;目前仅群聊场景(胶囊条),私聊未来扩展再补 peerUserId 参数 76 * 查询当前正在进行的通话;目前仅群聊场景(胶囊条),私聊未来扩展再补 peerUserId 参数
@@ -86,19 +86,19 @@ public interface ImRtcCallService { @@ -86,19 +86,19 @@ public interface ImRtcCallService {
86 /** 86 /**
87 * 查询某通话的全部参与者明细;交给 Controller 拼装 inviteeIds / joinedUserIds 87 * 查询某通话的全部参与者明细;交给 Controller 拼装 inviteeIds / joinedUserIds
88 * 88 *
89 - * @param callId 业务通话编号 89 + * @param room 业务通话编号
90 * @return 参与者明细列表 90 * @return 参与者明细列表
91 */ 91 */
92 - List<ImRtcParticipantDO> getCallParticipants(String callId); 92 + List<ImRtcParticipantDO> getCallParticipants(String room);
93 93
94 /** 94 /**
95 * 签发指定用户进入该通话的 LiveKit Token;供 Controller 拼接到响应 VO 95 * 签发指定用户进入该通话的 LiveKit Token;供 Controller 拼接到响应 VO
96 * 96 *
97 - * @param userId 进房用户编号;token 内 displayName 取该用户昵称  
98 - * @param roomName LiveKit 房间名 97 + * @param userId 进房用户编号;token 内 displayName 取该用户昵称
  98 + * @param room 业务通话编号
99 * @return JWT 字符串 99 * @return JWT 字符串
100 */ 100 */
101 - String signCallToken(Long userId, String roomName); 101 + String signCallToken(Long userId, String room);
102 102
103 /** 103 /**
104 * 处理 LiveKit Webhook 事件;用于关 tab / 强杀 / 网络断开等异常退出场景的兜底清理 104 * 处理 LiveKit Webhook 事件;用于关 tab / 强杀 / 网络断开等异常退出场景的兜底清理
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/rtc/ImRtcCallServiceImpl.java
@@ -155,28 +155,26 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -155,28 +155,26 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
155 * @return 通话主表 155 * @return 通话主表
156 */ 156 */
157 private ImRtcCallDO createCall(Long inviterId, ImRtcCallInviteReqVO reqVO) { 157 private ImRtcCallDO createCall(Long inviterId, ImRtcCallInviteReqVO reqVO) {
158 - // 1. 构造参数:派生 callId / roomName,解析被邀请池(私聊单元素;群聊 invitee 子集或全员)  
159 - // TODO @AI:callId、roomName 都抽成小方法。  
160 - String callId = IdUtil.fastSimpleUUID();  
161 - String roomName = ImRtcCallDO.ROOM_NAME_PREFIX + callId; 158 + // 1. 构造参数:room 用 UUID;解析被邀请池
  159 + String room = IdUtil.fastSimpleUUID();
162 LocalDateTime now = LocalDateTime.now(); 160 LocalDateTime now = LocalDateTime.now();
163 Set<Long> invitees = resolveInvitees(reqVO, inviterId); 161 Set<Long> invitees = resolveInvitees(reqVO, inviterId);
164 162
165 // 2.1 INSERT 主表;群聊发起人即时 JOINED 但通话仍处 CREATED,等首个非发起人接通才切 RUNNING 163 // 2.1 INSERT 主表;群聊发起人即时 JOINED 但通话仍处 CREATED,等首个非发起人接通才切 RUNNING
166 - ImRtcCallDO call = new ImRtcCallDO().setCallId(callId).setRoomName(roomName) 164 + ImRtcCallDO call = new ImRtcCallDO().setRoom(room)
167 .setConversationType(reqVO.getScene()).setMediaType(reqVO.getMediaType()) 165 .setConversationType(reqVO.getScene()).setMediaType(reqVO.getMediaType())
168 .setInviterUserId(inviterId).setGroupId(reqVO.getGroupId()) 166 .setInviterUserId(inviterId).setGroupId(reqVO.getGroupId())
169 .setStatus(ImRtcCallStatusEnum.CREATED.getStatus()).setStartTime(now); 167 .setStatus(ImRtcCallStatusEnum.CREATED.getStatus()).setStartTime(now);
170 rtcCallMapper.insert(call); 168 rtcCallMapper.insert(call);
171 // 2.2 批量 INSERT 参与表:发起人即时 JOINED,被邀请人 INVITING 等接通 169 // 2.2 批量 INSERT 参与表:发起人即时 JOINED,被邀请人 INVITING 等接通
172 List<ImRtcParticipantDO> participants = new ArrayList<>(invitees.size() + 1); 170 List<ImRtcParticipantDO> participants = new ArrayList<>(invitees.size() + 1);
173 - participants.add(new ImRtcParticipantDO().setCallId(callId).setUserId(inviterId) 171 + participants.add(new ImRtcParticipantDO().setRoom(room).setUserId(inviterId)
174 .setRole(ImRtcParticipantRoleEnum.INVITER.getRole()) 172 .setRole(ImRtcParticipantRoleEnum.INVITER.getRole())
175 .setStatus(ImRtcParticipantStatusEnum.JOINED.getStatus()) 173 .setStatus(ImRtcParticipantStatusEnum.JOINED.getStatus())
176 .setInviteTime(now).setAcceptTime(now)); 174 .setInviteTime(now).setAcceptTime(now));
177 for (Long inviteeId : invitees) { 175 for (Long inviteeId : invitees) {
178 participants.add(new ImRtcParticipantDO() 176 participants.add(new ImRtcParticipantDO()
179 - .setCallId(callId).setUserId(inviteeId) 177 + .setRoom(room).setUserId(inviteeId)
180 .setRole(ImRtcParticipantRoleEnum.INVITEE.getRole()) 178 .setRole(ImRtcParticipantRoleEnum.INVITEE.getRole())
181 .setStatus(ImRtcParticipantStatusEnum.INVITING.getStatus()) 179 .setStatus(ImRtcParticipantStatusEnum.INVITING.getStatus())
182 .setInviteTime(now)); 180 .setInviteTime(now));
@@ -197,10 +195,10 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -197,10 +195,10 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
197 } 195 }
198 196
199 @Override 197 @Override
200 - public ImRtcCallDO joinCall(Long userId, String roomName) { 198 + public ImRtcCallDO joinCall(Long userId, String room) {
201 ensureEnabled(); 199 ensureEnabled();
202 // 1.1 校验通话存在且活跃 200 // 1.1 校验通话存在且活跃
203 - ImRtcCallDO call = validateCallActive(roomName); 201 + ImRtcCallDO call = validateCallActive(room);
204 // 1.2 仅群通话支持「旁观者加入」 202 // 1.2 仅群通话支持「旁观者加入」
205 if (!ImConversationTypeEnum.isGroup(call.getConversationType())) { 203 if (!ImConversationTypeEnum.isGroup(call.getConversationType())) {
206 throw exception(RTC_GROUP_REQUIRED); 204 throw exception(RTC_GROUP_REQUIRED);
@@ -208,7 +206,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -208,7 +206,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
208 206
209 // 2. 入参与表:已有记录切回 JOINED;不在记录则以 ACTIVE_JOIN 角色 INSERT 207 // 2. 入参与表:已有记录切回 JOINED;不在记录则以 ACTIVE_JOIN 角色 INSERT
210 LocalDateTime now = LocalDateTime.now(); 208 LocalDateTime now = LocalDateTime.now();
211 - ImRtcParticipantDO existing = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 209 + ImRtcParticipantDO existing = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
212 if (existing != null) { 210 if (existing != null) {
213 // 非 JOINED 状态切回 JOINED + accept_time;INVITER / INVITEE 重连 / 旁观点胶囊条都走这条 211 // 非 JOINED 状态切回 JOINED + accept_time;INVITER / INVITEE 重连 / 旁观点胶囊条都走这条
214 if (!ImRtcParticipantStatusEnum.isJoined(existing.getStatus())) { 212 if (!ImRtcParticipantStatusEnum.isJoined(existing.getStatus())) {
@@ -217,7 +215,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -217,7 +215,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
217 } 215 }
218 } else { 216 } else {
219 // 旁观者主动加入:INSERT role=ACTIVE_JOIN 217 // 旁观者主动加入:INSERT role=ACTIVE_JOIN
220 - rtcParticipantMapper.insert(new ImRtcParticipantDO().setCallId(call.getCallId()) 218 + rtcParticipantMapper.insert(new ImRtcParticipantDO().setRoom(call.getRoom())
221 .setUserId(userId).setRole(ImRtcParticipantRoleEnum.ACTIVE_JOIN.getRole()) 219 .setUserId(userId).setRole(ImRtcParticipantRoleEnum.ACTIVE_JOIN.getRole())
222 .setStatus(ImRtcParticipantStatusEnum.JOINED.getStatus()).setInviteTime(now).setAcceptTime(now)); 220 .setStatus(ImRtcParticipantStatusEnum.JOINED.getStatus()).setInviteTime(now).setAcceptTime(now));
223 } 221 }
@@ -231,13 +229,13 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -231,13 +229,13 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
231 public void inviteMoreCall(Long userId, ImRtcCallInviteMoreReqVO reqVO) { 229 public void inviteMoreCall(Long userId, ImRtcCallInviteMoreReqVO reqVO) {
232 ensureEnabled(); 230 ensureEnabled();
233 // TODO @AI:校验的,按照 1.1 1.2 1.3 这样; 231 // TODO @AI:校验的,按照 1.1 1.2 1.3 这样;
234 - ImRtcCallDO call = validateCallActive(reqVO.getRoomName()); 232 + ImRtcCallDO call = validateCallActive(reqVO.getRoom());
235 // 仅群通话支持追加邀请 233 // 仅群通话支持追加邀请
236 if (!ImConversationTypeEnum.isGroup(call.getConversationType())) { 234 if (!ImConversationTypeEnum.isGroup(call.getConversationType())) {
237 throw exception(RTC_GROUP_REQUIRED); 235 throw exception(RTC_GROUP_REQUIRED);
238 } 236 }
239 // 操作者必须是已在房间的参与者 237 // 操作者必须是已在房间的参与者
240 - ImRtcParticipantDO operator = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 238 + ImRtcParticipantDO operator = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
241 if (operator == null || !ImRtcParticipantStatusEnum.isJoined(operator.getStatus())) { 239 if (operator == null || !ImRtcParticipantStatusEnum.isJoined(operator.getStatus())) {
242 throw exception(RTC_NOT_PARTICIPANT); 240 throw exception(RTC_NOT_PARTICIPANT);
243 } 241 }
@@ -246,7 +244,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -246,7 +244,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
246 Set<Long> validMemberIds = new LinkedHashSet<>( 244 Set<Long> validMemberIds = new LinkedHashSet<>(
247 groupMemberService.getActiveGroupMemberUserIdsByGroupId(call.getGroupId())); 245 groupMemberService.getActiveGroupMemberUserIdsByGroupId(call.getGroupId()));
248 // TODO @AI:convertSet; 246 // TODO @AI:convertSet;
249 - Set<Long> existingUserIds = rtcParticipantMapper.selectListByCallId(call.getCallId()).stream() 247 + Set<Long> existingUserIds = rtcParticipantMapper.selectListByRoom(call.getRoom()).stream()
250 .map(ImRtcParticipantDO::getUserId) 248 .map(ImRtcParticipantDO::getUserId)
251 .collect(Collectors.toSet()); 249 .collect(Collectors.toSet());
252 // TODO @AI:incomingUserIds;直接 remove 原始的元素;没必要;单独的; 250 // TODO @AI:incomingUserIds;直接 remove 原始的元素;没必要;单独的;
@@ -262,7 +260,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -262,7 +260,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
262 LocalDateTime now = LocalDateTime.now(); 260 LocalDateTime now = LocalDateTime.now();
263 for (Long inviteeId : incoming) { 261 for (Long inviteeId : incoming) {
264 rtcParticipantMapper.insert(new ImRtcParticipantDO() 262 rtcParticipantMapper.insert(new ImRtcParticipantDO()
265 - .setCallId(call.getCallId()).setUserId(inviteeId) 263 + .setRoom(call.getRoom()).setUserId(inviteeId)
266 .setRole(ImRtcParticipantRoleEnum.INVITEE.getRole()) 264 .setRole(ImRtcParticipantRoleEnum.INVITEE.getRole())
267 .setStatus(ImRtcParticipantStatusEnum.INVITING.getStatus()) 265 .setStatus(ImRtcParticipantStatusEnum.INVITING.getStatus())
268 .setInviteTime(now)); 266 .setInviteTime(now));
@@ -276,11 +274,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -276,11 +274,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
276 } 274 }
277 275
278 @Override 276 @Override
279 - public ImRtcCallDO acceptCall(Long userId, String roomName) { 277 + public ImRtcCallDO acceptCall(Long userId, String room) {
280 ensureEnabled(); 278 ensureEnabled();
281 // TODO @AI:按照 inviteMoreCall 风格,优化下注释; 279 // TODO @AI:按照 inviteMoreCall 风格,优化下注释;
282 - ImRtcCallDO call = validateCallActive(roomName);  
283 - ImRtcParticipantDO participant = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 280 + ImRtcCallDO call = validateCallActive(room);
  281 + ImRtcParticipantDO participant = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
284 if (participant == null) { 282 if (participant == null) {
285 throw exception(RTC_NOT_PARTICIPANT); 283 throw exception(RTC_NOT_PARTICIPANT);
286 } 284 }
@@ -305,11 +303,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -305,11 +303,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
305 } 303 }
306 304
307 @Override 305 @Override
308 - public void rejectCall(Long userId, String roomName) { 306 + public void rejectCall(Long userId, String room) {
309 ensureEnabled(); 307 ensureEnabled();
310 // TODO @AI:按照 inviteMoreCall 风格,优化下注释; 308 // TODO @AI:按照 inviteMoreCall 风格,优化下注释;
311 - ImRtcCallDO call = validateCallActive(roomName);  
312 - ImRtcParticipantDO participant = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 309 + ImRtcCallDO call = validateCallActive(room);
  310 + ImRtcParticipantDO participant = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
313 if (participant == null) { 311 if (participant == null) {
314 throw exception(RTC_NOT_PARTICIPANT); 312 throw exception(RTC_NOT_PARTICIPANT);
315 } 313 }
@@ -337,10 +335,10 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -337,10 +335,10 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
337 } 335 }
338 336
339 @Override 337 @Override
340 - public void cancelCall(Long userId, String roomName) { 338 + public void cancelCall(Long userId, String room) {
341 ensureEnabled(); 339 ensureEnabled();
342 // TODO @AI:按照 inviteMoreCall 风格,优化下注释; 340 // TODO @AI:按照 inviteMoreCall 风格,优化下注释;
343 - ImRtcCallDO call = validateCallActive(roomName); 341 + ImRtcCallDO call = validateCallActive(room);
344 // TODO @AI:notEquals; 342 // TODO @AI:notEquals;
345 if (!Objects.equals(call.getInviterUserId(), userId)) { 343 if (!Objects.equals(call.getInviterUserId(), userId)) {
346 throw exception(RTC_NOT_PARTICIPANT); 344 throw exception(RTC_NOT_PARTICIPANT);
@@ -355,11 +353,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -355,11 +353,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
355 } 353 }
356 354
357 @Override 355 @Override
358 - public void leaveCall(Long userId, String roomName) { 356 + public void leaveCall(Long userId, String room) {
359 ensureEnabled(); 357 ensureEnabled();
360 // TODO @AI:按照 inviteMoreCall 风格,优化下注释; 358 // TODO @AI:按照 inviteMoreCall 风格,优化下注释;
361 - ImRtcCallDO call = validateCallActive(roomName);  
362 - ImRtcParticipantDO participant = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 359 + ImRtcCallDO call = validateCallActive(room);
  360 + ImRtcParticipantDO participant = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
363 if (participant == null) { 361 if (participant == null) {
364 throw exception(RTC_NOT_PARTICIPANT); 362 throw exception(RTC_NOT_PARTICIPANT);
365 } 363 }
@@ -373,7 +371,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -373,7 +371,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
373 // TODO @AI:群聊的关房,本质和单聊,是不是一样的?是否有必要统一掉? 371 // TODO @AI:群聊的关房,本质和单聊,是不是一样的?是否有必要统一掉?
374 // 关房条件:私聊任一方离开 = 关;群通话仅在「无人在房 + 无人响铃」时关 372 // 关房条件:私聊任一方离开 = 关;群通话仅在「无人在房 + 无人响铃」时关
375 if (ImConversationTypeEnum.isPrivate(call.getConversationType()) 373 if (ImConversationTypeEnum.isPrivate(call.getConversationType())
376 - || shouldCloseGroupRoom(call.getCallId())) { 374 + || shouldCloseGroupRoom(call.getRoom())) {
377 endSession(call, userId, ImRtcCallEndReasonEnum.HANGUP); 375 endSession(call, userId, ImRtcCallEndReasonEnum.HANGUP);
378 } 376 }
379 // 群通话单人离开:LiveKit `ParticipantDisconnected` 自动通知房内成员;业务后端不另外推 377 // 群通话单人离开:LiveKit `ParticipantDisconnected` 自动通知房内成员;业务后端不另外推
@@ -386,9 +384,9 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -386,9 +384,9 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
386 * <p> 384 * <p>
387 * 关房后 endSession 会把残留 INVITING 批量改 NO_ANSWER 并推 RTC_CALL_END,响铃端 UI 自动收敛 385 * 关房后 endSession 会把残留 INVITING 批量改 NO_ANSWER 并推 RTC_CALL_END,响铃端 UI 自动收敛
388 */ 386 */
389 - private boolean shouldCloseGroupRoom(String callId) { 387 + private boolean shouldCloseGroupRoom(String room) {
390 // TODO @AI:通过查询,计算情况?;感觉所有群聊的关闭条件:都是只有 1 个 join,剩余都处于结束,说白了没人可以和他电话了。。。。 388 // TODO @AI:通过查询,计算情况?;感觉所有群聊的关闭条件:都是只有 1 个 join,剩余都处于结束,说白了没人可以和他电话了。。。。
391 - List<ImRtcParticipantDO> joined = rtcParticipantMapper.selectListByCallIdAndStatus(callId, 389 + List<ImRtcParticipantDO> joined = rtcParticipantMapper.selectListByRoomAndStatus(room,
392 ImRtcParticipantStatusEnum.JOINED.getStatus()); 390 ImRtcParticipantStatusEnum.JOINED.getStatus());
393 return CollUtil.isEmpty(joined); 391 return CollUtil.isEmpty(joined);
394 } 392 }
@@ -406,13 +404,13 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -406,13 +404,13 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
406 if (aPart == null) { 404 if (aPart == null) {
407 return null; 405 return null;
408 } 406 }
409 - ImRtcCallDO call = rtcCallMapper.selectByCallId(aPart.getCallId()); 407 + ImRtcCallDO call = rtcCallMapper.selectByRoom(aPart.getRoom());
410 if (call == null 408 if (call == null
411 || !ImConversationTypeEnum.isPrivate(call.getConversationType()) 409 || !ImConversationTypeEnum.isPrivate(call.getConversationType())
412 || ImRtcCallStatusEnum.isEnded(call.getStatus())) { 410 || ImRtcCallStatusEnum.isEnded(call.getStatus())) {
413 return null; 411 return null;
414 } 412 }
415 - ImRtcParticipantDO bPart = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userIdB); 413 + ImRtcParticipantDO bPart = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userIdB);
416 if (bPart == null 414 if (bPart == null
417 || !ImRtcParticipantStatusEnum.ACTIVE_STATUSES.contains(bPart.getStatus())) { 415 || !ImRtcParticipantStatusEnum.ACTIVE_STATUSES.contains(bPart.getStatus())) {
418 return null; 416 return null;
@@ -422,11 +420,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -422,11 +420,11 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
422 420
423 // TODO @AI:怎么感觉这个要改下?是不是根据 userid + callid 更合理? 421 // TODO @AI:怎么感觉这个要改下?是不是根据 userid + callid 更合理?
424 @Override 422 @Override
425 - public ImRtcCallDO refreshCallToken(Long userId, String roomName) { 423 + public ImRtcCallDO refreshCallToken(Long userId, String room) {
426 ensureEnabled(); 424 ensureEnabled();
427 // TODO @AI:按照 inviteMoreCall 风格,优化下注释; 425 // TODO @AI:按照 inviteMoreCall 风格,优化下注释;
428 - ImRtcCallDO call = validateCallActive(roomName);  
429 - ImRtcParticipantDO participant = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 426 + ImRtcCallDO call = validateCallActive(room);
  427 + ImRtcParticipantDO participant = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
430 if (participant == null) { 428 if (participant == null) {
431 throw exception(RTC_NOT_PARTICIPANT); 429 throw exception(RTC_NOT_PARTICIPANT);
432 } 430 }
@@ -444,16 +442,16 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -444,16 +442,16 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
444 442
445 // TODO @AI:方法名,复数应该使用 List,不使用 s; 443 // TODO @AI:方法名,复数应该使用 List,不使用 s;
446 @Override 444 @Override
447 - public List<ImRtcParticipantDO> getCallParticipants(String callId) {  
448 - return rtcParticipantMapper.selectListByCallId(callId); 445 + public List<ImRtcParticipantDO> getCallParticipants(String room) {
  446 + return rtcParticipantMapper.selectListByRoom(room);
449 } 447 }
450 448
451 @Override 449 @Override
452 - public String signCallToken(Long userId, String roomName) { 450 + public String signCallToken(Long userId, String room) {
453 AdminUserRespDTO user = adminUserApi.getUser(userId); 451 AdminUserRespDTO user = adminUserApi.getUser(userId);
454 // TODO @AI:不能为空。。。nickname 为空,则使用 userid; 452 // TODO @AI:不能为空。。。nickname 为空,则使用 userid;
455 String displayName = user == null ? null : user.getNickname(); 453 String displayName = user == null ? null : user.getNickname();
456 - return signToken(userId, displayName, roomName); 454 + return signToken(userId, displayName, room);
457 } 455 }
458 456
459 // TODO DONE @AI:兼容 JDK8 —— 项目 Spring Boot 3 已要求 JDK17+,switch arrow case 可直接用 457 // TODO DONE @AI:兼容 JDK8 —— 项目 Spring Boot 3 已要求 JDK17+,switch arrow case 可直接用
@@ -483,8 +481,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -483,8 +481,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
483 return; 481 return;
484 } 482 }
485 // 前置检查 483 // 前置检查
486 - String roomName = event.getRoom().getName();  
487 - ImRtcCallDO call = rtcCallMapper.selectByRoomName(roomName); 484 + String room = event.getRoom().getName();
  485 + ImRtcCallDO call = rtcCallMapper.selectByRoom(room);
488 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) { 486 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) {
489 return; 487 return;
490 } 488 }
@@ -506,8 +504,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -506,8 +504,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
506 return; 504 return;
507 } 505 }
508 // 前置检查 506 // 前置检查
509 - String roomName = event.getRoom().getName();  
510 - ImRtcCallDO call = rtcCallMapper.selectByRoomName(roomName); 507 + String room = event.getRoom().getName();
  508 + ImRtcCallDO call = rtcCallMapper.selectByRoom(room);
511 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) { 509 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) {
512 return; 510 return;
513 } 511 }
@@ -515,7 +513,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -515,7 +513,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
515 if (userId == null) { 513 if (userId == null) {
516 return; 514 return;
517 } 515 }
518 - ImRtcParticipantDO participant = rtcParticipantMapper.selectByCallIdAndUserId(call.getCallId(), userId); 516 + ImRtcParticipantDO participant = rtcParticipantMapper.selectByRoomAndUserId(call.getRoom(), userId);
519 if (participant == null || !ImRtcParticipantStatusEnum.isJoined(participant.getStatus())) { 517 if (participant == null || !ImRtcParticipantStatusEnum.isJoined(participant.getStatus())) {
520 return; 518 return;
521 } 519 }
@@ -526,14 +524,14 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -526,14 +524,14 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
526 if (updated == 0) { 524 if (updated == 0) {
527 return; 525 return;
528 } 526 }
529 - log.info("[handleParticipantLeft][roomName={} userId={} 由 LiveKit Webhook 兜底]", roomName, userId); 527 + log.info("[handleParticipantLeft][room={} userId={} 由 LiveKit Webhook 兜底]", room, userId);
530 528
531 // 推 1603 通知参与方 / 全群参与方 529 // 推 1603 通知参与方 / 全群参与方
532 pushParticipantDisconnectedNotification(call, userId); 530 pushParticipantDisconnectedNotification(call, userId);
533 // 关房条件与 leave 一致;群通话仅在「无人在房 + 无人响铃」时关 531 // 关房条件与 leave 一致;群通话仅在「无人在房 + 无人响铃」时关
534 // TODO @AI:注释风格;感觉可以抽个 endSessionIfXXX;收口更统一; 532 // TODO @AI:注释风格;感觉可以抽个 endSessionIfXXX;收口更统一;
535 if (ImConversationTypeEnum.isPrivate(call.getConversationType()) 533 if (ImConversationTypeEnum.isPrivate(call.getConversationType())
536 - || shouldCloseGroupRoom(call.getCallId())) { 534 + || shouldCloseGroupRoom(call.getRoom())) {
537 endSession(call, userId, ImRtcCallEndReasonEnum.HANGUP); 535 endSession(call, userId, ImRtcCallEndReasonEnum.HANGUP);
538 } 536 }
539 } 537 }
@@ -546,14 +544,14 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -546,14 +544,14 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
546 return; 544 return;
547 } 545 }
548 // 前置检查 546 // 前置检查
549 - String roomName = event.getRoom().getName();  
550 - ImRtcCallDO call = rtcCallMapper.selectByRoomName(roomName); 547 + String room = event.getRoom().getName();
  548 + ImRtcCallDO call = rtcCallMapper.selectByRoom(room);
551 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) { 549 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) {
552 return; 550 return;
553 } 551 }
554 552
555 // TODO @AI:注释。带序号的; 553 // TODO @AI:注释。带序号的;
556 - log.info("[handleRoomFinished][roomName={} 由 LiveKit Webhook 兜底]", roomName); 554 + log.info("[handleRoomFinished][room={} 由 LiveKit Webhook 兜底]", room);
557 endSession(call, null, ImRtcCallEndReasonEnum.HANGUP); 555 endSession(call, null, ImRtcCallEndReasonEnum.HANGUP);
558 } 556 }
559 557
@@ -572,17 +570,15 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -572,17 +570,15 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
572 for (ImRtcCallDO call : candidates) { 570 for (ImRtcCallDO call : candidates) {
573 int count; 571 int count;
574 try { 572 try {
575 - count = liveKitClient.listParticipants(call.getRoomName()); 573 + count = liveKitClient.listParticipants(call.getRoom());
576 } catch (Exception e) { 574 } catch (Exception e) {
577 - log.warn("[cleanupZombieCalls][查询 LiveKit 失败 callId={} roomName={}]",  
578 - call.getCallId(), call.getRoomName(), e); 575 + log.warn("[cleanupZombieCalls][查询 LiveKit 失败 room={}]", call.getRoom(), e);
579 continue; 576 continue;
580 } 577 }
581 if (count != 0) { 578 if (count != 0) {
582 continue; 579 continue;
583 } 580 }
584 - log.info("[cleanupZombieCalls][清理僵尸通话 callId={} roomName={}]",  
585 - call.getCallId(), call.getRoomName()); 581 + log.info("[cleanupZombieCalls][清理僵尸通话 room={}]", call.getRoom());
586 endSession(call, null, ImRtcCallEndReasonEnum.HANGUP); 582 endSession(call, null, ImRtcCallEndReasonEnum.HANGUP);
587 cleaned++; 583 cleaned++;
588 } 584 }
@@ -604,8 +600,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -604,8 +600,8 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
604 /** 600 /**
605 * 校验通话存在且活跃:不存在 / 已 ENDED 直接抛 601 * 校验通话存在且活跃:不存在 / 已 ENDED 直接抛
606 */ 602 */
607 - private ImRtcCallDO validateCallActive(String roomName) {  
608 - ImRtcCallDO call = rtcCallMapper.selectByRoomName(roomName); 603 + private ImRtcCallDO validateCallActive(String room) {
  604 + ImRtcCallDO call = rtcCallMapper.selectByRoom(room);
609 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) { 605 if (call == null || ImRtcCallStatusEnum.isEnded(call.getStatus())) {
610 throw exception(RTC_SESSION_NOT_EXISTS); 606 throw exception(RTC_SESSION_NOT_EXISTS);
611 } 607 }
@@ -729,29 +725,29 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -729,29 +725,29 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
729 new ImRtcCallDO().setStatus(ImRtcCallStatusEnum.ENDED.getStatus()) 725 new ImRtcCallDO().setStatus(ImRtcCallStatusEnum.ENDED.getStatus())
730 .setEndReason(reason.getReason()).setEndTime(now)); 726 .setEndReason(reason.getReason()).setEndTime(now));
731 if (updated == 0) { 727 if (updated == 0) {
732 - log.info("[endSession][已被另一路径终结,跳过 callId={} roomName={} operator={} reason={}]",  
733 - call.getCallId(), call.getRoomName(), operatorId, reason); 728 + log.info("[endSession][已被另一路径终结,跳过 room={} operator={} reason={}]",
  729 + call.getRoom(), operatorId, reason);
734 return; 730 return;
735 } 731 }
736 // 1.2 更新参与表为已结束:残留 INVITING 改 NO_ANSWER;残留 JOINED 改 LEFT 并写 leaveTime 732 // 1.2 更新参与表为已结束:残留 INVITING 改 NO_ANSWER;残留 JOINED 改 LEFT 并写 leaveTime
737 - rtcParticipantMapper.updateByCallIdAndStatus(call.getCallId(), ImRtcParticipantStatusEnum.INVITING.getStatus(), 733 + rtcParticipantMapper.updateByRoomAndStatus(call.getRoom(), ImRtcParticipantStatusEnum.INVITING.getStatus(),
738 new ImRtcParticipantDO().setStatus(ImRtcParticipantStatusEnum.NO_ANSWER.getStatus())); 734 new ImRtcParticipantDO().setStatus(ImRtcParticipantStatusEnum.NO_ANSWER.getStatus()));
739 - rtcParticipantMapper.updateByCallIdAndStatus(call.getCallId(), ImRtcParticipantStatusEnum.JOINED.getStatus(), 735 + rtcParticipantMapper.updateByRoomAndStatus(call.getRoom(), ImRtcParticipantStatusEnum.JOINED.getStatus(),
740 new ImRtcParticipantDO().setStatus(ImRtcParticipantStatusEnum.LEFT.getStatus()).setLeaveTime(now)); 736 new ImRtcParticipantDO().setStatus(ImRtcParticipantStatusEnum.LEFT.getStatus()).setLeaveTime(now));
741 737
742 // 2. 兜底删除 LiveKit 房间,强制断开异常残留客户端;失败仅记日志,不阻断业务 738 // 2. 兜底删除 LiveKit 房间,强制断开异常残留客户端;失败仅记日志,不阻断业务
743 try { 739 try {
744 - liveKitClient.deleteRoom(call.getRoomName()); 740 + liveKitClient.deleteRoom(call.getRoom());
745 } catch (Exception e) { 741 } catch (Exception e) {
746 - log.warn("[endSession][删除 LiveKit 房间失败 callId={} roomName={} operator={} reason={}]",  
747 - call.getCallId(), call.getRoomName(), operatorId, reason, e); 742 + log.warn("[endSession][删除 LiveKit 房间失败 room={} operator={} reason={}]",
  743 + call.getRoom(), operatorId, reason, e);
748 } 744 }
749 745
750 // 3. 推 RTC_CALL_END 746 // 3. 推 RTC_CALL_END
751 Long durationSeconds = call.getAcceptTime() != null ? 747 Long durationSeconds = call.getAcceptTime() != null ?
752 Duration.between(call.getAcceptTime(), now).getSeconds() : null; 748 Duration.between(call.getAcceptTime(), now).getSeconds() : null;
753 pushCallEndNotification(call, operatorId, reason, durationSeconds); 749 pushCallEndNotification(call, operatorId, reason, durationSeconds);
754 - log.info("[endSession][roomName={} operator={} reason={}]", call.getRoomName(), operatorId, reason); 750 + log.info("[endSession][room={} operator={} reason={}]", call.getRoom(), operatorId, reason);
755 } 751 }
756 752
757 // TODO @AI:getCallAudienceUserIdList? 753 // TODO @AI:getCallAudienceUserIdList?
@@ -765,7 +761,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -765,7 +761,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
765 return groupMemberService.getActiveGroupMemberUserIdsByGroupId(call.getGroupId()); 761 return groupMemberService.getActiveGroupMemberUserIdsByGroupId(call.getGroupId());
766 } 762 }
767 return CollectionUtils.convertSet( 763 return CollectionUtils.convertSet(
768 - rtcParticipantMapper.selectListByCallId(call.getCallId()), ImRtcParticipantDO::getUserId); 764 + rtcParticipantMapper.selectListByRoom(call.getRoom()), ImRtcParticipantDO::getUserId);
769 } 765 }
770 766
771 // TODO @AI:这里的 ========== 太短了; 767 // TODO @AI:这里的 ========== 太短了;
@@ -779,7 +775,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -779,7 +775,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
779 * 不能走 imPrivateMessageService.send:persistent=false 时 send 仅推 sender 多端,receiver 不感知 775 * 不能走 imPrivateMessageService.send:persistent=false 时 send 仅推 sender 多端,receiver 不感知
780 */ 776 */
781 private void pushCallInviteNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Long inviteeId) { 777 private void pushCallInviteNotification(ImRtcCallDO call, AdminUserRespDTO inviter, Long inviteeId) {
782 - String token = signToken(inviteeId, inviter == null ? null : inviter.getNickname(), call.getRoomName()); 778 + String token = signToken(inviteeId, inviter == null ? null : inviter.getNickname(), call.getRoom());
783 ImRtcCallNotification payload = ImRtcCallNotification.ofInvite( 779 ImRtcCallNotification payload = ImRtcCallNotification.ofInvite(
784 call, inviter, imProperties.getRtc().getLivekitUrl(), token); 780 call, inviter, imProperties.getRtc().getLivekitUrl(), token);
785 webSocketService.sendPrivateMessageAsync(inviteeId, ImPrivateMessageDTO.ofRtcNotification( 781 webSocketService.sendPrivateMessageAsync(inviteeId, ImPrivateMessageDTO.ofRtcNotification(
@@ -865,7 +861,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -865,7 +861,7 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
865 861
866 // 私聊:发起人总是 sender;receiver = 通话另一方 862 // 私聊:发起人总是 sender;receiver = 通话另一方
867 ImRtcParticipantDO peer = CollUtil.findOne( 863 ImRtcParticipantDO peer = CollUtil.findOne(
868 - rtcParticipantMapper.selectListByCallId(call.getCallId()), 864 + rtcParticipantMapper.selectListByRoom(call.getRoom()),
869 p -> !Objects.equals(p.getUserId(), senderId)); 865 p -> !Objects.equals(p.getUserId(), senderId));
870 Long receiverId = peer != null ? peer.getUserId() : senderId; 866 Long receiverId = peer != null ? peer.getUserId() : senderId;
871 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO().setReceiverId(receiverId) 867 ImPrivateMessageSendDTO dto = new ImPrivateMessageSendDTO().setReceiverId(receiverId)
@@ -879,9 +875,9 @@ public class ImRtcCallServiceImpl implements ImRtcCallService { @@ -879,9 +875,9 @@ public class ImRtcCallServiceImpl implements ImRtcCallService {
879 * 签 LiveKit Token 875 * 签 LiveKit Token
880 */ 876 */
881 // TODO @AI:sign 方法,是不是传递 adminuserdo? 877 // TODO @AI:sign 方法,是不是传递 adminuserdo?
882 - private String signToken(Long userId, String displayName, String roomName) {  
883 - // TODO @AI:是不是抽一个 signJoinToken(userid, displayName, roomName)做减法  
884 - return liveKitClient.signJoinToken(liveKitClient.buildIdentity(userId), displayName, roomName); 878 + private String signToken(Long userId, String displayName, String room) {
  879 + // TODO @AI:是不是抽一个 signJoinToken(userid, displayName, room)做减法
  880 + return liveKitClient.signJoinToken(liveKitClient.buildIdentity(userId), displayName, room);
885 } 881 }
886 882
887 } 883 }
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallEndNotification.java
@@ -25,7 +25,7 @@ public class ImRtcCallEndNotification { @@ -25,7 +25,7 @@ public class ImRtcCallEndNotification {
25 /** 25 /**
26 * 业务通话编号 26 * 业务通话编号
27 */ 27 */
28 - private String callId; 28 + private String room;
29 /** 29 /**
30 * 会话类型 30 * 会话类型
31 */ 31 */
@@ -60,7 +60,7 @@ public class ImRtcCallEndNotification { @@ -60,7 +60,7 @@ public class ImRtcCallEndNotification {
60 public static ImRtcCallEndNotification of(ImRtcCallDO call, ImRtcCallEndReasonEnum reason, Long durationSeconds, 60 public static ImRtcCallEndNotification of(ImRtcCallDO call, ImRtcCallEndReasonEnum reason, Long durationSeconds,
61 Long operatorId, AdminUserRespDTO operator) { 61 Long operatorId, AdminUserRespDTO operator) {
62 ImRtcCallEndNotification notification = new ImRtcCallEndNotification(); 62 ImRtcCallEndNotification notification = new ImRtcCallEndNotification();
63 - notification.callId = call.getCallId(); 63 + notification.room = call.getRoom();
64 notification.conversationType = call.getConversationType(); 64 notification.conversationType = call.getConversationType();
65 notification.mediaType = call.getMediaType(); 65 notification.mediaType = call.getMediaType();
66 notification.endReason = reason.getReason(); 66 notification.endReason = reason.getReason();
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallNotification.java
@@ -27,11 +27,7 @@ public class ImRtcCallNotification { @@ -27,11 +27,7 @@ public class ImRtcCallNotification {
27 /** 27 /**
28 * 业务通话编号 28 * 业务通话编号
29 */ 29 */
30 - private String callId;  
31 - /**  
32 - * LiveKit 房间名  
33 - */  
34 - private String roomName; 30 + private String room;
35 /** 31 /**
36 * 会话类型 32 * 会话类型
37 */ 33 */
@@ -176,8 +172,7 @@ public class ImRtcCallNotification { @@ -176,8 +172,7 @@ public class ImRtcCallNotification {
176 private static ImRtcCallNotification baseOf(ImRtcCallDO call, Integer status) { 172 private static ImRtcCallNotification baseOf(ImRtcCallDO call, Integer status) {
177 ImRtcCallNotification notification = new ImRtcCallNotification(); 173 ImRtcCallNotification notification = new ImRtcCallNotification();
178 notification.status = status; 174 notification.status = status;
179 - notification.callId = call.getCallId();  
180 - notification.roomName = call.getRoomName(); 175 + notification.room = call.getRoom();
181 notification.conversationType = call.getConversationType(); 176 notification.conversationType = call.getConversationType();
182 notification.mediaType = call.getMediaType(); 177 notification.mediaType = call.getMediaType();
183 notification.groupId = call.getGroupId(); 178 notification.groupId = call.getGroupId();
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcCallStartNotification.java
@@ -23,7 +23,7 @@ public class ImRtcCallStartNotification { @@ -23,7 +23,7 @@ public class ImRtcCallStartNotification {
23 /** 23 /**
24 * 业务通话编号 24 * 业务通话编号
25 */ 25 */
26 - private String callId; 26 + private String room;
27 /** 27 /**
28 * 会话类型:当前固定 GROUP(私聊无 START) 28 * 会话类型:当前固定 GROUP(私聊无 START)
29 */ 29 */
@@ -47,7 +47,7 @@ public class ImRtcCallStartNotification { @@ -47,7 +47,7 @@ public class ImRtcCallStartNotification {
47 47
48 public static ImRtcCallStartNotification of(ImRtcCallDO call, AdminUserRespDTO inviter) { 48 public static ImRtcCallStartNotification of(ImRtcCallDO call, AdminUserRespDTO inviter) {
49 ImRtcCallStartNotification notification = new ImRtcCallStartNotification(); 49 ImRtcCallStartNotification notification = new ImRtcCallStartNotification();
50 - notification.callId = call.getCallId(); 50 + notification.room = call.getRoom();
51 notification.conversationType = call.getConversationType(); 51 notification.conversationType = call.getConversationType();
52 notification.mediaType = call.getMediaType(); 52 notification.mediaType = call.getMediaType();
53 notification.inviterUserId = call.getInviterUserId(); 53 notification.inviterUserId = call.getInviterUserId();
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcParticipantConnectedNotification.java
@@ -18,11 +18,7 @@ public class ImRtcParticipantConnectedNotification { @@ -18,11 +18,7 @@ public class ImRtcParticipantConnectedNotification {
18 /** 18 /**
19 * 业务通话编号 19 * 业务通话编号
20 */ 20 */
21 - private String callId;  
22 - /**  
23 - * LiveKit 房间名  
24 - */  
25 - private String roomName; 21 + private String room;
26 /** 22 /**
27 * 加入的参与者用户编号 23 * 加入的参与者用户编号
28 */ 24 */
@@ -53,8 +49,7 @@ public class ImRtcParticipantConnectedNotification { @@ -53,8 +49,7 @@ public class ImRtcParticipantConnectedNotification {
53 */ 49 */
54 public static ImRtcParticipantConnectedNotification of(ImRtcCallDO call, Long userId) { 50 public static ImRtcParticipantConnectedNotification of(ImRtcCallDO call, Long userId) {
55 ImRtcParticipantConnectedNotification notification = new ImRtcParticipantConnectedNotification(); 51 ImRtcParticipantConnectedNotification notification = new ImRtcParticipantConnectedNotification();
56 - notification.callId = call.getCallId();  
57 - notification.roomName = call.getRoomName(); 52 + notification.room = call.getRoom();
58 notification.userId = userId; 53 notification.userId = userId;
59 notification.conversationType = call.getConversationType(); 54 notification.conversationType = call.getConversationType();
60 notification.groupId = call.getGroupId(); 55 notification.groupId = call.getGroupId();
yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/websocket/dto/notification/rtc/ImRtcParticipantDisconnectedNotification.java
@@ -18,11 +18,7 @@ public class ImRtcParticipantDisconnectedNotification { @@ -18,11 +18,7 @@ public class ImRtcParticipantDisconnectedNotification {
18 /** 18 /**
19 * 业务通话编号 19 * 业务通话编号
20 */ 20 */
21 - private String callId;  
22 - /**  
23 - * LiveKit 房间名  
24 - */  
25 - private String roomName; 21 + private String room;
26 /** 22 /**
27 * 离开的参与者用户编号 23 * 离开的参与者用户编号
28 */ 24 */
@@ -45,8 +41,7 @@ public class ImRtcParticipantDisconnectedNotification { @@ -45,8 +41,7 @@ public class ImRtcParticipantDisconnectedNotification {
45 */ 41 */
46 public static ImRtcParticipantDisconnectedNotification of(ImRtcCallDO call, Long userId) { 42 public static ImRtcParticipantDisconnectedNotification of(ImRtcCallDO call, Long userId) {
47 ImRtcParticipantDisconnectedNotification notification = new ImRtcParticipantDisconnectedNotification(); 43 ImRtcParticipantDisconnectedNotification notification = new ImRtcParticipantDisconnectedNotification();
48 - notification.callId = call.getCallId();  
49 - notification.roomName = call.getRoomName(); 44 + notification.room = call.getRoom();
50 notification.userId = userId; 45 notification.userId = userId;
51 notification.conversationType = call.getConversationType(); 46 notification.conversationType = call.getConversationType();
52 notification.groupId = call.getGroupId(); 47 notification.groupId = call.getGroupId();