feat: 优化视频通话逻辑

This commit is contained in:
曹鹏飞 2025-08-08 18:27:18 +08:00
parent c83cebf5f6
commit 29c5a1e556
17 changed files with 309 additions and 131 deletions

View File

@ -1,9 +1,9 @@
package com.nflg.mobilebroken.admin.controller;
import com.nflg.mobilebroken.admin.pojo.dto.ShengWangChannelDTO;
import com.nflg.mobilebroken.admin.pojo.dto.ShengWangKickingRuleListItemDTO;
import com.nflg.mobilebroken.admin.service.ShengWangService;
import com.nflg.mobilebroken.common.pojo.ApiResult;
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelDTO;
import com.nflg.mobilebroken.common.pojo.dto.ShengWangKickingRuleListItemDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

View File

@ -130,11 +130,11 @@ public class TicketController extends ControllerBase {
@Resource
private UniPushService uniPushService;
@Resource
private ITicketCallService ticketCallService;
@Resource
private ITicketCallJoinService ticketCallJoinService;
// @Resource
// private ITicketCallService ticketCallService;
//
// @Resource
// private ITicketCallJoinService ticketCallJoinService;
/**
* 获取问题类型
@ -1256,7 +1256,6 @@ public class TicketController extends ControllerBase {
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getUserId(), AdminUserUtil.getUserId()) && !Objects.equals(AdminUserUtil.getUserId(), handlerUserId))
.throwMessage("无权限呼叫");
}
VUtils.trueThrowBusinessError(ticketCallService.isInCall(ticket.getUserId())).throwMessage("对方正在通话中");
boolean userIdCreate = StrUtil.equals(ticket.getUserPlatform(), Constant.FROM_ADMIN) && Objects.equals(ticket.getUserId(), AdminUserUtil.getUserId());
Integer sendUserId = 0, receiveUserId = 0;
String sendUserFrom, receiveUserFrom;
@ -1271,7 +1270,8 @@ public class TicketController extends ControllerBase {
sendUserFrom = Constant.FROM_ADMIN;
receiveUserFrom = Constant.FROM_APP;
}
ticketCallService.add(ticketId, sendUserId, sendUserFrom, receiveUserId, receiveUserFrom);
// VUtils.trueThrowBusinessError(ticketCallJoinService.isInCall(ticket.getId(), receiveUserFrom, receiveUserId)).throwMessage("对方正在通话中");
// ticketCallService.add(ticketId, sendUserId, sendUserFrom, receiveUserId, receiveUserFrom);
AdminUser adminUser = adminUserService.getById(sendUserId);
uniPushService.send(new UniPushMessage()
.setSenderId("admin-uid-" + sendUserId)
@ -1306,11 +1306,11 @@ public class TicketController extends ControllerBase {
@PostMapping("addCallUser")
public ApiResult<Void> addCallUser(@Valid @RequestBody CallUserAddRequest request){
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
TicketCall ticketCall = ticketCallService.lambdaQuery()
.eq(TicketCall::getTicketId, request.getTicketId())
.eq(TicketCall::getState, 1)
.one();
VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("未在通话中");
// TicketCall ticketCall = ticketCallService.lambdaQuery()
// .eq(TicketCall::getTicketId, request.getTicketId())
// .eq(TicketCall::getState, 1)
// .one();
// VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("未在通话中");
request.getUserIds().forEach(userId->{
AdminUser adminUser1 = adminUserService.getById(userId);
if (Objects.nonNull(adminUser1)) {
@ -1331,7 +1331,7 @@ public class TicketController extends ControllerBase {
)
);
ssePushService.sendTicketCallToAdmin(adminUser, userId, request.getTicketId());
ticketCallJoinService.add(ticketCall.getId(), userId, Constant.FROM_ADMIN);
// ticketCallJoinService.add(ticketCall.getId(), userId, Constant.FROM_ADMIN);
}
});
return ApiResult.success();
@ -1347,24 +1347,24 @@ public class TicketController extends ControllerBase {
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
.throwMessage("当前工单状态不允许请求通话");
VUtils.trueThrowBusinessError(ticketCallService.isInCall(AdminUserUtil.getUserId()))
.throwMessage("您已加入别的通话中");
ticketCallJoinService.join(ticketId, AdminUserUtil.getUserId(),Constant.FROM_ADMIN);
ssePushService.sendTicketCallJoinedToAdmin(AdminUserUtil.getUserId(), ticketId);
uniPushService.send(new UniPushMessage()
.setSenderId("admin-uid-" + AdminUserUtil.getUserId())//不重要
.setReceiverId("admin-uid-" + AdminUserUtil.getUserId())
.setSendData(new UniPushMessageBody()
.setTitle("视频通话")
.setContent("您已加入别的通话中")
.setPayload(new UniPushMessageCallPayload()
.setTicketId(ticketId)
.setUserId(AdminUserUtil.getUserId())
.setCategory("ticketCallJoined")
.setFrom("admin")
)
)
);
// VUtils.trueThrowBusinessError(ticketCallJoinService.isInCall(ticket.getId(), Constant.FROM_ADMIN, AdminUserUtil.getUserId()))
// .throwMessage("您已加入别的通话中");
// ticketCallJoinService.join(ticketId, AdminUserUtil.getUserId(),Constant.FROM_ADMIN);
// ssePushService.sendTicketCallJoinedToAdmin(AdminUserUtil.getUserId(), ticketId);
// uniPushService.send(new UniPushMessage()
// .setSenderId("admin-uid-" + AdminUserUtil.getUserId())//不重要
// .setReceiverId("admin-uid-" + AdminUserUtil.getUserId())
// .setSendData(new UniPushMessageBody()
// .setTitle("视频通话")
// .setContent("您已加入别的通话中")
// .setPayload(new UniPushMessageCallPayload()
// .setTicketId(ticketId)
// .setUserId(AdminUserUtil.getUserId())
// .setCategory("ticketCallJoined")
// .setFrom("admin")
// )
// )
// );
return ApiResult.success();
}
@ -1374,16 +1374,11 @@ public class TicketController extends ControllerBase {
*/
@PostMapping("call/hangUp")
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
TicketCall ticketCall = ticketCallService.lambdaQuery()
.eq(TicketCall::getTicketId, request.getTicketId())
.ne(TicketCall::getState, 2)
.last("limit 1")
.one();
if (Objects.isNull(ticketCall)) return ApiResult.success();
boolean flag=false;
// TicketCall ticketCall = ticketCallService.getLast(request.getTicketId());
// if (Objects.isNull(ticketCall)) return ApiResult.success();
if (request.getReject()) {
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
if (StrUtil.equals(request.getFrom(), "app")) {
if (StrUtil.equals(request.getFrom(), Constant.FROM_APP)) {
uniPushService.send(new UniPushMessage()
.setSenderId("admin-uid-" + adminUser.getId())
.setReceiverId("app-uid-" + request.getFromUserId())
@ -1401,8 +1396,7 @@ public class TicketController extends ControllerBase {
)
);
ssePushService.sendTicketCallHangUpToApp(request.getTicketId(), request.getFromUserId(), adminUser);
flag=ticketCallJoinService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
}else if (StrUtil.equals(request.getFrom(), "admin")) {
} else if (StrUtil.equals(request.getFrom(), Constant.FROM_ADMIN)) {
if (Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())){
Ticket ticket = ticketService.getById(request.getTicketId());
int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get());
@ -1411,7 +1405,7 @@ public class TicketController extends ControllerBase {
.setReceiverId("admin-uid-" + handlerId)
.setSendData(new UniPushMessageBody()
.setTitle("挂断视频通话")
.setContent(adminUser.getUserName() + "挂断了与您的视频通话")
.setContent(adminUser.getUserName() + "取消了与您的视频通话")
.setPayload(new UniPushMessageCallPayload()
.setTicketId(request.getTicketId())
.setUserId(adminUser.getId())
@ -1423,7 +1417,6 @@ public class TicketController extends ControllerBase {
)
);
ssePushService.sendTicketCallCancelToAdmin(request.getTicketId(), handlerId, adminUser);
flag=ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
}else {
uniPushService.send(new UniPushMessage()
.setSenderId("admin-uid-" + adminUser.getId())
@ -1442,19 +1435,12 @@ public class TicketController extends ControllerBase {
)
);
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), adminUser);
flag=ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
}
}
}else {
if (StrUtil.equals(request.getFrom(), "app") || Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())) {
flag=ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
}else {
flag=ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
}
}
if (flag){
// if (ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, request.getReject())) {
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
}
// }
return ApiResult.success();
}
}

View File

@ -1,5 +1,7 @@
package com.nflg.mobilebroken.admin.event;
import cn.hutool.core.collection.CollectionUtil;
import com.nflg.mobilebroken.admin.service.ShengWangService;
import com.nflg.mobilebroken.admin.service.SsePushService;
import com.nflg.mobilebroken.common.constant.TicketState;
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
@ -9,7 +11,9 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import java.io.IOException;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
@ -17,6 +21,7 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
private SsePushService ssePushService;
private TicketChatService ticketChatService;
private ShengWangService shengWangService;
public TicketCallEndEvent(Object source, Integer ticketId) {
super(source);
@ -29,7 +34,9 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
}
public void send(){
public void send() throws IOException, InterruptedException {
TimeUnit.SECONDS.sleep(2);
if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) {
ChatMessageDTO message = new ChatMessageDTO()
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
.setFrom("call")
@ -40,7 +47,8 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
.setCreateTime(Instant.now());
ticketChatService.addMessage(ticketId, message);
//推送消息
ssePushService.sendTicketMessageToAdmin(ticketId,message);
ssePushService.sendTicketMessageToApp(ticketId,message);
ssePushService.sendTicketMessageToAdmin(ticketId, message);
ssePushService.sendTicketMessageToApp(ticketId, message);
}
}
}

View File

@ -5,6 +5,8 @@ import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class TicketEventListener {
@ -40,7 +42,7 @@ public class TicketEventListener {
@Async
@EventListener
public void handleTicketCallEndEvent(TicketCallEndEvent event) {
public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException {
event.send();
}
}

View File

@ -4,8 +4,7 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nflg.mobilebroken.admin.pojo.dto.*;
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelUserResponseDTO;
import com.nflg.mobilebroken.common.pojo.dto.*;
import com.nflg.mobilebroken.common.util.VUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

View File

@ -1,10 +1,10 @@
package com.nflg.mobilebroken.admin.task;
import cn.hutool.core.collection.CollectionUtil;
import com.nflg.mobilebroken.admin.pojo.dto.ShengWangChannelDTO;
import com.nflg.mobilebroken.admin.pojo.dto.ShengWangChannelInfoDTO;
import com.nflg.mobilebroken.admin.service.ShengWangService;
import com.nflg.mobilebroken.common.constant.Constant;
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelDTO;
import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelInfoDTO;
import com.nflg.mobilebroken.common.util.IdUtil;
import com.nflg.mobilebroken.repository.entity.TicketCall;
import com.nflg.mobilebroken.repository.entity.TicketCallJoin;

View File

@ -0,0 +1,19 @@
package com.nflg.mobilebroken.cfs.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.http.HttpClient;
import java.time.Duration;
@Configuration
public class HttpClientConfig {
@Bean
public HttpClient getHttpClient() {
return HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(10))
.build();
}
}

View File

@ -93,11 +93,11 @@ public class TicketController extends ControllerBase {
@Resource
private UniPushService uniPushService;
@Resource
private ITicketCallService ticketCallService;
@Resource
private ITicketCallJoinService ticketCallJoinService;
// @Resource
// private ITicketCallService ticketCallService;
//
// @Resource
// private ITicketCallJoinService ticketCallJoinService;
/**
* 搜索设备
@ -504,7 +504,7 @@ public class TicketController extends ControllerBase {
VUtils.trueThrowBusinessError(!Objects.equals(AppUserUtil.getUserId(), ticket.getUserId()))
.throwMessage("不是工单创建人无权限呼叫");
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
VUtils.trueThrowBusinessError(ticketCallService.isInCall(handlerUserId)).throwMessage("对方正在通话中");
// VUtils.trueThrowBusinessError(ticketCallJoinService.isInCall(ticket.getId(), Constant.FROM_ADMIN, handlerUserId)).throwMessage("对方正在通话中");
AppUser appUser = appUserService.getById(ticket.getUserId());
uniPushService.send(new UniPushMessage()
.setSenderId(ticket.getUserPlatform()+"-uid-" + ticket.getUserId())
@ -523,7 +523,7 @@ public class TicketController extends ControllerBase {
)
);
ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId);
ticketCallService.add(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP, handlerUserId, Constant.FROM_ADMIN);
// ticketCallService.add(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP, handlerUserId, Constant.FROM_ADMIN);
ticketEventPublisher.publishTicketCallBeginEvent(ticketId,appUser.getName());
return ApiResult.success();
}
@ -538,28 +538,28 @@ public class TicketController extends ControllerBase {
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
.throwMessage("当前工单状态不允许通话");
VUtils.trueThrowBusinessError(!StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom())
|| !Objects.equals(AppUserUtil.getUserId(), ticket.getUserId()))
.throwMessage("不是创建人无法加入通话");
VUtils.trueThrowBusinessError(ticketCallService.isInCall(AppUserUtil.getUserId()))
.throwMessage("您已加入别的通话中");
ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(), Constant.FROM_APP);
ssePushService.sendTicketCallJoinedToApp(AppUserUtil.getUserId(), ticketId);
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
uniPushService.send(new UniPushMessage()
.setSenderId(ticket.getUserPlatform()+"-uid-" + ticket.getUserId())
.setReceiverId("admin-uid-" + handlerUserId)
.setSendData(new UniPushMessageBody()
.setTitle("视频通话")
.setContent("您已加入别的通话中")
.setPayload(new UniPushMessageCallPayload()
.setTicketId(ticketId)
.setUserId(AppUserUtil.getUserId())
.setCategory("ticketCallJoined")
.setFrom("app")
)
)
);
// VUtils.trueThrowBusinessError(!StrUtil.equals(ticket.getUserPlatform(), AppUserUtil.getFrom())
// || !Objects.equals(AppUserUtil.getUserId(), ticket.getUserId()))
// .throwMessage("不是创建人无法加入通话");
// VUtils.trueThrowBusinessError(ticketCallJoinService.isInCall(ticket.getId(), Constant.FROM_APP, AppUserUtil.getUserId()))
// .throwMessage("您已加入别的通话中");
// ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(), Constant.FROM_APP);
// ssePushService.sendTicketCallJoinedToApp(AppUserUtil.getUserId(), ticketId);
// Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
// uniPushService.send(new UniPushMessage()
// .setSenderId(ticket.getUserPlatform()+"-uid-" + ticket.getUserId())
// .setReceiverId("admin-uid-" + handlerUserId)
// .setSendData(new UniPushMessageBody()
// .setTitle("视频通话")
// .setContent("您已加入别的通话中")
// .setPayload(new UniPushMessageCallPayload()
// .setTicketId(ticketId)
// .setUserId(AppUserUtil.getUserId())
// .setCategory("ticketCallJoined")
// .setFrom("app")
// )
// )
// );
return ApiResult.success();
}
@ -569,9 +569,9 @@ public class TicketController extends ControllerBase {
*/
@PostMapping("call/hangUp")
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
TicketCall ticketCall = ticketCallService.getLast(request.getTicketId());
// TicketCall ticketCall = ticketCallService.getLast(request.getTicketId());
if (request.getReject()) {
if (Objects.isNull(ticketCall)) return ApiResult.success();
// if (Objects.isNull(ticketCall)) return ApiResult.success();
if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) {
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
Ticket ticket = ticketService.getById(request.getTicketId());
@ -615,15 +615,9 @@ public class TicketController extends ControllerBase {
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser);
}
}
boolean flag;
if (StrUtil.equals(request.getFrom(), Constant.FROM_APP)) {
flag = ticketCallService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject());
} else {
flag = ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject());
}
if (flag) {
// if (ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject())) {
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
}
// }
return ApiResult.success();
}
}

View File

@ -1,5 +1,7 @@
package com.nflg.mobilebroken.cfs.event;
import cn.hutool.core.collection.CollectionUtil;
import com.nflg.mobilebroken.cfs.service.ShengWangService;
import com.nflg.mobilebroken.cfs.service.SsePushService;
import com.nflg.mobilebroken.common.constant.TicketState;
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
@ -9,7 +11,9 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import java.io.IOException;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
@ -17,6 +21,7 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
private SsePushService ssePushService;
private TicketChatService ticketChatService;
private ShengWangService shengWangService;
public TicketCallEndEvent(Object source,Integer ticketId) {
super(source);
@ -27,9 +32,12 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ssePushService = applicationContext.getBean(SsePushService.class);
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
this.shengWangService = applicationContext.getBean(ShengWangService.class);
}
public void send(){
public void send() throws IOException, InterruptedException {
TimeUnit.SECONDS.sleep(2);
if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) {
ChatMessageDTO message = new ChatMessageDTO()
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
.setFrom("call")
@ -40,7 +48,8 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC
.setCreateTime(Instant.now());
ticketChatService.addMessage(ticketId, message);
//推送消息
ssePushService.sendTicketMessageToAdmin(ticketId,message);
ssePushService.sendTicketMessageToApp(ticketId,message);
ssePushService.sendTicketMessageToAdmin(ticketId, message);
ssePushService.sendTicketMessageToApp(ticketId, message);
}
}
}

View File

@ -5,6 +5,8 @@ import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class TicketEventListener {
@ -46,7 +48,7 @@ public class TicketEventListener {
@Async
@EventListener
public void handleTicketCallEndEvent(TicketCallEndEvent event) {
public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException {
event.send();
}
}

View File

@ -0,0 +1,159 @@
package com.nflg.mobilebroken.cfs.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nflg.mobilebroken.common.pojo.dto.*;
import com.nflg.mobilebroken.common.util.VUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Base64;
import java.util.List;
/**
* 声网服务
*/
@Slf4j
@Component
@RefreshScope
public class ShengWangService {
private static final String baseUrl = "https://api.sd-rtn.com/dev";
@Resource
private HttpClient httpClient;
@Resource
private ObjectMapper objectMapper;
@Value("${shengwang.rtc.appId}")
private String appId;
@Value("${shengwang.rtc.customerKey}")
private String customerKey;
@Value("${shengwang.rtc.customerSecret}")
private String customerSecret;
public ShengWangChannelDTO getAllChannels() throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Authorization", generateAuthorization(customerKey, customerSecret))
.uri(URI.create(baseUrl + "/v1/channel/" + appId))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("getAllChannels Response:" + response.body());
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
ShengWangResponse<ShengWangChannelDTO> result = objectMapper.readValue(response.body(), new TypeReference<>() {
});
VUtils.trueThrowBusinessError(!result.isSuccess()).throwMessage("获取频道信息失败");
return result.getData();
}
/**
* 创建规则
* @param channelName 频道名称
* @param uid 用户ID
* @param time 封禁时间单位为分钟取值范围为 [1,1440]当设置的值为 0 表示不封禁服务端会对频道内符合设定规则的用户进行下线一次的操作用户可以重新登录进入频道
* @param privileges 要封禁的用户权限取值包括join_channel加入频道表示禁止用户加入频道或将用户踢出频道publish_audio发送音频表示禁止用户发送音频流可以与 publish_video 同时设置表示禁止用户发送音视流和视频流publish_video发送视频表示禁止用户发送视频流可以与 publish_audio 同时设置表示禁止用户发送音视流和视频流
* @return 规则ID
*/
public Long addKickingRule(String channelName, Integer uid, Integer time, List<String> privileges) throws Exception {
JSONObject json = new JSONObject();
json.putOpt("appid", appId);
json.putOpt("cname", channelName);
json.putOpt("uid", uid);
json.putOpt("time", time);
json.putOpt("privileges", privileges);
HttpRequest request = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofString(json.toString()))
.header("Authorization", generateAuthorization(customerKey, customerSecret))
.header("Content-Type", "application/json")
.uri(URI.create(baseUrl + "/v1/kicking-rule"))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("addKickingRule Response:" + response.body());
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
ShengWangKickingRuleAddDTO result = objectMapper.readValue(response.body(), ShengWangKickingRuleAddDTO.class);
VUtils.trueThrowBusinessError(!StrUtil.equals(result.getStatus(), "success")).throwMessage("创建规则失败");
return result.getId();
}
/**
* 获取规则
* @return 规则列表
*/
public List<ShengWangKickingRuleListItemDTO> getKickingRule() throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Authorization", generateAuthorization(customerKey, customerSecret))
.uri(URI.create(baseUrl + "/v1/kicking-rule?appid=" + appId))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("getKickingRule Response:" + response.body());
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
ShengWangKickingRuleListResponseDTO result = objectMapper.readValue(response.body(), ShengWangKickingRuleListResponseDTO.class);
VUtils.trueThrowBusinessError(!StrUtil.equals(result.getStatus(), "success")).throwMessage("获取规则失败");
return result.getRules();
}
/**
* 删除规则
* @param id 规则ID
*/
public void deleteKickingRule(long id) throws IOException, InterruptedException {
JSONObject json = new JSONObject();
json.putOpt("appid", appId);
json.putOpt("id", id);
HttpRequest request = HttpRequest.newBuilder()
.method("DELETE", HttpRequest.BodyPublishers.ofString(json.toString()))
.header("Authorization", generateAuthorization(customerKey, customerSecret))
.header("Content-Type", "application/json")
.uri(URI.create(baseUrl + "/v1/kicking-rule"))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("deleteKickingRule Response:" + response.body());
VUtils.trueThrowBusinessError(response.statusCode() == 404).throwMessage("规则不存在");
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
ShengWangKickingRuleAddDTO result = objectMapper.readValue(response.body(), ShengWangKickingRuleAddDTO.class);
VUtils.trueThrowBusinessError(!StrUtil.equals(result.getStatus(), "success")).throwMessage("删除规则失败");
}
/**
* 生成鉴权信息
* @param customerKey 客户ID
* @param customerSecret 客户密钥
* @return 鉴权信息
*/
private String generateAuthorization(String customerKey, String customerSecret) {
// 拼接客户 ID 和客户密钥并使用 base64 编码
String plainCredentials = customerKey + ":" + customerSecret;
String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));
// 创建 authorization header
return "Basic " + base64Credentials;
}
public List<Integer> getChannelUsers(String channelName) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header("Authorization", generateAuthorization(customerKey, customerSecret))
.uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
log.debug("getChannelUsers Response:" + response.body());
VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败");
ShengWangChannelUserResponseDTO result = objectMapper.readValue(response.body(), ShengWangChannelUserResponseDTO.class);
VUtils.trueThrowBusinessError(!result.getSuccess()).throwMessage("获取频道用户失败");
return result.getData().isChannel_exist() ? result.getData().getUsers() : null;
}
}

View File

@ -1,4 +1,4 @@
package com.nflg.mobilebroken.admin.pojo.dto;
package com.nflg.mobilebroken.common.pojo.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.nflg.mobilebroken.admin.pojo.dto;
package com.nflg.mobilebroken.common.pojo.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.nflg.mobilebroken.admin.pojo.dto;
package com.nflg.mobilebroken.common.pojo.dto;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;

View File

@ -1,4 +1,4 @@
package com.nflg.mobilebroken.admin.pojo.dto;
package com.nflg.mobilebroken.common.pojo.dto;
import lombok.Data;