feat: 产品中心
This commit is contained in:
parent
1c3554a35e
commit
14535f8906
|
|
@ -27,6 +27,7 @@ import com.nflg.mobilebroken.repository.service.ILanguageService;
|
||||||
import com.nflg.mobilebroken.repository.service.IWebComponentService;
|
import com.nflg.mobilebroken.repository.service.IWebComponentService;
|
||||||
import com.nflg.mobilebroken.repository.service.IWebComponentTranslateService;
|
import com.nflg.mobilebroken.repository.service.IWebComponentTranslateService;
|
||||||
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
|
import com.nflg.mobilebroken.starter.annotation.MethodInfoMark;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
@ -55,6 +56,7 @@ import java.util.stream.Collectors;
|
||||||
*
|
*
|
||||||
* @author 曹鹏飞
|
* @author 曹鹏飞
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/multilingual")
|
@RequestMapping("/multilingual")
|
||||||
public class MultilingualController extends ControllerBase {
|
public class MultilingualController extends ControllerBase {
|
||||||
|
|
@ -204,8 +206,15 @@ public class MultilingualController extends ControllerBase {
|
||||||
List<Map<String, Object>> datas = EecExcelUtil.readTo(file.getInputStream());
|
List<Map<String, Object>> datas = EecExcelUtil.readTo(file.getInputStream());
|
||||||
List<Language> languages = languageService.getLanguages();
|
List<Language> languages = languageService.getLanguages();
|
||||||
datas.forEach(d -> {
|
datas.forEach(d -> {
|
||||||
|
String moduleCode = (String) d.get("模块编号");
|
||||||
|
String pageCode = (String) d.get("页面编号");
|
||||||
String componentCode = (String) d.get("组件编号");
|
String componentCode = (String) d.get("组件编号");
|
||||||
WebComponent webComponent = webComponentService.lambdaQuery().eq(WebComponent::getComponentCode, componentCode).one();
|
log.info("模块编号:{},页面编号:{},组件编号:{}",moduleCode,pageCode,componentCode);
|
||||||
|
WebComponent webComponent = webComponentService.lambdaQuery()
|
||||||
|
.eq(WebComponent::getModuleCode, moduleCode)
|
||||||
|
.eq(WebComponent::getPageCode, pageCode)
|
||||||
|
.eq(WebComponent::getComponentCode, componentCode)
|
||||||
|
.one();
|
||||||
if (Objects.nonNull(webComponent)) {
|
if (Objects.nonNull(webComponent)) {
|
||||||
d.remove("模块");
|
d.remove("模块");
|
||||||
d.remove("模块编号");
|
d.remove("模块编号");
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.nflg.mobilebroken.admin.controller;
|
package com.nflg.mobilebroken.admin.controller;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.admin.service.DeviceQRCodeService;
|
import com.nflg.mobilebroken.admin.service.DeviceQRCodeService;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
import com.nflg.mobilebroken.common.util.VUtils;
|
import com.nflg.mobilebroken.common.util.VUtils;
|
||||||
|
import com.nflg.mobilebroken.repository.service.ITicketCallService;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
@ -21,6 +23,9 @@ public class TestController extends ControllerBase{
|
||||||
@Resource
|
@Resource
|
||||||
private DeviceQRCodeService deviceQRCodeService;
|
private DeviceQRCodeService deviceQRCodeService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ITicketCallService ticketCallService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示二维码
|
* 显示二维码
|
||||||
* @param deviceNo 设备编号
|
* @param deviceNo 设备编号
|
||||||
|
|
@ -42,4 +47,9 @@ public class TestController extends ControllerBase{
|
||||||
VUtils.trueThrowBusinessError(true).throwMessage("生成二维码出错");
|
VUtils.trueThrowBusinessError(true).throwMessage("生成二维码出错");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("test")
|
||||||
|
public ApiResult<Boolean> test(@RequestParam Integer userId){
|
||||||
|
return ApiResult.success(ticketCallService.isInCall(userId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -131,11 +130,11 @@ public class TicketController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private UniPushService uniPushService;
|
private UniPushService uniPushService;
|
||||||
|
|
||||||
// @Resource
|
@Resource
|
||||||
// private ITicketCallService ticketCallService;
|
private ITicketCallService ticketCallService;
|
||||||
//
|
|
||||||
// @Resource
|
@Resource
|
||||||
// private ITicketCallJoinService ticketCallJoinService;
|
private ITicketCallJoinService ticketCallJoinService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取问题类型
|
* 获取问题类型
|
||||||
|
|
@ -1235,7 +1234,7 @@ public class TicketController extends ControllerBase {
|
||||||
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
|
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(AdminUserUtil.getUserId(), handlerUserId))
|
VUtils.trueThrowBusinessError(!Objects.equals(AdminUserUtil.getUserId(), handlerUserId))
|
||||||
.throwMessage("不是工单主负责人无权限呼叫");
|
.throwMessage("不是工单主负责人无权限呼叫");
|
||||||
// VUtils.trueThrowBusinessError(ticketCallService.isInCall(ticket.getUserId())).throwMessage("对方正在通话中");
|
VUtils.trueThrowBusinessError(ticketCallService.isInCall(ticket.getUserId())).throwMessage("对方正在通话中");
|
||||||
AdminUser adminUser = adminUserService.getById(handlerUserId);
|
AdminUser adminUser = adminUserService.getById(handlerUserId);
|
||||||
uniPushService.send(new UniPushMessage()
|
uniPushService.send(new UniPushMessage()
|
||||||
.setSenderId("admin-uid-" + handlerUserId)
|
.setSenderId("admin-uid-" + handlerUserId)
|
||||||
|
|
@ -1248,13 +1247,14 @@ public class TicketController extends ControllerBase {
|
||||||
.setUserId(adminUser.getId())
|
.setUserId(adminUser.getId())
|
||||||
.setUserName(adminUser.getUserName())
|
.setUserName(adminUser.getUserName())
|
||||||
.setUserAvatar(adminUser.getAvatar())
|
.setUserAvatar(adminUser.getAvatar())
|
||||||
.setCategory("call")
|
.setCategory("ticketCall")
|
||||||
.setFrom("admin")
|
.setFrom("admin")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ssePushService.sendTicketCallToApp(adminUser, ticket.getUserId(), ticketId);
|
ssePushService.sendTicketCallToApp(adminUser, ticket.getUserId(), ticketId);
|
||||||
// ticketCallService.add(ticketId, handlerUserId, ticket.getUserId(), Constant.FROM_ADMIN);
|
ticketCallService.add(ticketId, handlerUserId, ticket.getUserId(), Constant.FROM_ADMIN);
|
||||||
|
ticketEventPublisher.publishTicketCallBeginEvent(ticketId, adminUser.getUserName());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1266,34 +1266,32 @@ public class TicketController extends ControllerBase {
|
||||||
@PostMapping("addCallUser")
|
@PostMapping("addCallUser")
|
||||||
public ApiResult<Void> addCallUser(@Valid @RequestBody CallUserAddRequest request){
|
public ApiResult<Void> addCallUser(@Valid @RequestBody CallUserAddRequest request){
|
||||||
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
|
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
|
||||||
// TicketCall ticketCall = ticketCallService.lambdaQuery()
|
TicketCall ticketCall = ticketCallService.lambdaQuery()
|
||||||
// .eq(TicketCall::getTicketId, request.getTicketId())
|
.eq(TicketCall::getTicketId, request.getTicketId())
|
||||||
// .eq(TicketCall::getState, 1)
|
.eq(TicketCall::getState, 1)
|
||||||
// .one();
|
.one();
|
||||||
// VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("未在通话中");
|
VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("未在通话中");
|
||||||
request.getUserIds().forEach(userId->{
|
request.getUserIds().forEach(userId->{
|
||||||
AdminUser adminUser1 = adminUserService.getById(userId);
|
AdminUser adminUser1 = adminUserService.getById(userId);
|
||||||
if (Objects.nonNull(adminUser1)) {
|
if (Objects.nonNull(adminUser1)) {
|
||||||
CompletableFuture.runAsync(()->{
|
uniPushService.send(new UniPushMessage()
|
||||||
uniPushService.send(new UniPushMessage()
|
.setSenderId("admin-uid-" + adminUser.getId())
|
||||||
.setSenderId("admin-uid-" + adminUser.getId())
|
.setReceiverId("admin-uid-" + userId)
|
||||||
.setReceiverId("admin-uid-" + userId)
|
.setSendData(new UniPushMessageBody()
|
||||||
.setSendData(new UniPushMessageBody()
|
.setTitle("视频通话")
|
||||||
.setTitle("视频通话")
|
.setContent(adminUser.getUserName() + "请求与您视频通话")
|
||||||
.setContent(adminUser.getUserName() + "请求与您视频通话")
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
.setPayload(new UniPushMessageCallPayload()
|
.setTicketId(request.getTicketId())
|
||||||
.setTicketId(request.getTicketId())
|
.setUserId(adminUser.getId())
|
||||||
.setUserId(adminUser.getId())
|
.setUserName(adminUser.getUserName())
|
||||||
.setUserName(adminUser.getUserName())
|
.setUserAvatar(adminUser.getAvatar())
|
||||||
.setUserAvatar(adminUser.getAvatar())
|
.setCategory("ticketCall")
|
||||||
.setCategory("call")
|
.setFrom("admin")
|
||||||
.setFrom("admin")
|
)
|
||||||
)
|
)
|
||||||
)
|
);
|
||||||
);
|
ssePushService.sendTicketCallToAdmin(adminUser, userId, request.getTicketId());
|
||||||
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();
|
return ApiResult.success();
|
||||||
|
|
@ -1309,9 +1307,9 @@ public class TicketController extends ControllerBase {
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
||||||
.throwMessage("当前工单状态不允许请求通话");
|
.throwMessage("当前工单状态不允许请求通话");
|
||||||
// VUtils.trueThrowBusinessError(ticketCallService.isInCall(AdminUserUtil.getUserId()))
|
VUtils.trueThrowBusinessError(ticketCallService.isInCall(AdminUserUtil.getUserId()))
|
||||||
// .throwMessage("您已加入别的通话中");
|
.throwMessage("您已加入别的通话中");
|
||||||
// ticketCallJoinService.join(ticketId, AdminUserUtil.getUserId(),Constant.FROM_ADMIN);
|
ticketCallJoinService.join(ticketId, AdminUserUtil.getUserId(),Constant.FROM_ADMIN);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1321,10 +1319,11 @@ public class TicketController extends ControllerBase {
|
||||||
*/
|
*/
|
||||||
@PostMapping("call/hangUp")
|
@PostMapping("call/hangUp")
|
||||||
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
|
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
|
||||||
// TicketCall ticketCall = ticketCallService.lambdaQuery()
|
TicketCall ticketCall = ticketCallService.lambdaQuery()
|
||||||
// .eq(TicketCall::getTicketId, request.getTicketId())
|
.eq(TicketCall::getTicketId, request.getTicketId())
|
||||||
// .ne(TicketCall::getState, 2)
|
.ne(TicketCall::getState, 2)
|
||||||
// .one();
|
.one();
|
||||||
|
boolean flag=false;
|
||||||
if (request.getReject()) {
|
if (request.getReject()) {
|
||||||
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
|
AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId());
|
||||||
if (StrUtil.equals(request.getFrom(), "app")) {
|
if (StrUtil.equals(request.getFrom(), "app")) {
|
||||||
|
|
@ -1339,39 +1338,65 @@ public class TicketController extends ControllerBase {
|
||||||
.setUserId(adminUser.getId())
|
.setUserId(adminUser.getId())
|
||||||
.setUserName(adminUser.getUserName())
|
.setUserName(adminUser.getUserName())
|
||||||
.setUserAvatar(adminUser.getAvatar())
|
.setUserAvatar(adminUser.getAvatar())
|
||||||
.setCategory("callHangUp")
|
.setCategory("ticketCallHangUp")
|
||||||
.setFrom("admin")
|
.setFrom("admin")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ssePushService.sendTicketCallHangUpToApp(request.getTicketId(), request.getFromUserId(), adminUser);
|
ssePushService.sendTicketCallHangUpToApp(request.getTicketId(), request.getFromUserId(), adminUser);
|
||||||
// ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
|
flag=ticketCallJoinService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
|
||||||
}else if (StrUtil.equals(request.getFrom(), "admin")) {
|
}else if (StrUtil.equals(request.getFrom(), "admin")) {
|
||||||
uniPushService.send(new UniPushMessage()
|
if (Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())){
|
||||||
.setSenderId("admin-uid-" + adminUser.getId())
|
Ticket ticket = ticketService.getById(request.getTicketId());
|
||||||
.setReceiverId("admin-uid-" + request.getFromUserId())
|
int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get());
|
||||||
.setSendData(new UniPushMessageBody()
|
uniPushService.send(new UniPushMessage()
|
||||||
.setTitle("拒绝视频通话")
|
.setSenderId("admin-uid-" + adminUser.getId())
|
||||||
.setContent(adminUser.getUserName() + "拒绝与您视频通话")
|
.setReceiverId("admin-uid-" + handlerId)
|
||||||
.setPayload(new UniPushMessageCallPayload()
|
.setSendData(new UniPushMessageBody()
|
||||||
.setTicketId(request.getTicketId())
|
.setTitle("挂断视频通话")
|
||||||
.setUserId(adminUser.getId())
|
.setContent(adminUser.getUserName() + "挂断了与您的视频通话")
|
||||||
.setUserName(adminUser.getUserName())
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
.setUserAvatar(adminUser.getAvatar())
|
.setTicketId(request.getTicketId())
|
||||||
.setCategory("callHangUp")
|
.setUserId(adminUser.getId())
|
||||||
.setFrom("admin")
|
.setUserName(adminUser.getUserName())
|
||||||
)
|
.setUserAvatar(adminUser.getAvatar())
|
||||||
)
|
.setCategory("ticketCallCancel")
|
||||||
);
|
.setFrom("admin")
|
||||||
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), adminUser);
|
)
|
||||||
// ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
|
)
|
||||||
|
);
|
||||||
|
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())
|
||||||
|
.setReceiverId("admin-uid-" + request.getFromUserId())
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("拒绝视频通话")
|
||||||
|
.setContent(adminUser.getUserName() + "拒绝与您视频通话")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(request.getTicketId())
|
||||||
|
.setUserId(adminUser.getId())
|
||||||
|
.setUserName(adminUser.getUserName())
|
||||||
|
.setUserAvatar(adminUser.getAvatar())
|
||||||
|
.setCategory("ticketCallHangUp")
|
||||||
|
.setFrom("admin")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), adminUser);
|
||||||
|
flag=ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
// if (StrUtil.equals(request.getFrom(), "app")) {
|
if (StrUtil.equals(request.getFrom(), "app") || Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())) {
|
||||||
// ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
|
flag=ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
|
||||||
// }else {
|
}else {
|
||||||
// ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
|
flag=ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false);
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
if (flag){
|
||||||
|
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
|
||||||
}
|
}
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.nflg.mobilebroken.admin.event;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.admin.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class TicketCallBeginEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private final Integer ticketId;
|
||||||
|
private final String userName;
|
||||||
|
|
||||||
|
private SsePushService ssePushService;
|
||||||
|
private TicketChatService ticketChatService;
|
||||||
|
|
||||||
|
public TicketCallBeginEvent(Object source, Integer ticketId, String userName) {
|
||||||
|
super(source);
|
||||||
|
this.ticketId = ticketId;
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(){
|
||||||
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
|
.setFrom("call")
|
||||||
|
.setTicketState(TicketState.Processing.getState())
|
||||||
|
.setSenderId(0)
|
||||||
|
.setSenderName("通话助手")
|
||||||
|
.setContent(userName+"发起了视频通话")
|
||||||
|
.setCreateTime(Instant.now());
|
||||||
|
ticketChatService.addMessage(ticketId, message);
|
||||||
|
//推送消息
|
||||||
|
ssePushService.sendTicketMessageToAdmin(ticketId,message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.nflg.mobilebroken.admin.event;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.admin.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private final Integer ticketId;
|
||||||
|
|
||||||
|
private SsePushService ssePushService;
|
||||||
|
private TicketChatService ticketChatService;
|
||||||
|
|
||||||
|
public TicketCallEndEvent(Object source, Integer ticketId) {
|
||||||
|
super(source);
|
||||||
|
this.ticketId = ticketId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(){
|
||||||
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
|
.setFrom("call")
|
||||||
|
.setTicketState(TicketState.Processing.getState())
|
||||||
|
.setSenderId(0)
|
||||||
|
.setSenderName("通话助手")
|
||||||
|
.setContent("视频通话已结束")
|
||||||
|
.setCreateTime(Instant.now());
|
||||||
|
ticketChatService.addMessage(ticketId, message);
|
||||||
|
//推送消息
|
||||||
|
ssePushService.sendTicketMessageToAdmin(ticketId,message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package com.nflg.mobilebroken.admin.listener;
|
package com.nflg.mobilebroken.admin.listener;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketAssignedEvent;
|
import com.nflg.mobilebroken.admin.event.*;
|
||||||
import com.nflg.mobilebroken.admin.event.TicketCloseEvent;
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketCompleteEvent;
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketReplyEvent;
|
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
@ -34,4 +31,16 @@ public class TicketEventListener {
|
||||||
public void handleTicketCloseEvent(TicketCloseEvent event) {
|
public void handleTicketCloseEvent(TicketCloseEvent event) {
|
||||||
event.send();
|
event.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@EventListener
|
||||||
|
public void handleTicketCallBeginEvent(TicketCallBeginEvent event) {
|
||||||
|
event.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@EventListener
|
||||||
|
public void handleTicketCallEndEvent(TicketCallEndEvent event) {
|
||||||
|
event.send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package com.nflg.mobilebroken.admin.publisher;
|
package com.nflg.mobilebroken.admin.publisher;
|
||||||
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketAssignedEvent;
|
import com.nflg.mobilebroken.admin.event.*;
|
||||||
import com.nflg.mobilebroken.admin.event.TicketCloseEvent;
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketCompleteEvent;
|
|
||||||
import com.nflg.mobilebroken.admin.event.TicketReplyEvent;
|
|
||||||
import com.nflg.mobilebroken.repository.entity.Ticket;
|
import com.nflg.mobilebroken.repository.entity.Ticket;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
|
|
@ -44,4 +41,16 @@ public class TicketEventPublisher {
|
||||||
event.setApplicationContext(applicationContext);
|
event.setApplicationContext(applicationContext);
|
||||||
eventPublisher.publishEvent(event);
|
eventPublisher.publishEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void publishTicketCallBeginEvent(Integer ticketId, String userName) {
|
||||||
|
TicketCallBeginEvent event = new TicketCallBeginEvent(this, ticketId,userName);
|
||||||
|
event.setApplicationContext(applicationContext);
|
||||||
|
eventPublisher.publishEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publishTicketCallEndEvent(Integer ticketId) {
|
||||||
|
TicketCallEndEvent event = new TicketCallEndEvent(this, ticketId);
|
||||||
|
event.setApplicationContext(applicationContext);
|
||||||
|
eventPublisher.publishEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,11 @@ public class SsePushService {
|
||||||
TicketMessagePushRequest request=new TicketMessagePushRequest()
|
TicketMessagePushRequest request=new TicketMessagePushRequest()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setMessage(buildMessage(ticketId,message));
|
.setMessage(buildMessage(ticketId,message));
|
||||||
|
log.debug("发送SSE消息:{}", JSONUtil.toJsonStr(request));
|
||||||
ApiResult<?> result = sendMessage(request,"admin");
|
ApiResult<?> result = sendMessage(request,"admin");
|
||||||
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
log.debug("发送SSE消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("发送消息出错", e);
|
log.error("发送SSE消息出错", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,6 +112,7 @@ public class SsePushService {
|
||||||
.setType("ticketMessage")
|
.setType("ticketMessage")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketMessage")
|
||||||
.setData(new ChatMessageVO()
|
.setData(new ChatMessageVO()
|
||||||
.setId(message.getId())
|
.setId(message.getId())
|
||||||
.setFrom(message.getFrom())
|
.setFrom(message.getFrom())
|
||||||
|
|
@ -146,6 +148,7 @@ public class SsePushService {
|
||||||
.setType("ticketMessageWithdraw")
|
.setType("ticketMessageWithdraw")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketMessageWithdraw")
|
||||||
.setData(messageId)
|
.setData(messageId)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -158,6 +161,7 @@ public class SsePushService {
|
||||||
.setType("ticketCall")
|
.setType("ticketCall")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCall")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(user.getId())
|
.setUserId(user.getId())
|
||||||
|
|
@ -182,6 +186,7 @@ public class SsePushService {
|
||||||
.setType("ticketCall")
|
.setType("ticketCall")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCall")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(user.getId())
|
.setUserId(user.getId())
|
||||||
|
|
@ -211,6 +216,7 @@ public class SsePushService {
|
||||||
.setType("ticketCallHangUp")
|
.setType("ticketCallHangUp")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallHangUp")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(user.getId())
|
.setUserId(user.getId())
|
||||||
|
|
@ -235,6 +241,32 @@ public class SsePushService {
|
||||||
.setType("ticketCallHangUp")
|
.setType("ticketCallHangUp")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallHangUp")
|
||||||
|
.setData(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setUserId(user.getId())
|
||||||
|
.setUserName(user.getUserName())
|
||||||
|
.setUserAvatar(user.getAvatar())
|
||||||
|
.setFrom("admin")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ApiResult<?> result = sendMessageByUser(request, "admin");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendTicketCallCancelToAdmin(@NotNull Integer ticketId, @NotNull Integer userId, AdminUser user) {
|
||||||
|
try {
|
||||||
|
PushUserMessageRequest request = new PushUserMessageRequest()
|
||||||
|
.setUserId(userId)
|
||||||
|
.setMessage(new PushMessageDTO()
|
||||||
|
.setType("ticketCallCancel")
|
||||||
|
.setData(new PushMessageDataBody()
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallCancel")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(user.getId())
|
.setUserId(user.getId())
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher;
|
import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher;
|
||||||
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.Constant;
|
||||||
import com.nflg.mobilebroken.common.constant.TicketState;
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
import com.nflg.mobilebroken.common.pojo.ApiResult;
|
||||||
import com.nflg.mobilebroken.common.pojo.PageData;
|
import com.nflg.mobilebroken.common.pojo.PageData;
|
||||||
|
|
@ -92,11 +93,11 @@ public class TicketController extends ControllerBase {
|
||||||
@Resource
|
@Resource
|
||||||
private UniPushService uniPushService;
|
private UniPushService uniPushService;
|
||||||
|
|
||||||
// @Resource
|
@Resource
|
||||||
// private ITicketCallService ticketCallService;
|
private ITicketCallService ticketCallService;
|
||||||
//
|
|
||||||
// @Resource
|
@Resource
|
||||||
// private ITicketCallJoinService ticketCallJoinService;
|
private ITicketCallJoinService ticketCallJoinService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索设备
|
* 搜索设备
|
||||||
|
|
@ -489,7 +490,7 @@ public class TicketController extends ControllerBase {
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(AppUserUtil.getUserId(), ticket.getUserId()))
|
VUtils.trueThrowBusinessError(!Objects.equals(AppUserUtil.getUserId(), ticket.getUserId()))
|
||||||
.throwMessage("不是工单创建人无权限呼叫");
|
.throwMessage("不是工单创建人无权限呼叫");
|
||||||
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
|
Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get();
|
||||||
// VUtils.trueThrowBusinessError(ticketCallService.isInCall(handlerUserId)).throwMessage("对方正在通话中");
|
VUtils.trueThrowBusinessError(ticketCallService.isInCall(handlerUserId)).throwMessage("对方正在通话中");
|
||||||
AppUser appUser = appUserService.getById(ticket.getUserId());
|
AppUser appUser = appUserService.getById(ticket.getUserId());
|
||||||
uniPushService.send(new UniPushMessage()
|
uniPushService.send(new UniPushMessage()
|
||||||
.setSenderId("app-uid-" + ticket.getUserId())
|
.setSenderId("app-uid-" + ticket.getUserId())
|
||||||
|
|
@ -502,13 +503,14 @@ public class TicketController extends ControllerBase {
|
||||||
.setUserId(appUser.getId())
|
.setUserId(appUser.getId())
|
||||||
.setUserName(appUser.getName())
|
.setUserName(appUser.getName())
|
||||||
.setUserAvatar(appUser.getAvatar())
|
.setUserAvatar(appUser.getAvatar())
|
||||||
.setCategory("call")
|
.setCategory("ticketCall")
|
||||||
.setFrom("app")
|
.setFrom("app")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId);
|
ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId);
|
||||||
// ticketCallService.add(ticketId, AppUserUtil.getUserId(), handlerUserId, Constant.FROM_APP);
|
ticketCallService.add(ticketId, AppUserUtil.getUserId(), handlerUserId, Constant.FROM_APP);
|
||||||
|
ticketEventPublisher.publishTicketCallBeginEvent(ticketId,appUser.getName());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,9 +524,9 @@ public class TicketController extends ControllerBase {
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在");
|
||||||
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState()))
|
||||||
.throwMessage("当前工单状态不允许通话");
|
.throwMessage("当前工单状态不允许通话");
|
||||||
// VUtils.trueThrowBusinessError(ticketCallService.isInCall(AppUserUtil.getUserId()))
|
VUtils.trueThrowBusinessError(ticketCallService.isInCall(AppUserUtil.getUserId()))
|
||||||
// .throwMessage("您已加入别的通话中");
|
.throwMessage("您已加入别的通话中");
|
||||||
// ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP);
|
ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP);
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,26 +536,54 @@ public class TicketController extends ControllerBase {
|
||||||
*/
|
*/
|
||||||
@PostMapping("call/hangUp")
|
@PostMapping("call/hangUp")
|
||||||
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
|
public ApiResult<Void> hangUp(@Valid @RequestBody TicketCallHangUpRequest request) {
|
||||||
|
boolean flag=false;
|
||||||
if (request.getReject()) {
|
if (request.getReject()) {
|
||||||
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) {
|
||||||
uniPushService.send(new UniPushMessage()
|
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
||||||
.setSenderId("app-uid-" + appUser.getId())
|
Ticket ticket = ticketService.getById(request.getTicketId());
|
||||||
.setReceiverId("admin-uid-" + request.getFromUserId())
|
int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get());
|
||||||
.setSendData(new UniPushMessageBody()
|
uniPushService.send(new UniPushMessage()
|
||||||
.setTitle("拒绝视频通话")
|
.setSenderId("app-uid-" + appUser.getId())
|
||||||
.setContent(appUser.getName() + "拒绝与您视频通话")
|
.setReceiverId("admin-uid-" + handlerId)
|
||||||
.setPayload(new UniPushMessageCallPayload()
|
.setSendData(new UniPushMessageBody()
|
||||||
.setTicketId(request.getTicketId())
|
.setTitle("挂断视频通话")
|
||||||
.setUserId(appUser.getId())
|
.setContent(appUser.getName() + "挂断了与您的视频通话")
|
||||||
.setUserName(appUser.getName())
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
.setUserAvatar(appUser.getAvatar())
|
.setTicketId(request.getTicketId())
|
||||||
.setCategory("callHangUp")
|
.setUserId(appUser.getId())
|
||||||
.setFrom("app")
|
.setUserName(appUser.getName())
|
||||||
)
|
.setUserAvatar(appUser.getAvatar())
|
||||||
)
|
.setCategory("ticketCallCancel")
|
||||||
);
|
.setFrom("app")
|
||||||
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser);
|
)
|
||||||
// ticketCallService.hangUp(request.getTicketId(), AppUserUtil.getUserId(), Constant.FROM_APP, true);
|
)
|
||||||
|
);
|
||||||
|
ssePushService.sendTicketCallCancelToAdmin(request.getTicketId(), handlerId, appUser);
|
||||||
|
flag=ticketCallService.hangUp(request.getTicketId(), AppUserUtil.getUserId(), Constant.FROM_APP, true);
|
||||||
|
}else {
|
||||||
|
AppUser appUser = appUserService.getById(AppUserUtil.getUserId());
|
||||||
|
uniPushService.send(new UniPushMessage()
|
||||||
|
.setSenderId("app-uid-" + appUser.getId())
|
||||||
|
.setReceiverId("admin-uid-" + request.getFromUserId())
|
||||||
|
.setSendData(new UniPushMessageBody()
|
||||||
|
.setTitle("拒绝视频通话")
|
||||||
|
.setContent(appUser.getName() + "拒绝与您视频通话")
|
||||||
|
.setPayload(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(request.getTicketId())
|
||||||
|
.setUserId(appUser.getId())
|
||||||
|
.setUserName(appUser.getName())
|
||||||
|
.setUserAvatar(appUser.getAvatar())
|
||||||
|
.setCategory("ticketCallHangUp")
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser);
|
||||||
|
flag=ticketCallJoinService.hangUp(request.getTicketId(), AppUserUtil.getUserId(), Constant.FROM_APP, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flag){
|
||||||
|
ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId());
|
||||||
}
|
}
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.nflg.mobilebroken.cfs.event;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class TicketCallBeginEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private final Integer ticketId;
|
||||||
|
private final String userName;
|
||||||
|
|
||||||
|
private SsePushService ssePushService;
|
||||||
|
private TicketChatService ticketChatService;
|
||||||
|
|
||||||
|
public TicketCallBeginEvent(Object source, Integer ticketId, String userName) {
|
||||||
|
super(source);
|
||||||
|
this.ticketId = ticketId;
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(){
|
||||||
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
|
.setFrom("call")
|
||||||
|
.setTicketState(TicketState.Processing.getState())
|
||||||
|
.setSenderId(0)
|
||||||
|
.setSenderName("通话助手")
|
||||||
|
.setContent(userName+"发起了视频通话")
|
||||||
|
.setCreateTime(Instant.now());
|
||||||
|
ticketChatService.addMessage(ticketId, message);
|
||||||
|
//推送消息
|
||||||
|
ssePushService.sendTicketMessageToAdmin(ticketId,message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.nflg.mobilebroken.cfs.event;
|
||||||
|
|
||||||
|
import com.nflg.mobilebroken.cfs.service.SsePushService;
|
||||||
|
import com.nflg.mobilebroken.common.constant.TicketState;
|
||||||
|
import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO;
|
||||||
|
import com.nflg.mobilebroken.repository.service.TicketChatService;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware {
|
||||||
|
|
||||||
|
private final Integer ticketId;
|
||||||
|
|
||||||
|
private SsePushService ssePushService;
|
||||||
|
private TicketChatService ticketChatService;
|
||||||
|
|
||||||
|
public TicketCallEndEvent(Object source,Integer ticketId) {
|
||||||
|
super(source);
|
||||||
|
this.ticketId = ticketId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.ssePushService = applicationContext.getBean(SsePushService.class);
|
||||||
|
this.ticketChatService = applicationContext.getBean(TicketChatService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(){
|
||||||
|
ChatMessageDTO message = new ChatMessageDTO()
|
||||||
|
.setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr())
|
||||||
|
.setFrom("call")
|
||||||
|
.setTicketState(TicketState.Processing.getState())
|
||||||
|
.setSenderId(0)
|
||||||
|
.setSenderName("通话助手")
|
||||||
|
.setContent("视频通话已结束")
|
||||||
|
.setCreateTime(Instant.now());
|
||||||
|
ticketChatService.addMessage(ticketId, message);
|
||||||
|
//推送消息
|
||||||
|
ssePushService.sendTicketMessageToAdmin(ticketId,message);
|
||||||
|
ssePushService.sendTicketMessageToApp(ticketId,message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,4 +37,16 @@ public class TicketEventListener {
|
||||||
public void handleTicketCloseEvent(TicketCloseEvent event) {
|
public void handleTicketCloseEvent(TicketCloseEvent event) {
|
||||||
event.send();
|
event.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@EventListener
|
||||||
|
public void handleTicketCallBeginEvent(TicketCallBeginEvent event) {
|
||||||
|
event.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@EventListener
|
||||||
|
public void handleTicketCallEndEvent(TicketCallEndEvent event) {
|
||||||
|
event.send();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,4 +52,16 @@ public class TicketEventPublisher {
|
||||||
event.setApplicationContext(applicationContext);
|
event.setApplicationContext(applicationContext);
|
||||||
eventPublisher.publishEvent(event);
|
eventPublisher.publishEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void publishTicketCallBeginEvent(Integer ticketId, String userName) {
|
||||||
|
TicketCallBeginEvent event = new TicketCallBeginEvent(this, ticketId,userName);
|
||||||
|
event.setApplicationContext(applicationContext);
|
||||||
|
eventPublisher.publishEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publishTicketCallEndEvent(Integer ticketId) {
|
||||||
|
TicketCallEndEvent event = new TicketCallEndEvent(this, ticketId);
|
||||||
|
event.setApplicationContext(applicationContext);
|
||||||
|
eventPublisher.publishEvent(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ public class SsePushService {
|
||||||
.setType("ticketMessage")
|
.setType("ticketMessage")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketMessage")
|
||||||
.setData(new ChatMessageVO()
|
.setData(new ChatMessageVO()
|
||||||
.setId(message.getId())
|
.setId(message.getId())
|
||||||
.setFrom(message.getFrom())
|
.setFrom(message.getFrom())
|
||||||
|
|
@ -136,7 +137,10 @@ public class SsePushService {
|
||||||
private PushMessageDTO buildWithdrawMessage(Integer ticketId,String messageId) {
|
private PushMessageDTO buildWithdrawMessage(Integer ticketId,String messageId) {
|
||||||
return new PushMessageDTO()
|
return new PushMessageDTO()
|
||||||
.setType("ticketMessageWithdraw")
|
.setType("ticketMessageWithdraw")
|
||||||
.setData(new PushMessageDataBody().setTargetId(ticketId).setData(messageId));
|
.setData(new PushMessageDataBody()
|
||||||
|
.setType("ticketMessageWithdraw")
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setData(messageId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTicketCallToAdmin(AppUser appUser, Integer userId, Integer ticketId) {
|
public void sendTicketCallToAdmin(AppUser appUser, Integer userId, Integer ticketId) {
|
||||||
|
|
@ -146,6 +150,7 @@ public class SsePushService {
|
||||||
.setType("ticketCall")
|
.setType("ticketCall")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCall")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(appUser.getId())
|
.setUserId(appUser.getId())
|
||||||
|
|
@ -176,6 +181,32 @@ public class SsePushService {
|
||||||
.setType("ticketCallHangUp")
|
.setType("ticketCallHangUp")
|
||||||
.setData(new PushMessageDataBody()
|
.setData(new PushMessageDataBody()
|
||||||
.setTargetId(ticketId)
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallHangUp")
|
||||||
|
.setData(new UniPushMessageCallPayload()
|
||||||
|
.setTicketId(ticketId)
|
||||||
|
.setUserId(user.getId())
|
||||||
|
.setUserName(user.getName())
|
||||||
|
.setUserAvatar(user.getAvatar())
|
||||||
|
.setFrom("app")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ApiResult<?> result = sendMessageByUser(request, "admin");
|
||||||
|
log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("发送消息出错", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendTicketCallCancelToAdmin(@NotNull Integer ticketId, @NotNull Integer userId, AppUser user) {
|
||||||
|
try {
|
||||||
|
PushUserMessageRequest request = new PushUserMessageRequest()
|
||||||
|
.setUserId(userId)
|
||||||
|
.setMessage(new PushMessageDTO()
|
||||||
|
.setType("ticketCallCancel")
|
||||||
|
.setData(new PushMessageDataBody()
|
||||||
|
.setTargetId(ticketId)
|
||||||
|
.setType("ticketCallCancel")
|
||||||
.setData(new UniPushMessageCallPayload()
|
.setData(new UniPushMessageCallPayload()
|
||||||
.setTicketId(ticketId)
|
.setTicketId(ticketId)
|
||||||
.setUserId(user.getId())
|
.setUserId(user.getId())
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,10 @@ public class PushMessageDataBody {
|
||||||
|
|
||||||
private Integer targetId;
|
private Integer targetId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
private Object data;
|
private Object data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class UserSseEmitter extends SseEmitter {
|
public class UserSseEmitter extends SseEmitter {
|
||||||
|
|
||||||
|
private String from;
|
||||||
|
|
||||||
private Integer userId;
|
private Integer userId;
|
||||||
|
|
||||||
private Integer ticketId;
|
private Integer ticketId;
|
||||||
|
|
@ -19,4 +21,8 @@ public class UserSseEmitter extends SseEmitter {
|
||||||
public UserSseEmitter(){
|
public UserSseEmitter(){
|
||||||
super(0L);
|
super(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUser(){
|
||||||
|
return from + "-" + userId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package com.nflg.mobilebroken.push.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class CorsConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public WebMvcConfigurer corsConfigurer() {
|
|
||||||
return new WebMvcConfigurer() {
|
|
||||||
@Override
|
|
||||||
public void addCorsMappings(CorsRegistry registry) {
|
|
||||||
registry.addMapping("/**") // 允许所有路径
|
|
||||||
.allowedOrigins("*") // 允许所有来源
|
|
||||||
.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
|
|
||||||
.allowedHeaders("*") // 允许所有请求头
|
|
||||||
.allowCredentials(true) // 允许携带凭证(如cookies)
|
|
||||||
.maxAge(3600); // 预检请求的缓存时间(秒)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -6,9 +6,11 @@ import com.nflg.mobilebroken.common.pojo.request.PushUserMessageRequest;
|
||||||
import com.nflg.mobilebroken.common.pojo.request.TicketMessagePushRequest;
|
import com.nflg.mobilebroken.common.pojo.request.TicketMessagePushRequest;
|
||||||
import com.nflg.mobilebroken.common.util.AdminUserUtil;
|
import com.nflg.mobilebroken.common.util.AdminUserUtil;
|
||||||
import com.nflg.mobilebroken.common.util.AppUserUtil;
|
import com.nflg.mobilebroken.common.util.AppUserUtil;
|
||||||
|
import com.nflg.mobilebroken.common.util.IdUtil;
|
||||||
import com.nflg.mobilebroken.push.service.impl.APPSSEManagerService;
|
import com.nflg.mobilebroken.push.service.impl.APPSSEManagerService;
|
||||||
import com.nflg.mobilebroken.push.service.impl.AdminSSEManagerService;
|
import com.nflg.mobilebroken.push.service.impl.AdminSSEManagerService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.slf4j.MDC;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||||
|
|
@ -44,11 +46,14 @@ public class SSEController {
|
||||||
@PostMapping("app/push/ticket/message")
|
@PostMapping("app/push/ticket/message")
|
||||||
public ApiResult<Void> pushToApp(@Valid @RequestBody @NotNull TicketMessagePushRequest request){
|
public ApiResult<Void> pushToApp(@Valid @RequestBody @NotNull TicketMessagePushRequest request){
|
||||||
try {
|
try {
|
||||||
|
MDC.put("traceId", IdUtil.getIdStr());
|
||||||
appsseManagerService.sendTicketMessage(request.getTicketId(),request.getMessage());
|
appsseManagerService.sendTicketMessage(request.getTicketId(),request.getMessage());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("发送SSE消息出错", e);
|
log.error("发送SSE消息出错", e);
|
||||||
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
||||||
|
}finally {
|
||||||
|
MDC.remove("traceId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,11 +64,14 @@ public class SSEController {
|
||||||
@PostMapping("app/push/user/message")
|
@PostMapping("app/push/user/message")
|
||||||
public ApiResult<Void> appMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){
|
public ApiResult<Void> appMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){
|
||||||
try {
|
try {
|
||||||
|
MDC.put("traceId", IdUtil.getIdStr());
|
||||||
appsseManagerService.sendByUser(request.getUserId(),request.getMessage());
|
appsseManagerService.sendByUser(request.getUserId(),request.getMessage());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("发送SSE消息出错", e);
|
log.error("发送SSE消息出错", e);
|
||||||
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
||||||
|
}finally {
|
||||||
|
MDC.remove("traceId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,11 +90,14 @@ public class SSEController {
|
||||||
@PostMapping("admin/push/ticket/message")
|
@PostMapping("admin/push/ticket/message")
|
||||||
public ApiResult<Void> adminPushTicketMessage(@Valid @RequestBody @NotNull TicketMessagePushRequest request){
|
public ApiResult<Void> adminPushTicketMessage(@Valid @RequestBody @NotNull TicketMessagePushRequest request){
|
||||||
try {
|
try {
|
||||||
|
MDC.put("traceId", IdUtil.getIdStr());
|
||||||
adminSSEManagerService.sendTicketMessage(request.getTicketId(),request.getMessage());
|
adminSSEManagerService.sendTicketMessage(request.getTicketId(),request.getMessage());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("发送SSE消息出错", e);
|
log.error("发送SSE消息出错", e);
|
||||||
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
||||||
|
}finally {
|
||||||
|
MDC.remove("traceId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,11 +108,14 @@ public class SSEController {
|
||||||
@PostMapping("admin/push/user/message")
|
@PostMapping("admin/push/user/message")
|
||||||
public ApiResult<Void> adminMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){
|
public ApiResult<Void> adminMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){
|
||||||
try {
|
try {
|
||||||
|
MDC.put("traceId", IdUtil.getIdStr());
|
||||||
adminSSEManagerService.sendByUser(request.getUserId(),request.getMessage());
|
adminSSEManagerService.sendByUser(request.getUserId(),request.getMessage());
|
||||||
return ApiResult.success();
|
return ApiResult.success();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("发送SSE消息出错", e);
|
log.error("发送SSE消息出错", e);
|
||||||
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
return ApiResult.error(STATE.BusinessError,e.getMessage());
|
||||||
|
}finally {
|
||||||
|
MDC.remove("traceId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,30 +57,30 @@ public class SSEManagerBase {
|
||||||
|
|
||||||
protected SseEmitter connect(Integer ticketId,Integer userId) {
|
protected SseEmitter connect(Integer ticketId,Integer userId) {
|
||||||
check();
|
check();
|
||||||
log.info(from+"SSE连接:用户id:"+userId+",工单id:"+ticketId);
|
log.info(from + "SSE连接:用户id:" + userId + ",工单id:" + ticketId);
|
||||||
UserSseEmitter emitter = new UserSseEmitter(userId,ticketId);
|
UserSseEmitter emitter = new UserSseEmitter(from, userId, ticketId);
|
||||||
SSE_EMITTERS.add(emitter);
|
SSE_EMITTERS.add(emitter);
|
||||||
ScheduledFuture<?> heartbeatTask = startHeartbeat(emitter);
|
ScheduledFuture<?> heartbeatTask = startHeartbeat(emitter);
|
||||||
emitter.onError((ex) -> {
|
emitter.onError((ex) -> {
|
||||||
remove(userId, emitter,heartbeatTask);
|
remove(emitter,heartbeatTask);
|
||||||
log.error("SSE异常:"+userId, ex);
|
log.error("SSE异常({}):{}", ex.getMessage(),emitter.getUser());
|
||||||
});
|
});
|
||||||
emitter.onTimeout(() -> {
|
emitter.onTimeout(() -> {
|
||||||
remove(userId, emitter,heartbeatTask);
|
remove(emitter,heartbeatTask);
|
||||||
log.error("SSE超时:"+userId);
|
log.error("SSE超时:"+userId);
|
||||||
});
|
});
|
||||||
emitter.onCompletion(() -> {
|
emitter.onCompletion(() -> {
|
||||||
remove(userId, emitter,heartbeatTask);
|
remove(emitter,heartbeatTask);
|
||||||
log.error("SSE完成:"+userId);
|
log.error("SSE完成:"+userId);
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
emitter.send(SseEmitter.event().data("已连接").reconnectTime(5000));
|
emitter.send(SseEmitter.event().data("已连接").reconnectTime(5000));
|
||||||
}catch (ClientAbortException e){
|
}catch (ClientAbortException e){
|
||||||
log.error("客户端断开连接:{}", userId);
|
log.error("客户端断开连接:{}", userId);
|
||||||
emitter.complete();
|
emitter.completeWithError(e);
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
log.error("sse发送数据出错", e);
|
log.error("sse发送数据出错:{}", e.getMessage());
|
||||||
emitter.completeWithError(e);
|
emitter.completeWithError(e);
|
||||||
}
|
}
|
||||||
return emitter;
|
return emitter;
|
||||||
|
|
@ -99,10 +99,10 @@ public class SSEManagerBase {
|
||||||
try {
|
try {
|
||||||
emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData()));
|
emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData()));
|
||||||
} catch (ClientAbortException e) {
|
} catch (ClientAbortException e) {
|
||||||
log.error("客户端断开连接:{}", emitter.getUserId());
|
log.error("客户端断开连接:{}", emitter.getUser());
|
||||||
emitter.complete();
|
emitter.completeWithError(e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("sse发送数据出错", e);
|
log.error("sse发送数据出错:{}", e.getMessage());
|
||||||
emitter.completeWithError(e);
|
emitter.completeWithError(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -111,7 +111,7 @@ public class SSEManagerBase {
|
||||||
protected void sendByUser(Integer userId, PushMessageDTO dto) {
|
protected void sendByUser(Integer userId, PushMessageDTO dto) {
|
||||||
log.info(StrUtil.format(from + "SSE发送消息,用户id: {},内容: {}", userId, dto));
|
log.info(StrUtil.format(from + "SSE发送消息,用户id: {},内容: {}", userId, dto));
|
||||||
List<UserSseEmitter> emitters = SSE_EMITTERS.stream()
|
List<UserSseEmitter> emitters = SSE_EMITTERS.stream()
|
||||||
.filter(s -> Objects.equals(s.getUserId(), userId))
|
.filter(s -> StrUtil.equals(s.getFrom(), from) && Objects.equals(s.getUserId(), userId))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (CollectionUtil.isEmpty(emitters)) {
|
if (CollectionUtil.isEmpty(emitters)) {
|
||||||
log.info(StrUtil.format(from + "用户未连接:{}", userId));
|
log.info(StrUtil.format(from + "用户未连接:{}", userId));
|
||||||
|
|
@ -122,26 +122,30 @@ public class SSEManagerBase {
|
||||||
emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData()));
|
emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData()));
|
||||||
log.info("发送成功");
|
log.info("发送成功");
|
||||||
} catch (ClientAbortException e) {
|
} catch (ClientAbortException e) {
|
||||||
log.error("客户端断开连接:{}", emitter.getUserId());
|
log.error("客户端断开连接:{}", emitter.getUser());
|
||||||
emitter.complete();
|
emitter.completeWithError(e);
|
||||||
}catch (IOException e) {
|
}catch (IOException e) {
|
||||||
log.error("sse发送数据出错", e);
|
log.error("sse发送数据出错:{}", e.getMessage());
|
||||||
emitter.completeWithError(e);
|
emitter.completeWithError(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void remove(Integer userId,UserSseEmitter emitter,ScheduledFuture<?> heartbeatTask){
|
private void remove(UserSseEmitter emitter,ScheduledFuture<?> heartbeatTask){
|
||||||
heartbeatTask.cancel(false);
|
heartbeatTask.cancel(true);
|
||||||
SSE_EMITTERS.remove(emitter);
|
SSE_EMITTERS.remove(emitter);
|
||||||
emitter.complete();
|
emitter.complete();
|
||||||
|
emitter=null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScheduledFuture<?> startHeartbeat(UserSseEmitter emitter) {
|
private ScheduledFuture<?> startHeartbeat(UserSseEmitter emitter) {
|
||||||
return taskScheduler.scheduleAtFixedRate(() -> {
|
return taskScheduler.scheduleAtFixedRate(() -> {
|
||||||
try {
|
try {
|
||||||
emitter.send(SseEmitter.event().data("ping"));
|
if (Objects.nonNull(emitter)) {
|
||||||
|
emitter.send(SseEmitter.event().data("ping"));
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
log.error("sse发送ping数据出错({}):{}", emitter.getUser(),e.getMessage());
|
||||||
emitter.completeWithError(e);
|
emitter.completeWithError(e);
|
||||||
}
|
}
|
||||||
}, 30_000);
|
}, 30_000);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public interface ITicketCallJoinService extends IService<TicketCallJoin> {
|
||||||
|
|
||||||
boolean allIsHangUp(Integer callId);
|
boolean allIsHangUp(Integer callId);
|
||||||
|
|
||||||
void hangUp(Integer callId, Integer userId, String from, boolean reject);
|
boolean hangUp(Integer callId, Integer userId, String from, boolean reject);
|
||||||
|
|
||||||
void add(Integer callId, Integer userId, String from);
|
void add(Integer callId, Integer userId, String from);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,5 +19,5 @@ public interface ITicketCallService extends IService<TicketCall> {
|
||||||
|
|
||||||
void add(Integer ticketId, Integer callerUserId, Integer calledUserId, String from);
|
void add(Integer ticketId, Integer callerUserId, Integer calledUserId, String from);
|
||||||
|
|
||||||
void hangUp(@NotNull Integer ticketId, Integer userId, String from, boolean reject);
|
boolean hangUp(@NotNull Integer ticketId, Integer userId, String from, boolean reject);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ public class TicketCallJoinServiceImpl extends ServiceImpl<TicketCallJoinMapper,
|
||||||
.eq(TicketCall::getTicketId, ticketId)
|
.eq(TicketCall::getTicketId, ticketId)
|
||||||
.ne(TicketCall::getState, 2)
|
.ne(TicketCall::getState, 2)
|
||||||
.one();
|
.one();
|
||||||
VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("加入失败");
|
VUtils.trueThrowBusinessError(Objects.isNull(ticketCall)).throwMessage("加入失败,通话已结束");
|
||||||
TicketCallJoin ticketCallJoin = lambdaQuery()
|
TicketCallJoin ticketCallJoin = lambdaQuery()
|
||||||
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
.eq(TicketCallJoin::getCallId, ticketCall.getId())
|
||||||
.eq(TicketCallJoin::getUserId, userId)
|
.eq(TicketCallJoin::getUserId, userId)
|
||||||
|
|
@ -66,13 +66,14 @@ public class TicketCallJoinServiceImpl extends ServiceImpl<TicketCallJoinMapper,
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public void hangUp(Integer callId, Integer userId, String from, boolean reject) {
|
public boolean hangUp(Integer callId, Integer userId, String from, boolean reject) {
|
||||||
TicketCallJoin ticketCallJoin = lambdaQuery()
|
TicketCallJoin ticketCallJoin = lambdaQuery()
|
||||||
.eq(TicketCallJoin::getCallId, callId)
|
.eq(TicketCallJoin::getCallId, callId)
|
||||||
.ne(TicketCallJoin::getState, 2)
|
.ne(TicketCallJoin::getState, 2)
|
||||||
.eq(TicketCallJoin::getUserId, userId)
|
.eq(TicketCallJoin::getUserId, userId)
|
||||||
.eq(TicketCallJoin::getFrom, from)
|
.eq(TicketCallJoin::getFrom, from)
|
||||||
.one();
|
.one();
|
||||||
|
boolean flag = false;
|
||||||
if (Objects.nonNull(ticketCallJoin)) {
|
if (Objects.nonNull(ticketCallJoin)) {
|
||||||
ticketCallJoin.setState(2);
|
ticketCallJoin.setState(2);
|
||||||
if (!reject) {
|
if (!reject) {
|
||||||
|
|
@ -96,8 +97,10 @@ public class TicketCallJoinServiceImpl extends ServiceImpl<TicketCallJoinMapper,
|
||||||
.set(!reject,TicketCall::getHangupTime, LocalDateTime.now())
|
.set(!reject,TicketCall::getHangupTime, LocalDateTime.now())
|
||||||
.eq(TicketCall::getId, callId)
|
.eq(TicketCall::getId, callId)
|
||||||
.update();
|
.update();
|
||||||
|
flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -113,6 +116,7 @@ public class TicketCallJoinServiceImpl extends ServiceImpl<TicketCallJoinMapper,
|
||||||
.setUserId(userId)
|
.setUserId(userId)
|
||||||
.setFrom(from)
|
.setFrom(from)
|
||||||
.setState(0)
|
.setState(0)
|
||||||
|
.setCreateTime(LocalDateTime.now())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,12 @@ public class TicketCallServiceImpl extends ServiceImpl<TicketCallMapper, TicketC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hangUp(Integer ticketId, Integer userId, String from, boolean reject) {
|
public boolean hangUp(Integer ticketId, Integer userId, String from, boolean reject) {
|
||||||
TicketCall ticketCall = lambdaQuery()
|
TicketCall ticketCall = lambdaQuery()
|
||||||
.eq(TicketCall::getTicketId, ticketId)
|
.eq(TicketCall::getTicketId, ticketId)
|
||||||
.ne(TicketCall::getState, 2)
|
.ne(TicketCall::getState, 2)
|
||||||
.one();
|
.one();
|
||||||
|
boolean flag = false;
|
||||||
if (Objects.nonNull(ticketCall)){
|
if (Objects.nonNull(ticketCall)){
|
||||||
if ((Objects.equals(ticketCall.getCallerUserId(), userId) && StrUtil.equals(ticketCall.getFrom(), Constant.FROM_APP))
|
if ((Objects.equals(ticketCall.getCallerUserId(), userId) && StrUtil.equals(ticketCall.getFrom(), Constant.FROM_APP))
|
||||||
|| ticketCallJoinService.allIsHangUp(ticketCall.getId())){
|
|| ticketCallJoinService.allIsHangUp(ticketCall.getId())){
|
||||||
|
|
@ -74,7 +75,8 @@ public class TicketCallServiceImpl extends ServiceImpl<TicketCallMapper, TicketC
|
||||||
}
|
}
|
||||||
updateById(ticketCall);
|
updateById(ticketCall);
|
||||||
}
|
}
|
||||||
ticketCallJoinService.hangUp(ticketCall.getId(), userId, from, reject);
|
flag=ticketCallJoinService.hangUp(ticketCall.getId(), userId, from, reject);
|
||||||
}
|
}
|
||||||
|
return flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.nflg.mobilebroken.repository.mapper.TicketCallJoinMapper">
|
<mapper namespace="com.nflg.mobilebroken.repository.mapper.TicketCallJoinMapper">
|
||||||
<select id="isInCall" resultType="boolean">
|
<select id="isInCall" resultType="boolean">
|
||||||
select exists(select 1
|
SELECT COUNT(*) > 0
|
||||||
from ticket_call tc
|
FROM ticket_call tc
|
||||||
left join ticket_call_join tcj on tc.id = tcj.call_id
|
INNER JOIN ticket_call_join tcj ON tc.id = tcj.call_id
|
||||||
where tc.state = 1
|
WHERE tc.state = 1
|
||||||
and tcj.user_id = #{userId})
|
AND tcj.state = 1
|
||||||
|
AND tcj.user_id = #{userId}
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package com.nflg.mobilebroken.starter.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class CorsConfig {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public WebMvcConfigurer corsConfigurer() {
|
|
||||||
return new WebMvcConfigurer() {
|
|
||||||
@Override
|
|
||||||
public void addCorsMappings(CorsRegistry registry) {
|
|
||||||
registry.addMapping("/**") // 允许所有路径
|
|
||||||
.allowedOrigins("*") // 允许所有来源
|
|
||||||
.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
|
|
||||||
.allowedHeaders("*") // 允许所有请求头
|
|
||||||
.allowCredentials(true) // 允许携带凭证(如cookies)
|
|
||||||
.maxAge(3600); // 预检请求的缓存时间(秒)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -43,6 +43,9 @@ public class RedisConfig {
|
||||||
template.setKeySerializer(new StringRedisSerializer());
|
template.setKeySerializer(new StringRedisSerializer());
|
||||||
// 设置 Value 的序列化器
|
// 设置 Value 的序列化器
|
||||||
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
|
// 设置 Hash Key 的序列化器
|
||||||
|
template.setHashKeySerializer(new StringRedisSerializer());
|
||||||
|
// 设置 Hash Value 的序列化器
|
||||||
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
|
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue