diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java index e8810fd0..842f8b54 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/MultilingualController.java @@ -27,6 +27,7 @@ import com.nflg.mobilebroken.repository.service.ILanguageService; import com.nflg.mobilebroken.repository.service.IWebComponentService; import com.nflg.mobilebroken.repository.service.IWebComponentTranslateService; import com.nflg.mobilebroken.starter.annotation.MethodInfoMark; +import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.FileSystemResource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -55,6 +56,7 @@ import java.util.stream.Collectors; * * @author 曹鹏飞 */ +@Slf4j @RestController @RequestMapping("/multilingual") public class MultilingualController extends ControllerBase { @@ -204,8 +206,15 @@ public class MultilingualController extends ControllerBase { List> datas = EecExcelUtil.readTo(file.getInputStream()); List languages = languageService.getLanguages(); datas.forEach(d -> { + String moduleCode = (String) d.get("模块编号"); + String pageCode = (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)) { d.remove("模块"); d.remove("模块编号"); diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TestController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TestController.java index 46b34c0e..77bdb3c3 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TestController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TestController.java @@ -1,7 +1,9 @@ package com.nflg.mobilebroken.admin.controller; 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.repository.service.ITicketCallService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -21,6 +23,9 @@ public class TestController extends ControllerBase{ @Resource private DeviceQRCodeService deviceQRCodeService; + @Resource + private ITicketCallService ticketCallService; + /** * 显示二维码 * @param deviceNo 设备编号 @@ -42,4 +47,9 @@ public class TestController extends ControllerBase{ VUtils.trueThrowBusinessError(true).throwMessage("生成二维码出错"); } } + + @GetMapping("test") + public ApiResult test(@RequestParam Integer userId){ + return ApiResult.success(ticketCallService.isInCall(userId)); + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java index 3d86c45e..8563da2f 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/controller/TicketController.java @@ -54,7 +54,6 @@ import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.LocalDateTime; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; /** @@ -131,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; /** * 获取问题类型 @@ -1235,7 +1234,7 @@ public class TicketController extends ControllerBase { Integer handlerUserId = Arrays.stream(ticket.getHandle().split(",")).map(Integer::parseInt).findFirst().get(); VUtils.trueThrowBusinessError(!Objects.equals(AdminUserUtil.getUserId(), handlerUserId)) .throwMessage("不是工单主负责人无权限呼叫"); -// VUtils.trueThrowBusinessError(ticketCallService.isInCall(ticket.getUserId())).throwMessage("对方正在通话中"); + VUtils.trueThrowBusinessError(ticketCallService.isInCall(ticket.getUserId())).throwMessage("对方正在通话中"); AdminUser adminUser = adminUserService.getById(handlerUserId); uniPushService.send(new UniPushMessage() .setSenderId("admin-uid-" + handlerUserId) @@ -1248,13 +1247,14 @@ public class TicketController extends ControllerBase { .setUserId(adminUser.getId()) .setUserName(adminUser.getUserName()) .setUserAvatar(adminUser.getAvatar()) - .setCategory("call") + .setCategory("ticketCall") .setFrom("admin") ) ) ); 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(); } @@ -1266,34 +1266,32 @@ public class TicketController extends ControllerBase { @PostMapping("addCallUser") public ApiResult 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)) { - CompletableFuture.runAsync(()->{ - uniPushService.send(new UniPushMessage() - .setSenderId("admin-uid-" + adminUser.getId()) - .setReceiverId("admin-uid-" + userId) - .setSendData(new UniPushMessageBody() - .setTitle("视频通话") - .setContent(adminUser.getUserName() + "请求与您视频通话") - .setPayload(new UniPushMessageCallPayload() - .setTicketId(request.getTicketId()) - .setUserId(adminUser.getId()) - .setUserName(adminUser.getUserName()) - .setUserAvatar(adminUser.getAvatar()) - .setCategory("call") - .setFrom("admin") - ) - ) - ); - ssePushService.sendTicketCallToAdmin(adminUser, userId, request.getTicketId()); -// ticketCallJoinService.add(ticketCall.getId(), userId, Constant.FROM_ADMIN); - }); + uniPushService.send(new UniPushMessage() + .setSenderId("admin-uid-" + adminUser.getId()) + .setReceiverId("admin-uid-" + userId) + .setSendData(new UniPushMessageBody() + .setTitle("视频通话") + .setContent(adminUser.getUserName() + "请求与您视频通话") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(request.getTicketId()) + .setUserId(adminUser.getId()) + .setUserName(adminUser.getUserName()) + .setUserAvatar(adminUser.getAvatar()) + .setCategory("ticketCall") + .setFrom("admin") + ) + ) + ); + ssePushService.sendTicketCallToAdmin(adminUser, userId, request.getTicketId()); + ticketCallJoinService.add(ticketCall.getId(), userId, Constant.FROM_ADMIN); } }); return ApiResult.success(); @@ -1309,9 +1307,9 @@ 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); + VUtils.trueThrowBusinessError(ticketCallService.isInCall(AdminUserUtil.getUserId())) + .throwMessage("您已加入别的通话中"); + ticketCallJoinService.join(ticketId, AdminUserUtil.getUserId(),Constant.FROM_ADMIN); return ApiResult.success(); } @@ -1321,10 +1319,11 @@ public class TicketController extends ControllerBase { */ @PostMapping("call/hangUp") public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) { -// TicketCall ticketCall = ticketCallService.lambdaQuery() -// .eq(TicketCall::getTicketId, request.getTicketId()) -// .ne(TicketCall::getState, 2) -// .one(); + TicketCall ticketCall = ticketCallService.lambdaQuery() + .eq(TicketCall::getTicketId, request.getTicketId()) + .ne(TicketCall::getState, 2) + .one(); + boolean flag=false; if (request.getReject()) { AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId()); if (StrUtil.equals(request.getFrom(), "app")) { @@ -1339,39 +1338,65 @@ public class TicketController extends ControllerBase { .setUserId(adminUser.getId()) .setUserName(adminUser.getUserName()) .setUserAvatar(adminUser.getAvatar()) - .setCategory("callHangUp") + .setCategory("ticketCallHangUp") .setFrom("admin") ) ) ); 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")) { - 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("callHangUp") - .setFrom("admin") - ) - ) - ); - ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), adminUser); -// ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, true); + if (Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())){ + Ticket ticket = ticketService.getById(request.getTicketId()); + int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); + uniPushService.send(new UniPushMessage() + .setSenderId("admin-uid-" + adminUser.getId()) + .setReceiverId("admin-uid-" + handlerId) + .setSendData(new UniPushMessageBody() + .setTitle("挂断视频通话") + .setContent(adminUser.getUserName() + "挂断了与您的视频通话") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(request.getTicketId()) + .setUserId(adminUser.getId()) + .setUserName(adminUser.getUserName()) + .setUserAvatar(adminUser.getAvatar()) + .setCategory("ticketCallCancel") + .setFrom("admin") + ) + ) + ); + 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 { -// if (StrUtil.equals(request.getFrom(), "app")) { -// ticketCallService.hangUp(request.getTicketId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false); -// }else { -// ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, false); -// } + 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){ + ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId()); } return ApiResult.success(); } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallBeginEvent.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallBeginEvent.java new file mode 100644 index 00000000..25127121 --- /dev/null +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallBeginEvent.java @@ -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); + } +} diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallEndEvent.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallEndEvent.java new file mode 100644 index 00000000..fbf067cb --- /dev/null +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/event/TicketCallEndEvent.java @@ -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); + } +} \ No newline at end of file diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/listener/TicketEventListener.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/listener/TicketEventListener.java index e690c7a6..8ed15aac 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/listener/TicketEventListener.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/listener/TicketEventListener.java @@ -1,9 +1,6 @@ package com.nflg.mobilebroken.admin.listener; -import com.nflg.mobilebroken.admin.event.TicketAssignedEvent; -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.admin.event.*; import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; @@ -34,4 +31,16 @@ public class TicketEventListener { public void handleTicketCloseEvent(TicketCloseEvent event) { event.send(); } + + @Async + @EventListener + public void handleTicketCallBeginEvent(TicketCallBeginEvent event) { + event.send(); + } + + @Async + @EventListener + public void handleTicketCallEndEvent(TicketCallEndEvent event) { + event.send(); + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/publisher/TicketEventPublisher.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/publisher/TicketEventPublisher.java index 99d3b781..9707dc30 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/publisher/TicketEventPublisher.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/publisher/TicketEventPublisher.java @@ -1,9 +1,6 @@ package com.nflg.mobilebroken.admin.publisher; -import com.nflg.mobilebroken.admin.event.TicketAssignedEvent; -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.admin.event.*; import com.nflg.mobilebroken.repository.entity.Ticket; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; @@ -44,4 +41,16 @@ public class TicketEventPublisher { event.setApplicationContext(applicationContext); 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); + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/SsePushService.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/SsePushService.java index 61520b3a..cc420f74 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/SsePushService.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/SsePushService.java @@ -37,10 +37,11 @@ public class SsePushService { TicketMessagePushRequest request=new TicketMessagePushRequest() .setTicketId(ticketId) .setMessage(buildMessage(ticketId,message)); + log.debug("发送SSE消息:{}", JSONUtil.toJsonStr(request)); ApiResult result = sendMessage(request,"admin"); - log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + log.debug("发送SSE消息结果:{}", JSONUtil.toJsonStr(result)); } catch (Exception e) { - log.error("发送消息出错", e); + log.error("发送SSE消息出错", e); } } @@ -111,6 +112,7 @@ public class SsePushService { .setType("ticketMessage") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketMessage") .setData(new ChatMessageVO() .setId(message.getId()) .setFrom(message.getFrom()) @@ -146,6 +148,7 @@ public class SsePushService { .setType("ticketMessageWithdraw") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketMessageWithdraw") .setData(messageId) ); } @@ -158,6 +161,7 @@ public class SsePushService { .setType("ticketCall") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketCall") .setData(new UniPushMessageCallPayload() .setTicketId(ticketId) .setUserId(user.getId()) @@ -182,6 +186,7 @@ public class SsePushService { .setType("ticketCall") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketCall") .setData(new UniPushMessageCallPayload() .setTicketId(ticketId) .setUserId(user.getId()) @@ -211,6 +216,7 @@ public class SsePushService { .setType("ticketCallHangUp") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketCallHangUp") .setData(new UniPushMessageCallPayload() .setTicketId(ticketId) .setUserId(user.getId()) @@ -235,6 +241,32 @@ public class SsePushService { .setType("ticketCallHangUp") .setData(new PushMessageDataBody() .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() .setTicketId(ticketId) .setUserId(user.getId()) diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java index d8c2f082..4c6c5437 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/controller/TicketController.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.nflg.mobilebroken.cfs.publisher.TicketEventPublisher; 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.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; @@ -92,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; /** * 搜索设备 @@ -489,7 +490,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(ticketCallService.isInCall(handlerUserId)).throwMessage("对方正在通话中"); AppUser appUser = appUserService.getById(ticket.getUserId()); uniPushService.send(new UniPushMessage() .setSenderId("app-uid-" + ticket.getUserId()) @@ -502,13 +503,14 @@ public class TicketController extends ControllerBase { .setUserId(appUser.getId()) .setUserName(appUser.getName()) .setUserAvatar(appUser.getAvatar()) - .setCategory("call") + .setCategory("ticketCall") .setFrom("app") ) ) ); 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(); } @@ -522,9 +524,9 @@ 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(AppUserUtil.getUserId())) -// .throwMessage("您已加入别的通话中"); -// ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP); + VUtils.trueThrowBusinessError(ticketCallService.isInCall(AppUserUtil.getUserId())) + .throwMessage("您已加入别的通话中"); + ticketCallJoinService.join(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP); return ApiResult.success(); } @@ -534,26 +536,54 @@ public class TicketController extends ControllerBase { */ @PostMapping("call/hangUp") public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) { + boolean flag=false; if (request.getReject()) { - 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("callHangUp") - .setFrom("app") - ) - ) - ); - ssePushService.sendTicketCallHangUpToAdmin(request.getTicketId(), request.getFromUserId(), appUser); -// ticketCallService.hangUp(request.getTicketId(), AppUserUtil.getUserId(), Constant.FROM_APP, true); + 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()); + int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); + uniPushService.send(new UniPushMessage() + .setSenderId("app-uid-" + appUser.getId()) + .setReceiverId("admin-uid-" + handlerId) + .setSendData(new UniPushMessageBody() + .setTitle("挂断视频通话") + .setContent(appUser.getName() + "挂断了与您的视频通话") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(request.getTicketId()) + .setUserId(appUser.getId()) + .setUserName(appUser.getName()) + .setUserAvatar(appUser.getAvatar()) + .setCategory("ticketCallCancel") + .setFrom("app") + ) + ) + ); + 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(); } diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallBeginEvent.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallBeginEvent.java new file mode 100644 index 00000000..78adcf3f --- /dev/null +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallBeginEvent.java @@ -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); + } +} diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallEndEvent.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallEndEvent.java new file mode 100644 index 00000000..943d67c2 --- /dev/null +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/event/TicketCallEndEvent.java @@ -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); + } +} \ No newline at end of file diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/listener/TicketEventListener.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/listener/TicketEventListener.java index 38526f61..a9394044 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/listener/TicketEventListener.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/listener/TicketEventListener.java @@ -37,4 +37,16 @@ public class TicketEventListener { public void handleTicketCloseEvent(TicketCloseEvent event) { event.send(); } + + @Async + @EventListener + public void handleTicketCallBeginEvent(TicketCallBeginEvent event) { + event.send(); + } + + @Async + @EventListener + public void handleTicketCallEndEvent(TicketCallEndEvent event) { + event.send(); + } } diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/publisher/TicketEventPublisher.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/publisher/TicketEventPublisher.java index 8beedc7a..cb5bd6cb 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/publisher/TicketEventPublisher.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/publisher/TicketEventPublisher.java @@ -52,4 +52,16 @@ public class TicketEventPublisher { event.setApplicationContext(applicationContext); 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); + } } diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/SsePushService.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/SsePushService.java index 58e3b9ff..4b2382e6 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/SsePushService.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/SsePushService.java @@ -103,6 +103,7 @@ public class SsePushService { .setType("ticketMessage") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketMessage") .setData(new ChatMessageVO() .setId(message.getId()) .setFrom(message.getFrom()) @@ -136,7 +137,10 @@ public class SsePushService { private PushMessageDTO buildWithdrawMessage(Integer ticketId,String messageId) { return new PushMessageDTO() .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) { @@ -146,6 +150,7 @@ public class SsePushService { .setType("ticketCall") .setData(new PushMessageDataBody() .setTargetId(ticketId) + .setType("ticketCall") .setData(new UniPushMessageCallPayload() .setTicketId(ticketId) .setUserId(appUser.getId()) @@ -176,6 +181,32 @@ public class SsePushService { .setType("ticketCallHangUp") .setData(new PushMessageDataBody() .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() .setTicketId(ticketId) .setUserId(user.getId()) diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/PushMessageDataBody.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/PushMessageDataBody.java index 06d30c51..95b92743 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/PushMessageDataBody.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/PushMessageDataBody.java @@ -9,5 +9,10 @@ public class PushMessageDataBody { private Integer targetId; + /** + * 消息类型 + */ + private String type; + private Object data; } diff --git a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/UserSseEmitter.java b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/UserSseEmitter.java index 205001e5..9780e9e5 100644 --- a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/UserSseEmitter.java +++ b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/UserSseEmitter.java @@ -12,6 +12,8 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @Accessors(chain = true) public class UserSseEmitter extends SseEmitter { + private String from; + private Integer userId; private Integer ticketId; @@ -19,4 +21,8 @@ public class UserSseEmitter extends SseEmitter { public UserSseEmitter(){ super(0L); } + + public String getUser(){ + return from + "-" + userId; + } } diff --git a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/config/CorsConfig.java b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/config/CorsConfig.java deleted file mode 100644 index d423afb3..00000000 --- a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/config/CorsConfig.java +++ /dev/null @@ -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); // 预检请求的缓存时间(秒) - } - }; - } -} diff --git a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/controller/SSEController.java b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/controller/SSEController.java index f0dd5ae3..98bcbce7 100644 --- a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/controller/SSEController.java +++ b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/controller/SSEController.java @@ -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.util.AdminUserUtil; 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.AdminSSEManagerService; import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; @@ -44,11 +46,14 @@ public class SSEController { @PostMapping("app/push/ticket/message") public ApiResult pushToApp(@Valid @RequestBody @NotNull TicketMessagePushRequest request){ try { + MDC.put("traceId", IdUtil.getIdStr()); appsseManagerService.sendTicketMessage(request.getTicketId(),request.getMessage()); return ApiResult.success(); } catch (IOException e) { log.error("发送SSE消息出错", e); return ApiResult.error(STATE.BusinessError,e.getMessage()); + }finally { + MDC.remove("traceId"); } } @@ -59,11 +64,14 @@ public class SSEController { @PostMapping("app/push/user/message") public ApiResult appMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){ try { + MDC.put("traceId", IdUtil.getIdStr()); appsseManagerService.sendByUser(request.getUserId(),request.getMessage()); return ApiResult.success(); } catch (Exception e) { log.error("发送SSE消息出错", e); return ApiResult.error(STATE.BusinessError,e.getMessage()); + }finally { + MDC.remove("traceId"); } } @@ -82,11 +90,14 @@ public class SSEController { @PostMapping("admin/push/ticket/message") public ApiResult adminPushTicketMessage(@Valid @RequestBody @NotNull TicketMessagePushRequest request){ try { + MDC.put("traceId", IdUtil.getIdStr()); adminSSEManagerService.sendTicketMessage(request.getTicketId(),request.getMessage()); return ApiResult.success(); } catch (IOException e) { log.error("发送SSE消息出错", e); return ApiResult.error(STATE.BusinessError,e.getMessage()); + }finally { + MDC.remove("traceId"); } } @@ -97,11 +108,14 @@ public class SSEController { @PostMapping("admin/push/user/message") public ApiResult adminMessageByUser(@Valid @RequestBody @NotNull PushUserMessageRequest request){ try { + MDC.put("traceId", IdUtil.getIdStr()); adminSSEManagerService.sendByUser(request.getUserId(),request.getMessage()); return ApiResult.success(); } catch (Exception e) { log.error("发送SSE消息出错", e); return ApiResult.error(STATE.BusinessError,e.getMessage()); + }finally { + MDC.remove("traceId"); } } } diff --git a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/service/SSEManagerBase.java b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/service/SSEManagerBase.java index b0c34185..7118abaf 100644 --- a/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/service/SSEManagerBase.java +++ b/nflg-mobilebroken-push/src/main/java/com/nflg/mobilebroken/push/service/SSEManagerBase.java @@ -57,30 +57,30 @@ public class SSEManagerBase { protected SseEmitter connect(Integer ticketId,Integer userId) { check(); - log.info(from+"SSE连接:用户id:"+userId+",工单id:"+ticketId); - UserSseEmitter emitter = new UserSseEmitter(userId,ticketId); + log.info(from + "SSE连接:用户id:" + userId + ",工单id:" + ticketId); + UserSseEmitter emitter = new UserSseEmitter(from, userId, ticketId); SSE_EMITTERS.add(emitter); ScheduledFuture heartbeatTask = startHeartbeat(emitter); emitter.onError((ex) -> { - remove(userId, emitter,heartbeatTask); - log.error("SSE异常:"+userId, ex); + remove(emitter,heartbeatTask); + log.error("SSE异常({}):{}", ex.getMessage(),emitter.getUser()); }); emitter.onTimeout(() -> { - remove(userId, emitter,heartbeatTask); + remove(emitter,heartbeatTask); log.error("SSE超时:"+userId); }); emitter.onCompletion(() -> { - remove(userId, emitter,heartbeatTask); + remove(emitter,heartbeatTask); log.error("SSE完成:"+userId); }); try { emitter.send(SseEmitter.event().data("已连接").reconnectTime(5000)); }catch (ClientAbortException e){ log.error("客户端断开连接:{}", userId); - emitter.complete(); + emitter.completeWithError(e); } catch (IOException e) { - log.error("sse发送数据出错", e); + log.error("sse发送数据出错:{}", e.getMessage()); emitter.completeWithError(e); } return emitter; @@ -99,10 +99,10 @@ public class SSEManagerBase { try { emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData())); } catch (ClientAbortException e) { - log.error("客户端断开连接:{}", emitter.getUserId()); - emitter.complete(); + log.error("客户端断开连接:{}", emitter.getUser()); + emitter.completeWithError(e); } catch (IOException e) { - log.error("sse发送数据出错", e); + log.error("sse发送数据出错:{}", e.getMessage()); emitter.completeWithError(e); } }); @@ -111,7 +111,7 @@ public class SSEManagerBase { protected void sendByUser(Integer userId, PushMessageDTO dto) { log.info(StrUtil.format(from + "SSE发送消息,用户id: {},内容: {}", userId, dto)); List 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()); if (CollectionUtil.isEmpty(emitters)) { log.info(StrUtil.format(from + "用户未连接:{}", userId)); @@ -122,26 +122,30 @@ public class SSEManagerBase { emitter.send(SseEmitter.event().name(dto.getType()).data(dto.getData())); log.info("发送成功"); } catch (ClientAbortException e) { - log.error("客户端断开连接:{}", emitter.getUserId()); - emitter.complete(); + log.error("客户端断开连接:{}", emitter.getUser()); + emitter.completeWithError(e); }catch (IOException e) { - log.error("sse发送数据出错", e); + log.error("sse发送数据出错:{}", e.getMessage()); emitter.completeWithError(e); } }); } - private void remove(Integer userId,UserSseEmitter emitter,ScheduledFuture heartbeatTask){ - heartbeatTask.cancel(false); + private void remove(UserSseEmitter emitter,ScheduledFuture heartbeatTask){ + heartbeatTask.cancel(true); SSE_EMITTERS.remove(emitter); emitter.complete(); + emitter=null; } private ScheduledFuture startHeartbeat(UserSseEmitter emitter) { return taskScheduler.scheduleAtFixedRate(() -> { try { - emitter.send(SseEmitter.event().data("ping")); + if (Objects.nonNull(emitter)) { + emitter.send(SseEmitter.event().data("ping")); + } } catch (IOException e) { + log.error("sse发送ping数据出错({}):{}", emitter.getUser(),e.getMessage()); emitter.completeWithError(e); } }, 30_000); diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallJoinService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallJoinService.java index a0c1dafd..8d20483c 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallJoinService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallJoinService.java @@ -22,7 +22,7 @@ public interface ITicketCallJoinService extends IService { 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); diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallService.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallService.java index d5fb0b61..fe460741 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallService.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/ITicketCallService.java @@ -19,5 +19,5 @@ public interface ITicketCallService extends IService { 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); } diff --git a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketCallJoinServiceImpl.java b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketCallJoinServiceImpl.java index 80bde7c0..22f47fd9 100644 --- a/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketCallJoinServiceImpl.java +++ b/nflg-mobilebroken-repository/src/main/java/com/nflg/mobilebroken/repository/service/impl/TicketCallJoinServiceImpl.java @@ -42,7 +42,7 @@ public class TicketCallJoinServiceImpl extends ServiceImpl diff --git a/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/CorsConfig.java b/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/CorsConfig.java deleted file mode 100644 index 7d65da0b..00000000 --- a/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/CorsConfig.java +++ /dev/null @@ -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); // 预检请求的缓存时间(秒) - } - }; - } -} diff --git a/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/RedisConfig.java b/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/RedisConfig.java index a57b5ad5..43ad46dd 100644 --- a/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/RedisConfig.java +++ b/nflg-mobilebroken-starter/src/main/java/com/nflg/mobilebroken/starter/config/RedisConfig.java @@ -43,6 +43,9 @@ public class RedisConfig { template.setKeySerializer(new StringRedisSerializer()); // 设置 Value 的序列化器 template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); + // 设置 Hash Key 的序列化器 + template.setHashKeySerializer(new StringRedisSerializer()); + // 设置 Hash Value 的序列化器 template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; }