From 691fe4013167060c7fb4eb0d612038d16dfbcc49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=B9=E9=B9=8F=E9=A3=9E?= Date: Wed, 27 Aug 2025 16:50:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20bug-632=20=E8=A7=86=E9=A2=91=E9=80=9A?= =?UTF-8?q?=E8=AF=9D=E9=80=BB=E8=BE=91=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/TicketController.java | 478 ++++++++++-------- .../admin/event/TicketCallEndEvent.java | 42 +- .../admin/listener/TicketEventListener.java | 12 +- .../admin/service/ShengWangService.java | 38 +- .../admin/service/SsePushService.java | 24 + .../admin/task/ShengWangScheduledTasks.java | 166 +++--- .../cfs/controller/TicketController.java | 162 ++++-- .../cfs/event/TicketCallEndEvent.java | 41 +- .../cfs/listener/TicketEventListener.java | 12 +- .../cfs/service/ShengWangService.java | 34 +- .../cfs/service/SsePushService.java | 47 ++ .../common/constant/Constant.java | 2 + .../pojo/dto/ShengWangChannelUserListDTO.java | 26 + .../common/util/ShengWangUtil.java | 18 + 14 files changed, 662 insertions(+), 440 deletions(-) create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/ShengWangChannelUserListDTO.java create mode 100644 nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ShengWangUtil.java 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 aa1b1d7d..61b1011c 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 @@ -6,15 +6,13 @@ import cn.hutool.core.util.StrUtil; import com.itextpdf.text.pdf.BaseFont; import com.nflg.mobilebroken.admin.annotation.ApiMark; import com.nflg.mobilebroken.admin.publisher.TicketEventPublisher; +import com.nflg.mobilebroken.admin.service.ShengWangService; import com.nflg.mobilebroken.admin.service.SsePushService; import com.nflg.mobilebroken.common.constant.*; import com.nflg.mobilebroken.common.exception.NflgException; import com.nflg.mobilebroken.common.pojo.ApiResult; import com.nflg.mobilebroken.common.pojo.PageData; -import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO; -import com.nflg.mobilebroken.common.pojo.dto.UniPushMessage; -import com.nflg.mobilebroken.common.pojo.dto.UniPushMessageBody; -import com.nflg.mobilebroken.common.pojo.dto.UniPushMessageCallPayload; +import com.nflg.mobilebroken.common.pojo.dto.*; import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.*; import com.nflg.mobilebroken.common.util.*; @@ -54,6 +52,7 @@ import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.LocalDateTime; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -136,6 +135,9 @@ public class TicketController extends ControllerBase { // @Resource // private ITicketCallJoinService ticketCallJoinService; + @Resource + private ShengWangService shengWangService; + /** * 获取问题类型 * @return 问题类型列表 @@ -152,9 +154,9 @@ public class TicketController extends ControllerBase { * @return 收藏夹信息 */ @GetMapping("getFavorites") - @ApiMark(moduleName = "工单管理", apiName = "获取收藏夹",isPublic = true) - public ApiResult getFavorites(@RequestParam(defaultValue ="0") Integer id){ - return ApiResult.success(ticketFavoritesService.getList(AdminUserUtil.getUserId(),Constant.FROM_ADMIN,id)); + @ApiMark(moduleName = "工单管理", apiName = "获取收藏夹", isPublic = true) + public ApiResult getFavorites(@RequestParam(defaultValue = "0") Integer id) { + return ApiResult.success(ticketFavoritesService.getList(AdminUserUtil.getUserId(), Constant.FROM_ADMIN, id)); } /** @@ -163,8 +165,8 @@ public class TicketController extends ControllerBase { * @return 树结构 */ @GetMapping("getFavoritesTree") - public ApiResult getFavoritesTree(@RequestParam(defaultValue ="0") Integer id){ - return ApiResult.success(ticketFavoritesService.getTree(AdminUserUtil.getUserId(),Constant.FROM_ADMIN,id)); + public ApiResult getFavoritesTree(@RequestParam(defaultValue = "0") Integer id) { + return ApiResult.success(ticketFavoritesService.getTree(AdminUserUtil.getUserId(), Constant.FROM_ADMIN, id)); } /** @@ -173,9 +175,9 @@ public class TicketController extends ControllerBase { * @return 无 */ @PostMapping("addFavorites") - @ApiMark(moduleName = "工单管理", apiName = "添加收藏夹",isPublic = true) - public ApiResult addFavorites(@Valid @RequestBody AdminFavoritesRequest request){ - ticketFavoritesService.addFavorites(request,AdminUserUtil.getUserId(),Constant.FROM_ADMIN); + @ApiMark(moduleName = "工单管理", apiName = "添加收藏夹", isPublic = true) + public ApiResult addFavorites(@Valid @RequestBody AdminFavoritesRequest request) { + ticketFavoritesService.addFavorites(request, AdminUserUtil.getUserId(), Constant.FROM_ADMIN); return ApiResult.success(); } @@ -184,8 +186,8 @@ public class TicketController extends ControllerBase { * @param request 请求信息 */ @PostMapping("updateFavorites") - public ApiResult updateFavorites(@Valid @RequestBody FavoritesUpdateRequest request){ - ticketFavoritesService.updateFavorites(request,AdminUserUtil.getUserId(),Constant.FROM_ADMIN); + public ApiResult updateFavorites(@Valid @RequestBody FavoritesUpdateRequest request) { + ticketFavoritesService.updateFavorites(request, AdminUserUtil.getUserId(), Constant.FROM_ADMIN); return ApiResult.success(); } @@ -195,9 +197,9 @@ public class TicketController extends ControllerBase { * @return 无 */ @PostMapping("deleteFavorites") - @ApiMark(moduleName = "工单管理", apiName = "删除收藏夹",isPublic = true) - public ApiResult deleteFavorites(@Valid @RequestParam @NotNull Integer favoritesId){ - ticketFavoritesService.deleteFavorites(AdminUserUtil.getUserId(),Constant.FROM_ADMIN,favoritesId); + @ApiMark(moduleName = "工单管理", apiName = "删除收藏夹", isPublic = true) + public ApiResult deleteFavorites(@Valid @RequestParam @NotNull Integer favoritesId) { + ticketFavoritesService.deleteFavorites(AdminUserUtil.getUserId(), Constant.FROM_ADMIN, favoritesId); return ApiResult.success(); } @@ -206,7 +208,7 @@ public class TicketController extends ControllerBase { * @param request 请求信息 */ @PostMapping("moveFavorites") - public ApiResult moveFavorites(@Valid @RequestBody FavoritesMoveRequest request){ + public ApiResult moveFavorites(@Valid @RequestBody FavoritesMoveRequest request) { ticketFavoritesService.moveFavorites(request); return ApiResult.success(); } @@ -216,8 +218,8 @@ public class TicketController extends ControllerBase { * @param request 请求信息 */ @PostMapping("moveFavoritesTicket") - public ApiResult moveFavoritesTicket(@Valid @RequestBody FavoritesTicketMoveRequest request){ - ticketFavoritesService.moveFavoritesTicket(AdminUserUtil.getUserId(),Constant.FROM_ADMIN,request); + public ApiResult moveFavoritesTicket(@Valid @RequestBody FavoritesTicketMoveRequest request) { + ticketFavoritesService.moveFavoritesTicket(AdminUserUtil.getUserId(), Constant.FROM_ADMIN, request); return ApiResult.success(); } @@ -227,8 +229,8 @@ public class TicketController extends ControllerBase { **/ @PostMapping("followTiket") @ApiMark(moduleName = "工单管理", apiName = "关注工单") - public ApiResult followTiket(@Valid @RequestBody AdminFollowRequest request){ - ticketFollowService.follow(request, AdminUserUtil.getUserId(),Constant.FROM_ADMIN); + public ApiResult followTiket(@Valid @RequestBody AdminFollowRequest request) { + ticketFollowService.follow(request, AdminUserUtil.getUserId(), Constant.FROM_ADMIN); return ApiResult.success(); } @@ -237,8 +239,8 @@ public class TicketController extends ControllerBase { * @param ticketId 工单id **/ @PostMapping("unfollowTicket") - public ApiResult unfollowTicket(@Valid @RequestParam @NotNull Integer ticketId){ - ticketFollowService.unfollow(AdminUserUtil.getUserId(),Constant.FROM_ADMIN,ticketId); + public ApiResult unfollowTicket(@Valid @RequestParam @NotNull Integer ticketId) { + ticketFollowService.unfollow(AdminUserUtil.getUserId(), Constant.FROM_ADMIN, ticketId); return ApiResult.success(); } @@ -248,7 +250,7 @@ public class TicketController extends ControllerBase { * @return 部件列表 */ @GetMapping("getDeviceComponents") - public ApiResult> getDeviceComponents(@RequestParam String name){ + public ApiResult> getDeviceComponents(@RequestParam String name) { return ApiResult.success(partService.getSimpleList(name)); } @@ -257,7 +259,7 @@ public class TicketController extends ControllerBase { * @return 代理商列表 */ @GetMapping("getDeviceAgents") - public ApiResult> getDeviceAgents(){ + public ApiResult> getDeviceAgents() { return ApiResult.success(deviceService.getAgents()); } @@ -276,7 +278,7 @@ public class TicketController extends ControllerBase { } private TicketEvaluateVO getTicketEvaluateForList(Integer ticketId) { - TicketEvaluate ticketEvaluate = ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId,ticketId).one(); + TicketEvaluate ticketEvaluate = ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, ticketId).one(); if (Objects.isNull(ticketEvaluate)) { return null; } @@ -295,7 +297,7 @@ public class TicketController extends ControllerBase { } } if (CollectionUtil.isNotEmpty(item.getChildren())) { - item.getChildren().removeIf(child -> !Objects.equals(child.getSelected(),true)); + item.getChildren().removeIf(child -> !Objects.equals(child.getSelected(), true)); } }); vo.getServiceEvaluation().removeIf(item -> !item.getSelected()); @@ -312,10 +314,10 @@ public class TicketController extends ControllerBase { } } if (CollectionUtil.isNotEmpty(item.getChildren())) { - item.getChildren().removeIf(child ->!Objects.equals(child.getSelected(),true)); + item.getChildren().removeIf(child -> !Objects.equals(child.getSelected(), true)); } }); - vo.getExperienceEvaluation().removeIf(item -> !Objects.equals(item.getSelected(),true)); + vo.getExperienceEvaluation().removeIf(item -> !Objects.equals(item.getSelected(), true)); return new TicketEvaluateVO() .setScore(ticketEvaluate.getScore()) .setFeedback(ticketEvaluate.getFeedback()) @@ -329,9 +331,9 @@ public class TicketController extends ControllerBase { * @return 根本原因分析 */ @GetMapping("getReason") - @ApiMark(moduleName = "工单管理", apiName = "获取工单根本原因分析",isPublic = true) - public ApiResult getReason(@Valid @RequestParam @NotNull Integer ticketId){ - Ticket ticket=ticketService.getById(ticketId); + @ApiMark(moduleName = "工单管理", apiName = "获取工单根本原因分析", isPublic = true) + public ApiResult getReason(@Valid @RequestParam @NotNull Integer ticketId) { + Ticket ticket = ticketService.getById(ticketId); VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); return ApiResult.success(ticket.getReason()); } @@ -342,7 +344,7 @@ public class TicketController extends ControllerBase { */ @PostMapping("exportSearchTicket") @ApiMark(moduleName = "工单管理", apiName = "导出搜索工单") - public void exportSearchTicket(HttpServletResponse response,@Valid @RequestBody AdminTicketSearchRequest request) throws IOException { + public void exportSearchTicket(HttpServletResponse response, @Valid @RequestBody AdminTicketSearchRequest request) throws IOException { request.setPageSize(Integer.MAX_VALUE); List datas = ticketService.exportSearch(request); EecExcelUtil.export("工单", "sheet1", datas, response); @@ -356,8 +358,8 @@ public class TicketController extends ControllerBase { @MethodInfoMark(value = "分派工单", menuName = "工单管理") @ApiMark(moduleName = "工单管理", apiName = "分派工单") public ApiResult assignmentTicket(@Valid @RequestBody AssignmentTicketRequest request) { - Ticket ticket=ticketService.assignmentTicket(request); - ticketEventPublisher.publishTicketAssignedEvent(ticket,request.getUserIds()); + Ticket ticket = ticketService.assignmentTicket(request); + ticketEventPublisher.publishTicketAssignedEvent(ticket, request.getUserIds()); ChatMessageDTO message = new ChatMessageDTO() .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) .setFrom("system") @@ -368,8 +370,8 @@ public class TicketController extends ControllerBase { .setCreateTime(Instant.now()); ticketChatService.addMessage(ticket.getId(), message); //推送消息 - ssePushService.sendTicketMessageToApp(ticket.getId(),message); - ssePushService.sendTicketMessageToAdmin(ticket.getId(),message); + ssePushService.sendTicketMessageToApp(ticket.getId(), message); + ssePushService.sendTicketMessageToAdmin(ticket.getId(), message); return ApiResult.success(); } @@ -380,7 +382,7 @@ public class TicketController extends ControllerBase { */ @GetMapping("getTicketHandle") @ApiMark(moduleName = "工单管理", apiName = "获取工单处理人") - public ApiResult> getTicketHandle(@Valid @RequestParam @NotNull(message = "工单编号不能为空") Integer id){ + public ApiResult> getTicketHandle(@Valid @RequestParam @NotNull(message = "工单编号不能为空") Integer id) { return ApiResult.success(ticketService.getTicketHandle(id)); } @@ -391,15 +393,15 @@ public class TicketController extends ControllerBase { @PostMapping("addTicketHandle") @MethodInfoMark(value = "添加工单处理人", menuName = "工单管理") @ApiMark(moduleName = "工单管理", apiName = "添加工单处理人") - public ApiResult addTicketHandle(@Valid @RequestBody TicketHandleAddRequest request){ - Ticket ticket=ticketService.getById(request.getTicketId()); - List handleIds= StrUtil.split(ticket.getHandle(),",").stream().map(Integer::parseInt).collect(Collectors.toList()); + public ApiResult addTicketHandle(@Valid @RequestBody TicketHandleAddRequest request) { + Ticket ticket = ticketService.getById(request.getTicketId()); + List handleIds = StrUtil.split(ticket.getHandle(), ",").stream().map(Integer::parseInt).collect(Collectors.toList()); VUtils.trueThrowBusinessError(handleIds.stream().anyMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId())) && request.getUserIds().stream().noneMatch(uid -> Objects.equals(uid, AdminUserUtil.getUserId()))) .throwMessage("不可以移除自己"); - Ticket ticket1=ticketService.addTicketHandle(request); + Ticket ticket1 = ticketService.addTicketHandle(request); request.getUserIds().removeAll(handleIds); - if(CollectionUtil.isNotEmpty(request.getUserIds())) { + if (CollectionUtil.isNotEmpty(request.getUserIds())) { ticketEventPublisher.publishTicketAssignedEvent(ticket1, request.getUserIds()); } return ApiResult.success(); @@ -413,8 +415,8 @@ public class TicketController extends ControllerBase { @MethodInfoMark(value = "完成工单", menuName = "工单管理") @ApiMark(moduleName = "工单管理", apiName = "完成工单") public ApiResult completeTicket(@Valid @RequestBody @NotEmpty List ids) { - for (Integer id : ids){ - Ticket ticket=ticketService.completeTicket(id); + for (Integer id : ids) { + Ticket ticket = ticketService.completeTicket(id); ticketEventPublisher.publishTicketCompleteEvent(ticket); ChatMessageDTO message = new ChatMessageDTO() .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) @@ -426,8 +428,8 @@ public class TicketController extends ControllerBase { .setCreateTime(Instant.now()); ticketChatService.addMessage(id, message); //推送消息 - ssePushService.sendTicketMessageToAdmin(id,message); - ssePushService.sendTicketMessageToApp(id,message); + ssePushService.sendTicketMessageToAdmin(id, message); + ssePushService.sendTicketMessageToApp(id, message); } return ApiResult.success(); } @@ -440,8 +442,8 @@ public class TicketController extends ControllerBase { @MethodInfoMark(value = "驳回工单", menuName = "工单管理") @ApiMark(moduleName = "工单管理", apiName = "驳回工单") public ApiResult rejectTicket(@Valid @RequestBody @NotEmpty List ids) { - for (Integer id : ids){ - Ticket ticket=ticketService.rejectTicket(id); + for (Integer id : ids) { + Ticket ticket = ticketService.rejectTicket(id); // ticketEventPublisher.publishTicketCompleteEvent(ticket); ChatMessageDTO message = new ChatMessageDTO() .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) @@ -453,8 +455,8 @@ public class TicketController extends ControllerBase { .setCreateTime(Instant.now()); ticketChatService.addMessage(id, message); //推送消息 - ssePushService.sendTicketMessageToAdmin(id,message); - ssePushService.sendTicketMessageToApp(id,message); + ssePushService.sendTicketMessageToAdmin(id, message); + ssePushService.sendTicketMessageToApp(id, message); } return ApiResult.success(); } @@ -493,7 +495,7 @@ public class TicketController extends ControllerBase { public void exportPdf(HttpServletResponse response, @Valid @RequestParam @NotBlank(message = "工单编号不能为空") String id) { Ticket ticket = ticketService.getById(id); AppUser user = appUserService.getById(ticket.getUserId()); - List companyIds= Arrays.stream(user.getCompanyId().split(",")).map(Integer::parseInt).collect(Collectors.toList()); + List companyIds = Arrays.stream(user.getCompanyId().split(",")).map(Integer::parseInt).collect(Collectors.toList()); List companys = customerService.listByIds(companyIds); DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo()); String handle = ticket.getHandle(); @@ -501,16 +503,16 @@ public class TicketController extends ControllerBase { List adminUsers = adminUserService.listByIds(Arrays.stream(handle.split(",")).map(Integer::parseInt).collect(Collectors.toList())); handle = adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.joining(",")); } - List fileIds=CollectionUtil.addAll(StrUtil.split(ticket.getAttachments(),","), StrUtil.split(ticket.getImages(),",")) + List fileIds = CollectionUtil.addAll(StrUtil.split(ticket.getAttachments(), ","), StrUtil.split(ticket.getImages(), ",")) .stream() .map(Integer::parseInt) .collect(Collectors.toList()); List images = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(fileIds)){ - images=fileUploadRecordService.listByIds(fileIds) + if (CollectionUtil.isNotEmpty(fileIds)) { + images = fileUploadRecordService.listByIds(fileIds) .stream() .map(FileUploadRecord::getUrl) - .filter(url->url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".jpeg")) + .filter(url -> url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".jpeg")) .collect(Collectors.toList()); } TBasePart part = partService.getByIdAndLanguage(ticket.getComponentId(), Constant.DEFAULT_LANGUAGE_CODE); @@ -519,13 +521,13 @@ public class TicketController extends ControllerBase { .setTitle(ticket.getTitle()) .setDeviceNo(ticket.getDeviceNo()) .setModelNo(device.getModelNo()) - .setComponent(Objects.nonNull(part)?part.getPartName():"") + .setComponent(Objects.nonNull(part) ? part.getPartName() : "") .setUseTime(ticket.getUseTime()) .setDescription(ticket.getDescription()) .setState(ticket.getState()) .setCreateUserName(user.getName()) .setCreateTime(DateTimeUtil.format(ticket.getCreateTime())) - .setCompanyName(StrUtil.join(",",companys.stream().map(TBaseCustomer::getAgencyCompanyName).collect(Collectors.toList()))) + .setCompanyName(StrUtil.join(",", companys.stream().map(TBaseCustomer::getAgencyCompanyName).collect(Collectors.toList()))) .setUrgency(ticket.getUrgency()) .setUpdateTime(DateTimeUtil.format(ticket.getUpdateTime())) .setHandleUserName(handle) @@ -549,7 +551,7 @@ public class TicketController extends ControllerBase { response.setContentType(MediaType.APPLICATION_PDF_VALUE); String encode = URLEncoder.encode(ticket.getTitle() + ".pdf", StandardCharsets.UTF_8); - response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=" +encode ); + response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "inline;filename=" + encode); // 生成PDF try { ITextRenderer renderer = new ITextRenderer(); @@ -580,15 +582,15 @@ public class TicketController extends ControllerBase { @GetMapping("getTicket") public ApiResult getTicket(@Valid @RequestParam @NotNull Integer id) { Ticket ticket = ticketService.getById(id); - AdminUser adminUser=StrUtil.equals(ticket.getUserPlatform(),Constant.FROM_ADMIN)?adminUserService.getById(ticket.getUserId()):null; + AdminUser adminUser = StrUtil.equals(ticket.getUserPlatform(), Constant.FROM_ADMIN) ? adminUserService.getById(ticket.getUserId()) : null; AppUser user = StrUtil.equals(ticket.getUserPlatform(), Constant.FROM_APP) ? appUserService.getById(ticket.getUserId()) : null; String areaName = ""; if (Objects.nonNull(user)) - if (user.getIsPrimary()){ - areaName=StrUtil.join(",",customerService.getAreas(Arrays.stream(user.getCompanyId().split(",")).map(Integer::parseInt).collect(Collectors.toList()))); - }else if (Objects.nonNull(user.getAreaId())){ - areaName = appAreaService.getById(user.getAreaId()).getName(); - } + if (user.getIsPrimary()) { + areaName = StrUtil.join(",", customerService.getAreas(Arrays.stream(user.getCompanyId().split(",")).map(Integer::parseInt).collect(Collectors.toList()))); + } else if (Objects.nonNull(user.getAreaId())) { + areaName = appAreaService.getById(user.getAreaId()).getName(); + } // TBaseCustomer company = customerService.getById(Integer.valueOf(user.getCompanyId())); DeviceInfoVO device = deviceService.getByDeviceNo(ticket.getDeviceNo()); String warrantyStateDesc = ""; @@ -602,8 +604,8 @@ public class TicketController extends ControllerBase { // List adminUsers = adminUserService.listByIds(handleIds); // handle = adminUsers.stream().map(AdminUser::getUserName).collect(Collectors.joining(",")); // } - List handleIds=StrUtil.split(ticket.getHandle(),",").stream().map(Integer::parseInt).collect(Collectors.toList()); - List cqms=adminUserService.getCQMIds(); + List handleIds = StrUtil.split(ticket.getHandle(), ",").stream().map(Integer::parseInt).collect(Collectors.toList()); + List cqms = adminUserService.getCQMIds(); TBasePart part = partService.getByIdAndLanguage(ticket.getComponentId(), Constant.DEFAULT_LANGUAGE_CODE); TicketInfoVO vo = new TicketInfoVO() .setId(ticket.getId()) @@ -613,7 +615,7 @@ public class TicketController extends ControllerBase { .setDeviceAddress(ticket.getDeviceAddress()) .setModelNo(device.getModelNo()) .setDeviceType(device.getDeviceType()) - .setComponent(Objects.nonNull(part)?part.getPartName():"") + .setComponent(Objects.nonNull(part) ? part.getPartName() : "") .setUseTime(ticket.getUseTime()) .setDescription(ticket.getDescription()) .setState(ticket.getState()) @@ -629,8 +631,8 @@ public class TicketController extends ControllerBase { .setImages(getFileVOs(ticket.getImages())) .setAttachments(getFileVOs(ticket.getAttachments())) .setCreateUserId(ticket.getUserId()) - .setCreateUserName(Objects.nonNull(user)?user.getName():adminUser.getUserName()) - .setCreateUserAvatar(Objects.nonNull(user)?user.getAvatar():adminUser.getAvatar()) + .setCreateUserName(Objects.nonNull(user) ? user.getName() : adminUser.getUserName()) + .setCreateUserAvatar(Objects.nonNull(user) ? user.getAvatar() : adminUser.getAvatar()) .setCreateTime(ticket.getCreateTime()) .setAreaName(areaName) .setCompanyName(device.getCustomerName()) @@ -644,8 +646,8 @@ public class TicketController extends ControllerBase { return ApiResult.success(vo); } - private List getFileVOs(String ids){ - if (StrUtil.isBlank(ids)){ + private List getFileVOs(String ids) { + if (StrUtil.isBlank(ids)) { return Collections.emptyList(); } return fileUploadRecordService.listByIds(StrUtil.split(ids, ",").stream().map(Integer::parseInt).collect(Collectors.toList())) @@ -655,7 +657,7 @@ public class TicketController extends ControllerBase { } private TicketEvaluateVO getTicketEvaluate(Integer ticketId) { - TicketEvaluate ticketEvaluate = ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId,ticketId).one(); + TicketEvaluate ticketEvaluate = ticketEvaluateService.lambdaQuery().eq(TicketEvaluate::getTicketId, ticketId).one(); if (Objects.isNull(ticketEvaluate)) { return null; } @@ -718,7 +720,7 @@ public class TicketController extends ControllerBase { for (ChatMessageVO messageVO : messageVOS) { if (Objects.equals(messageVO.getSenderId(), userId) || readeds.contains(messageVO.getId())) { messageVO.setReaded(true); - } else if(Objects.nonNull(messageVO.getId())){ + } else if (Objects.nonNull(messageVO.getId())) { notReadeds.add(messageVO.getId()); } } @@ -743,9 +745,9 @@ public class TicketController extends ControllerBase { VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())) .throwMessage("当前工单状态不允许发送消息"); - List adminUsers=adminUserService.getTickerMangagers(); - adminUsers.addAll(StrUtil.split(ticket.getHandle(),",").stream().map(Integer::parseInt).collect(Collectors.toList())); - if (StrUtil.equals(Constant.FROM_ADMIN,ticket.getUserPlatform())){ + List adminUsers = adminUserService.getTickerMangagers(); + adminUsers.addAll(StrUtil.split(ticket.getHandle(), ",").stream().map(Integer::parseInt).collect(Collectors.toList())); + if (StrUtil.equals(Constant.FROM_ADMIN, ticket.getUserPlatform())) { adminUsers.add(ticket.getUserId()); } VUtils.trueThrowBusinessError(adminUsers.stream() @@ -767,14 +769,14 @@ public class TicketController extends ControllerBase { .setImages(request.getImages()) .setRemindUsers(request.getRemindUsers()) .setAudioUrl(request.getAudioUrl()); - if(Objects.nonNull(request.getQuoteId())){ + if (Objects.nonNull(request.getQuoteId())) { ChatMessageDTO quoteMessage = ticketChatService.getMessage(request.getTicketId(), request.getQuoteId()); message.setQuote(quoteMessage); } ticketChatService.addMessage(request.getTicketId(), message); //推送消息 - ssePushService.sendTicketMessageToAdmin(request.getTicketId(),message); - ssePushService.sendTicketMessageToApp(request.getTicketId(),message); + ssePushService.sendTicketMessageToAdmin(request.getTicketId(), message); + ssePushService.sendTicketMessageToApp(request.getTicketId(), message); ticketEventPublisher.publishTicketReplyEvent(ticket); return ApiResult.success(); } @@ -785,11 +787,11 @@ public class TicketController extends ControllerBase { **/ @PostMapping("withdrawChatMessage") @ApiMark(moduleName = "工单管理", apiName = "撤回聊天记录") - public ApiResult withdrawChatMessage(@Valid @RequestBody WithdrawChatMessageRequest request){ + public ApiResult withdrawChatMessage(@Valid @RequestBody WithdrawChatMessageRequest request) { ticketChatService.withdrawMessage(request.getTicketId(), request.getMessageId()); //推送消息 - ssePushService.sendTicketMessageWithdrawToAdmin(request.getTicketId(),request.getMessageId()); - ssePushService.sendTicketMessageWithdrawToApp(request.getTicketId(),request.getMessageId()); + ssePushService.sendTicketMessageWithdrawToAdmin(request.getTicketId(), request.getMessageId()); + ssePushService.sendTicketMessageWithdrawToApp(request.getTicketId(), request.getMessageId()); return ApiResult.success(); } @@ -800,7 +802,7 @@ public class TicketController extends ControllerBase { **/ @GetMapping("getSolutionMeasures") @ApiMark(moduleName = "工单管理", apiName = "获取工单解决方案措施") - public ApiResult getSolutionMeasures(@Valid @RequestParam @NotNull Integer ticketId){ + public ApiResult getSolutionMeasures(@Valid @RequestParam @NotNull Integer ticketId) { return ApiResult.success(ticketSolutionService.getSolutionMeasures(ticketId)); } @@ -810,11 +812,11 @@ public class TicketController extends ControllerBase { **/ @PostMapping("saveSolutionMeasures") @ApiMark(moduleName = "工单管理", apiName = "保存工单解决方案措施") - public ApiResult saveSolutionMeasures(@Valid @RequestBody SolutionMeasuresSaveRequest request){ + public ApiResult saveSolutionMeasures(@Valid @RequestBody SolutionMeasuresSaveRequest request) { Ticket ticket = ticketSolutionService.saveSolutionMeasures(request); List audits = ticketSolutionAuditService.getByTicket(request.getTicketId()); audits.forEach(audit -> { - if (Objects.equals(audit.getState(),0)) { + if (Objects.equals(audit.getState(), 0)) { adminMessageService.add( new AdminMessage() .setNo(ticket.getNo()) @@ -839,7 +841,7 @@ public class TicketController extends ControllerBase { **/ @GetMapping("getSolutionReviewDepartment") @ApiMark(moduleName = "工单管理", apiName = "获取工单解决方案评审部门") - public ApiResult> getSolutionReviewDepartment(@Valid @RequestParam @NotNull Integer ticketId){ + public ApiResult> getSolutionReviewDepartment(@Valid @RequestParam @NotNull Integer ticketId) { return ApiResult.success(ticketSolutionAuditService.getByTicket(ticketId)); } @@ -849,7 +851,7 @@ public class TicketController extends ControllerBase { **/ @PostMapping("saveSolutionReviewDepartment") @ApiMark(moduleName = "工单管理", apiName = "保存工单解决方案评审部门") - public ApiResult saveSolutionReviewDepartment(@Valid @RequestBody SolutionReviewDepartmentSaveRequest request){ + public ApiResult saveSolutionReviewDepartment(@Valid @RequestBody SolutionReviewDepartmentSaveRequest request) { ticketSolutionAuditService.saveSolutionReviewDepartment(request); return ApiResult.success(); } @@ -891,23 +893,23 @@ public class TicketController extends ControllerBase { **/ @GetMapping("passSolution") @ApiMark(moduleName = "工单管理", apiName = "通过工单解决方案") - public ApiResult passSolution(@Valid @RequestParam @NotNull Integer ticketId){ - if(ticketSolutionAuditService.pass(ticketId)){ - Ticket ticket = ticketService.getById(ticketId); - ticketEventPublisher.publishTicketCloseEvent(ticket); - ChatMessageDTO message = new ChatMessageDTO() - .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) - .setFrom("system") - .setTicketState(ticket.getState()) - .setSenderId(0) - .setSenderName("服务助手") - .setContent("工单已关闭
感谢你的使用,如有问题,请重新提交新的工单。") - .setCreateTime(Instant.now()); - ticketChatService.addMessage(ticketId, message); - //推送消息 - ssePushService.sendTicketMessageToAdmin(ticket.getId(),message); - ssePushService.sendTicketMessageToApp(ticket.getId(),message); - } + public ApiResult passSolution(@Valid @RequestParam @NotNull Integer ticketId) { + if (ticketSolutionAuditService.pass(ticketId)) { + Ticket ticket = ticketService.getById(ticketId); + ticketEventPublisher.publishTicketCloseEvent(ticket); + ChatMessageDTO message = new ChatMessageDTO() + .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) + .setFrom("system") + .setTicketState(ticket.getState()) + .setSenderId(0) + .setSenderName("服务助手") + .setContent("工单已关闭
感谢你的使用,如有问题,请重新提交新的工单。") + .setCreateTime(Instant.now()); + ticketChatService.addMessage(ticketId, message); + //推送消息 + ssePushService.sendTicketMessageToAdmin(ticket.getId(), message); + ssePushService.sendTicketMessageToApp(ticket.getId(), message); + } return ApiResult.success(); } @@ -917,7 +919,7 @@ public class TicketController extends ControllerBase { */ @PostMapping("exportTicketReport") @ApiMark(moduleName = "工单管理", apiName = "导出工单报表") - public void exportTicketReport(HttpServletResponse response,@Valid @RequestBody AdminTicketSearchRequest request) throws IOException { + public void exportTicketReport(HttpServletResponse response, @Valid @RequestBody AdminTicketSearchRequest request) throws IOException { request.setPageSize(Integer.MAX_VALUE); List datas = ticketService.exportSearch(request); EecExcelUtil.export("工单报表", "sheet1", Convert.toList(AdminTicketReportVO.class, datas), response); @@ -929,7 +931,7 @@ public class TicketController extends ControllerBase { */ @GetMapping("/exportTicketExcel") @ApiMark(moduleName = "工单管理", apiName = "导出工单详情为excel") - public void exportExcel(HttpServletResponse response,@Valid @RequestParam @NotNull Integer ticketId) throws Exception { + public void exportExcel(HttpServletResponse response, @Valid @RequestParam @NotNull Integer ticketId) throws Exception { Ticket ticket = ticketService.getById(ticketId); VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); Workbook workbook = new XSSFWorkbook(); @@ -958,89 +960,89 @@ public class TicketController extends ControllerBase { Row row0 = sheet.createRow(0); row0.setHeightInPoints(25); row0.createCell(0).setCellStyle(centerStyle); - addMergedRegion(sheet,0, 0, 0, 2); - addMergedRegion(sheet,0, 0, 3, 11); + addMergedRegion(sheet, 0, 0, 0, 2); + addMergedRegion(sheet, 0, 0, 3, 11); createCell(row0, 3, getTitleStyle(workbook), "CSF系统问题解决方案"); //第一行 Row row1 = sheet.createRow(1); row1.setHeightInPoints(height); createCell(row1, 0, centerStyle, "主题"); - addMergedRegion(sheet,1, 1, 1, 4); + addMergedRegion(sheet, 1, 1, 1, 4); createCell(row1, 1, normalStyle, ticket.getTitle()); createCell(row1, 5, centerStyle, "事故等级"); createCell(row1, 6, centerStyle, "一般" + (Objects.equals(ticket.getAccidentLevel(), Byte.valueOf("0")) ? "\u2611" : "\u2610")); createCell(row1, 7, normalStyle, ""); createCell(row1, 8, centerStyle, "较严重" + (Objects.equals(ticket.getAccidentLevel(), Byte.valueOf("1")) ? "\u2611" : "\u2610")); createCell(row1, 9, normalStyle, ""); - createCell(row1, 10, centerStyle, "严重" + (Objects.equals(ticket.getAccidentLevel(), Byte.valueOf("2")) ? "\u2611" : "\u2610")); + createCell(row1, 10, centerStyle, "严重" + (Objects.equals(ticket.getAccidentLevel(), Byte.valueOf("2")) ? "\u2611" : "\u2610")); createCell(row1, 11, normalStyle, ""); //第二行 Row row2 = sheet.createRow(2); row2.setHeightInPoints(height); createCell(row2, 0, centerStyle, "工单编号"); - addMergedRegion(sheet,2, 2, 1, 4); + addMergedRegion(sheet, 2, 2, 1, 4); createCell(row2, 1, normalStyle, ticket.getNo()); createCell(row2, 5, centerStyle, "设备编号"); - addMergedRegion(sheet,2, 2, 6, 11); + addMergedRegion(sheet, 2, 2, 6, 11); createCell(row2, 6, normalStyle, ticket.getDeviceNo()); //第三行 Row row3 = sheet.createRow(3); createCell(row3, 0, centerStyle, "提交人"); - addMergedRegion(sheet,3, 3, 1, 4); + addMergedRegion(sheet, 3, 3, 1, 4); AppUser user = appUserService.getById(ticket.getUserId()); createCell(row3, 1, normalStyle, user.getName()); createCell(row3, 5, centerStyle, "反馈日期"); - addMergedRegion(sheet,3, 3, 6, 11); + addMergedRegion(sheet, 3, 3, 6, 11); createCell(row3, 6, normalStyle, DateTimeUtil.format(ticket.getCreateTime())); //第四行 Row row4 = sheet.createRow(4); row4.setHeightInPoints(height); createCell(row4, 0, centerStyle, "设备地点"); - addMergedRegion(sheet,4, 4, 1, 4); + addMergedRegion(sheet, 4, 4, 1, 4); createCell(row4, 1, normalStyle, ticket.getDeviceAddress()); createCell(row4, 5, centerStyle, "处理人员"); - addMergedRegion(sheet,4, 4, 6, 11); + addMergedRegion(sheet, 4, 4, 6, 11); createCell(row4, 6, normalStyle, ticket.getHandleName()); //第五行 Row row5 = sheet.createRow(5); row5.setHeightInPoints(height); createCell(row5, 0, centerStyle, "问题类型"); - addMergedRegion(sheet,5, 5, 1, 4); + addMergedRegion(sheet, 5, 5, 1, 4); createCell(row5, 1, normalStyle, ticket.getQuestion()); createCell(row5, 5, centerStyle, "问题部位"); - addMergedRegion(sheet,5, 5, 6, 11); + addMergedRegion(sheet, 5, 5, 6, 11); TBasePart part = partService.getByIdAndLanguage(ticket.getComponentId(), Constant.DEFAULT_LANGUAGE_CODE); createCell(row5, 6, normalStyle, Objects.nonNull(part) ? part.getPartName() : ""); //第六行 Row row6 = sheet.createRow(6); row6.setHeightInPoints(height); createCell(row6, 0, centerStyle, "问题描述"); - addMergedRegion(sheet,6, 6, 1, 11); + addMergedRegion(sheet, 6, 6, 1, 11); createCell(row6, 1, normalStyle, ticket.getDescription()); //第七行 Row row7 = sheet.createRow(7); row7.setHeightInPoints(height); - List fileIds=CollectionUtil.addAll(StrUtil.split(ticket.getAttachments(),","), StrUtil.split(ticket.getImages(),",")) + List fileIds = CollectionUtil.addAll(StrUtil.split(ticket.getAttachments(), ","), StrUtil.split(ticket.getImages(), ",")) .stream() .map(Integer::parseInt) .collect(Collectors.toList()); List images = new ArrayList<>(); - if (CollectionUtil.isNotEmpty(fileIds)){ - images=fileUploadRecordService.listByIds(fileIds) + if (CollectionUtil.isNotEmpty(fileIds)) { + images = fileUploadRecordService.listByIds(fileIds) .stream() .map(FileUploadRecord::getUrl) - .filter(url->url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".jpeg")) + .filter(url -> url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".jpeg")) .collect(Collectors.toList()); } int rowIndex = 6; int rows = images.size() % 2 == 0 ? images.size() / 2 : images.size() / 2 + 1; if (rows > 1) { - addMergedRegion(sheet,rowIndex + 1, rowIndex + rows, 0, 0); + addMergedRegion(sheet, rowIndex + 1, rowIndex + rows, 0, 0); } createCell(row7, 0, centerStyle, "案例照片"); if (rows == 0) { - addMergedRegion(sheet,rowIndex + 1, rowIndex + 1, 1, 5); - addMergedRegion(sheet,rowIndex + 1, rowIndex + 1, 6, 11); + addMergedRegion(sheet, rowIndex + 1, rowIndex + 1, 1, 5); + addMergedRegion(sheet, rowIndex + 1, rowIndex + 1, 6, 11); rowIndex++; } else { for (int i = 0; i < images.size(); i++) { @@ -1052,34 +1054,34 @@ public class TicketController extends ControllerBase { } } if (images.size() % 2 != 0) { - addMergedRegion(sheet,rowIndex, rowIndex, 6, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 6, 11); } } rowIndex++; Row row8 = sheet.createRow(rowIndex); row8.setHeightInPoints(height); - addMergedRegion(sheet,rowIndex, rowIndex, 0, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 0, 11); createCell(row8, 0, normalStyle, "根本原因分析"); rowIndex++; Row row9 = sheet.createRow(rowIndex); row9.setHeightInPoints(height); - addMergedRegion(sheet,rowIndex, rowIndex, 0, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 0, 11); createCell(row9, 0, normalStyle, ticket.getReason()); //解决方案 - List solutions = ticketSolutionService.lambdaQuery().eq(TicketSolution::getTicketId,ticketId).orderByAsc(TicketSolution::getId).list(); + List solutions = ticketSolutionService.lambdaQuery().eq(TicketSolution::getTicketId, ticketId).orderByAsc(TicketSolution::getId).list(); if (CollectionUtil.isNotEmpty(solutions)) { - Map> map=solutions.stream().collect(Collectors.groupingBy(TicketSolution::getDictionaryItemName, LinkedHashMap::new, Collectors.toList())); + Map> map = solutions.stream().collect(Collectors.groupingBy(TicketSolution::getDictionaryItemName, LinkedHashMap::new, Collectors.toList())); for (Map.Entry> item : map.entrySet()) { rowIndex++; Row row10 = sheet.createRow(rowIndex); row10.setHeightInPoints(height); createCell(row10, 0, centerStyle, "No."); - addMergedRegion(sheet,rowIndex, rowIndex, 1, 6); + addMergedRegion(sheet, rowIndex, rowIndex, 1, 6); createCell(row10, 1, centerStyle, item.getKey()); createCell(row10, 7, centerStyle, "负责人"); createCell(row10, 8, centerStyle, "计划日期"); createCell(row10, 9, centerStyle, "确认日期"); - addMergedRegion(sheet,rowIndex, rowIndex, 10, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 10, 11); createCell(row10, 10, centerStyle, "备注"); for (int i = 0; i < item.getValue().size(); i++) { rowIndex++; @@ -1087,12 +1089,12 @@ public class TicketController extends ControllerBase { Row row11 = sheet.createRow(rowIndex); row11.setHeightInPoints(height); createCell(row11, 0, centerStyle, String.valueOf(i + 1)); - addMergedRegion(sheet,rowIndex, rowIndex, 1, 6); + addMergedRegion(sheet, rowIndex, rowIndex, 1, 6); createCell(row11, 1, normalStyle, solution.getDescription()); createCell(row11, 7, centerStyle, solution.getSuperintendent()); createCell(row11, 8, centerStyle, solution.getScheduleDate()); createCell(row11, 9, centerStyle, solution.getConfirmedDate()); - addMergedRegion(sheet,rowIndex, rowIndex, 10, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 10, 11); createCell(row11, 10, normalStyle, solution.getRemark()); } } @@ -1106,7 +1108,7 @@ public class TicketController extends ControllerBase { rowIndex++; Row row12 = sheet.createRow(rowIndex); row12.setHeightInPoints(height); - addMergedRegion(sheet,rowIndex, rowIndex, 0, 11); + addMergedRegion(sheet, rowIndex, rowIndex, 0, 11); createCell(row12, 0, normalStyle, "相关部门审核确认"); rowIndex++; Row row13 = sheet.createRow(rowIndex); @@ -1115,9 +1117,9 @@ public class TicketController extends ControllerBase { row14.setHeightInPoints(height); for (int i = 0; i < reviewDepartments.size(); i++) { SolutionReviewDepartmentVO reviewDepartment = reviewDepartments.get(i); - addMergedRegion(sheet,rowIndex, rowIndex, i * 2, i * 2 + 1); + addMergedRegion(sheet, rowIndex, rowIndex, i * 2, i * 2 + 1); createCell(row13, i * 2, centerStyle, reviewDepartment.getDeptName() + "(" + reviewDepartment.getUserName() + ")"); - addMergedRegion(sheet,rowIndex + 1, rowIndex + 1, i * 2, i * 2 + 1); + addMergedRegion(sheet, rowIndex + 1, rowIndex + 1, i * 2, i * 2 + 1); createCell(row14, i * 2, centerStyle, Objects.isNull(reviewDepartment.getState()) ? "" : (Objects.equals(reviewDepartment.getState(), 1) ? "通过" : "不通过")); } } @@ -1130,7 +1132,7 @@ public class TicketController extends ControllerBase { } } - private void addMergedRegion(Sheet sheet,int firstRow, int lastRow, int firstCol, int lastCol){ + private void addMergedRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) { CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol); sheet.addMergedRegion(region); RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet); @@ -1139,13 +1141,13 @@ public class TicketController extends ControllerBase { RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet); } - private void createCell(Row row,int index,CellStyle style,String value){ - Cell cell =row.createCell(index); + private void createCell(Row row, int index, CellStyle style, String value) { + Cell cell = row.createCell(index); cell.setCellValue(value); cell.setCellStyle(style); } - private void bindPic(String url, Workbook workbook,Sheet sheet, int rowIndex, int colStart, int colEnd){ + private void bindPic(String url, Workbook workbook, Sheet sheet, int rowIndex, int colStart, int colEnd) { try { byte[] imageBytes; try (InputStream inputStream = new URL(url).openStream()) { @@ -1153,24 +1155,24 @@ public class TicketController extends ControllerBase { } int pictureIdx = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_PNG); Drawing drawing = sheet.createDrawingPatriarch(); - addMergedRegion(sheet,rowIndex,rowIndex,colStart,colEnd-1); + addMergedRegion(sheet, rowIndex, rowIndex, colStart, colEnd - 1); ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor(); anchor.setCol1(colStart); anchor.setRow1(rowIndex); anchor.setCol2(colEnd); - anchor.setRow2(rowIndex+1); + anchor.setRow2(rowIndex + 1); drawing.createPicture(anchor, pictureIdx); Row row = sheet.getRow(rowIndex); if (row == null) { row = sheet.createRow(rowIndex); } row.setHeightInPoints(200); - }catch (Exception ex){ - log.error("图片加载失败",ex); + } catch (Exception ex) { + log.error("图片加载失败", ex); } } - private CellStyle getNormalStyle(Workbook workbook){ + private CellStyle getNormalStyle(Workbook workbook) { CellStyle centerStyle = workbook.createCellStyle(); centerStyle.setAlignment(HorizontalAlignment.LEFT); centerStyle.setVerticalAlignment(VerticalAlignment.CENTER); @@ -1189,7 +1191,7 @@ public class TicketController extends ControllerBase { return centerStyle; } - private CellStyle getCenterStyle(Workbook workbook){ + private CellStyle getCenterStyle(Workbook workbook) { CellStyle centerStyle = workbook.createCellStyle(); centerStyle.setAlignment(HorizontalAlignment.CENTER); centerStyle.setVerticalAlignment(VerticalAlignment.CENTER); @@ -1208,7 +1210,7 @@ public class TicketController extends ControllerBase { return centerStyle; } - private CellStyle getTitleStyle(Workbook workbook){ + private CellStyle getTitleStyle(Workbook workbook) { CellStyle titleStyle = workbook.createCellStyle(); titleStyle.setAlignment(HorizontalAlignment.CENTER); titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); @@ -1295,6 +1297,8 @@ public class TicketController extends ControllerBase { ssePushService.sendTicketCallToAdmin(adminUser, receiveUserId, ticketId); } ticketEventPublisher.publishTicketCallBeginEvent(ticketId, adminUser.getUserName()); + stringRedisTemplate.opsForSet().add(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, receiveUserFrom + "-" + receiveUserId); + stringRedisTemplate.expire(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, 1, TimeUnit.MINUTES); return ApiResult.success(); } @@ -1304,14 +1308,14 @@ public class TicketController extends ControllerBase { */ @Transactional @PostMapping("addCallUser") - public ApiResult addCallUser(@Valid @RequestBody CallUserAddRequest request){ + 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("未在通话中"); - request.getUserIds().forEach(userId->{ + request.getUserIds().forEach(userId -> { AdminUser adminUser1 = adminUserService.getById(userId); if (Objects.nonNull(adminUser1)) { uniPushService.send(new UniPushMessage() @@ -1332,6 +1336,8 @@ public class TicketController extends ControllerBase { ); ssePushService.sendTicketCallToAdmin(adminUser, userId, request.getTicketId()); // ticketCallJoinService.add(ticketCall.getId(), userId, Constant.FROM_ADMIN); + stringRedisTemplate.opsForSet().add(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId(), Constant.FROM_ADMIN + "-" + userId); + stringRedisTemplate.expire(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId(), 1, TimeUnit.MINUTES); } }); return ApiResult.success(); @@ -1342,7 +1348,7 @@ public class TicketController extends ControllerBase { * @param ticketId 工单编号 */ @GetMapping("call/joinChannel") - public ApiResult joinChannel(@Valid @RequestParam @NotNull Integer ticketId){ + public ApiResult joinChannel(@Valid @RequestParam @NotNull Integer ticketId) throws IOException, InterruptedException { Ticket ticket = ticketService.getById(ticketId); VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())) @@ -1365,6 +1371,24 @@ public class TicketController extends ControllerBase { // ) // ) // ); + ShengWangChannelUserListDTO channelUsers = shengWangService.getChannelUsers("ticket" + ticketId); + VUtils.trueThrowBusinessError(!channelUsers.isChannelEexist()).throwMessage("通话已结束"); + VUtils.trueThrowBusinessError(channelUsers.getUsers().contains(ShengWangUtil.getUserId(AdminUserUtil.getUserId(), Constant.FROM_ADMIN))) + .throwMessage("你已在通话中"); + ssePushService.sendTicketCallJoinedToAdmin(AdminUserUtil.getUserId(), ticketId); + uniPushService.send(new UniPushMessage() + .setSenderId("admin-uid-" + AdminUserUtil.getUserId())//不重要 + .setReceiverId("admin-uid-" + AdminUserUtil.getUserId()) + .setSendData(new UniPushMessageBody() + .setTitle("视频通话") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(ticketId) + .setUserId(AdminUserUtil.getUserId()) + .setCategory("ticketCallJoined") + .setFrom("admin") + ) + ) + ); return ApiResult.success(); } @@ -1373,74 +1397,110 @@ public class TicketController extends ControllerBase { * @param request 请求信息 */ @PostMapping("call/hangUp") - public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) { + public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) throws IOException, InterruptedException { // TicketCall ticketCall = ticketCallService.getLast(request.getTicketId()); // if (Objects.isNull(ticketCall)) return ApiResult.success(); - if (request.getReject()) { - AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId()); - if (StrUtil.equals(request.getFrom(), Constant.FROM_APP)) { - uniPushService.send(new UniPushMessage() - .setSenderId("admin-uid-" + adminUser.getId()) - .setReceiverId("app-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.sendTicketCallHangUpToApp(request.getTicketId(), request.getFromUserId(), adminUser); - } else if (StrUtil.equals(request.getFrom(), Constant.FROM_ADMIN)) { - if (Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())){ - Ticket ticket = ticketService.getById(request.getTicketId()); - int handlerId= Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); +// if (request.getReject()) { +// AdminUser adminUser = adminUserService.getById(AdminUserUtil.getUserId()); +// if (StrUtil.equals(request.getFrom(), Constant.FROM_APP)) { +// uniPushService.send(new UniPushMessage() +// .setSenderId("admin-uid-" + adminUser.getId()) +// .setReceiverId("app-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.sendTicketCallHangUpToApp(request.getTicketId(), request.getFromUserId(), adminUser); +// } else if (StrUtil.equals(request.getFrom(), Constant.FROM_ADMIN)) { +// if (Objects.equals(request.getFromUserId(), AdminUserUtil.getUserId())) { +// Ticket ticket = ticketService.getById(request.getTicketId()); +// int handlerId = Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); +// 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); +// } 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); +// } +// } +// } +//// if (ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, request.getReject())) { +// ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId()); +//// } + + stringRedisTemplate.opsForSet().remove(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId(), Constant.FROM_ADMIN + "-" + AdminUserUtil.getUserId()); + if (Objects.equals(0L, stringRedisTemplate.opsForSet().size(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId()))) { + ShengWangChannelUserListDTO channelUserListDTO = shengWangService.getChannelUsers("ticket" + request.getTicketId()); + if (!channelUserListDTO.isChannelEexist() || channelUserListDTO.getUsers().size() <= 1) { + ssePushService.sendTicketCallEnd(request.getTicketId()); + Integer userId = CollectionUtil.get(channelUserListDTO.getUsers(), 0); + if (Objects.nonNull(userId)) { + String from = userId.toString().startsWith("1") ? "app" : "admin"; + userId = Integer.valueOf(userId.toString().substring(1)); uniPushService.send(new UniPushMessage() - .setSenderId("admin-uid-" + adminUser.getId()) - .setReceiverId("admin-uid-" + handlerId) + .setSenderId(from + "-uid-" + userId)//不重要 + .setReceiverId(from + "-uid-" + userId) .setSendData(new UniPushMessageBody() - .setTitle("挂断视频通话") - .setContent(adminUser.getUserName() + "取消了与您的视频通话") + .setTitle("视频通话结束") .setPayload(new UniPushMessageCallPayload() .setTicketId(request.getTicketId()) - .setUserId(adminUser.getId()) - .setUserName(adminUser.getUserName()) - .setUserAvatar(adminUser.getAvatar()) - .setCategory("ticketCallCancel") + .setUserId(userId) + .setCategory("ticketCallEnd") .setFrom("admin") ) ) ); - ssePushService.sendTicketCallCancelToAdmin(request.getTicketId(), handlerId, adminUser); - }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); } } } -// if (ticketCallJoinService.hangUp(ticketCall.getId(), AdminUserUtil.getUserId(), Constant.FROM_ADMIN, request.getReject())) { - ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId()); -// } return ApiResult.success(); } + + /** + * 获取声网频道用户列表 + * @param ticketId 工单ID + * @return 用户列表 + */ + @GetMapping("getShengWangChannelUsers") + public ApiResult> getShengWangChannelUsers(Integer ticketId) throws IOException, InterruptedException { + return ApiResult.success(shengWangService.getChannelUsers("ticket" + ticketId).getUsers()); + } } \ No newline at end of file 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 index 7e88ebe3..01bd8f4c 100644 --- 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 @@ -1,20 +1,13 @@ package com.nflg.mobilebroken.admin.event; -import cn.hutool.core.collection.CollectionUtil; import com.nflg.mobilebroken.admin.service.ShengWangService; import com.nflg.mobilebroken.admin.service.SsePushService; -import com.nflg.mobilebroken.common.constant.TicketState; -import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO; 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.io.IOException; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware { private final Integer ticketId; @@ -32,23 +25,24 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.ssePushService = applicationContext.getBean(SsePushService.class); this.ticketChatService = applicationContext.getBean(TicketChatService.class); + this.shengWangService = applicationContext.getBean(ShengWangService.class); } - public void send() throws IOException, InterruptedException { - TimeUnit.SECONDS.sleep(2); - if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) { - ChatMessageDTO message = new ChatMessageDTO() - .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) - .setFrom("call") - .setTicketState(TicketState.Processing.getState()) - .setSenderId(0) - .setSenderName("通话助手") - .setContent("视频通话已结束") - .setCreateTime(Instant.now()); - ticketChatService.addMessage(ticketId, message); - //推送消息 - ssePushService.sendTicketMessageToAdmin(ticketId, message); - ssePushService.sendTicketMessageToApp(ticketId, message); - } - } +// public void send() throws IOException, InterruptedException { +// TimeUnit.SECONDS.sleep(2); +// if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) { +// ChatMessageDTO message = new ChatMessageDTO() +// .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) +// .setFrom("call") +// .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 a1c714da..b9f73f28 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 @@ -5,8 +5,6 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import java.io.IOException; - @Component public class TicketEventListener { @@ -40,9 +38,9 @@ public class TicketEventListener { event.send(); } - @Async - @EventListener - public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException { - event.send(); - } +// @Async +// @EventListener +// public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException { +// event.send(); +// } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/ShengWangService.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/ShengWangService.java index 1e7590fc..6f682dd5 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/ShengWangService.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/service/ShengWangService.java @@ -45,6 +45,10 @@ public class ShengWangService { @Value("${shengwang.rtc.customerSecret}") private String customerSecret; + /** + * 获取所有频道 + * @return 频道列表 + */ public ShengWangChannelDTO getAllChannels() throws IOException, InterruptedException { HttpRequest request = HttpRequest.newBuilder() .GET() @@ -59,6 +63,26 @@ public class ShengWangService { return result.getData(); } + /** + * 查询频道用户列表 + * @param channelName 频道名称 + * @return 用户列表 + */ + public ShengWangChannelUserListDTO getChannelUsers(String channelName) throws IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder() + .GET() + .header("Authorization", generateAuthorization(customerKey, customerSecret)) + .uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName)) + .build(); + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + log.debug("getChannelUsers Response:" + response.body()); + VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败"); + ShengWangResponse result = objectMapper.readValue(response.body(), new TypeReference<>() { + }); + VUtils.trueThrowBusinessError(!result.isSuccess()).throwMessage("查询用户列表失败"); + return result.getData(); + } + /** * 创建规则 * @param channelName 频道名称 @@ -141,18 +165,4 @@ public class ShengWangService { // 创建 authorization header return "Basic " + base64Credentials; } - - public List getChannelUsers(String channelName) throws IOException, InterruptedException { - HttpRequest request = HttpRequest.newBuilder() - .GET() - .header("Authorization", generateAuthorization(customerKey, customerSecret)) - .uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName)) - .build(); - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - log.debug("getChannelUsers Response:" + response.body()); - VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败"); - ShengWangChannelUserResponseDTO result = objectMapper.readValue(response.body(), ShengWangChannelUserResponseDTO.class); - VUtils.trueThrowBusinessError(!result.getSuccess()).throwMessage("获取频道用户失败"); - return result.getData().isChannel_exist()?result.getData().getUsers():null; - } } 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 8cee0ead..e8944d6c 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 @@ -304,4 +304,28 @@ public class SsePushService { log.error("发送消息出错", e); } } + + public void sendTicketCallEnd(Integer ticketId) { + try { + TicketMessagePushRequest request = new TicketMessagePushRequest() + .setTicketId(ticketId) + .setMessage(new PushMessageDTO() + .setType("ticketCallEnd") + .setData(new PushMessageDataBody() + .setTargetId(ticketId) + .setType("ticketCallEnd") + .setData(new UniPushMessageCallPayload() + .setTicketId(ticketId) + .setFrom("admin") + ) + ) + ); + ApiResult result = sendMessage(request, "app"); + log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + result = sendMessage(request, "admin"); + log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + } catch (Exception e) { + log.error("发送消息出错", e); + } + } } diff --git a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/task/ShengWangScheduledTasks.java b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/task/ShengWangScheduledTasks.java index b7128c5a..9f9edeb9 100644 --- a/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/task/ShengWangScheduledTasks.java +++ b/nflg-mobilebroken-admin/src/main/java/com/nflg/mobilebroken/admin/task/ShengWangScheduledTasks.java @@ -1,28 +1,16 @@ package com.nflg.mobilebroken.admin.task; -import cn.hutool.core.collection.CollectionUtil; import com.nflg.mobilebroken.admin.service.ShengWangService; -import com.nflg.mobilebroken.common.constant.Constant; -import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelDTO; -import com.nflg.mobilebroken.common.pojo.dto.ShengWangChannelInfoDTO; -import com.nflg.mobilebroken.common.util.IdUtil; -import com.nflg.mobilebroken.repository.entity.TicketCall; -import com.nflg.mobilebroken.repository.entity.TicketCallJoin; import com.nflg.mobilebroken.repository.service.ITicketCallJoinService; import com.nflg.mobilebroken.repository.service.ITicketCallService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.slf4j.MDC; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; @ConditionalOnProperty(name = "shengwang.sync.enable", havingValue = "true", matchIfMissing = true) @Component @@ -45,83 +33,83 @@ public class ShengWangScheduledTasks { @Transactional @Scheduled(cron = "0 0/1 * * * ?") public void syncState() throws Exception { - MDC.put("traceId", IdUtil.getIdStr()); - log.info("开始执行声网通话状态同步"); - ShengWangChannelDTO dto = shengWangService.getAllChannels(); - log.info("共{}个频道", dto.getTotalSize()); - log.info("将不存在列表中的通话设置为已结束状态"); - List ticketCalls = ticketCallService.lambdaQuery() - .ne(TicketCall::getState, 2) - .notIn(dto.getTotalSize() > 0, TicketCall::getTicketId, dto.getChannels() - .stream() - .map(o -> Integer.valueOf(o.getChannelName().replace("ticket", ""))) - .collect(Collectors.toList())) - .list(); - if (CollectionUtil.isNotEmpty(ticketCalls)) { - ticketCalls.forEach(ticketCall -> { - ticketCall.setState(2); - ticketCall.setHangupTime(LocalDateTime.now()); - ticketCallService.updateById(ticketCall); - ticketCallJoinService.lambdaUpdate() - .set(TicketCallJoin::getState, 2) -// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) - .eq(TicketCallJoin::getCallId, ticketCall.getId()) - .update(); - }); - } - for (ShengWangChannelInfoDTO info : dto.getChannels()) { - log.info("处理频道:{}", info.getChannelName()); - TicketCall ticketCall = ticketCallService.lambdaQuery() - .eq(TicketCall::getTicketId, Integer.valueOf(info.getChannelName().replace("ticket", ""))) - .eq(TicketCall::getState, 1) - .one(); - if (Objects.nonNull(ticketCall)) { - log.info("获取频道用户"); - List channelUsers = shengWangService.getChannelUsers(info.getChannelName()); - log.info("频道用户:{}", channelUsers); - if (CollectionUtil.isEmpty(channelUsers)) { - ticketCallJoinService.lambdaUpdate() - .set(TicketCallJoin::getState, 2) -// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) - .eq(TicketCallJoin::getCallId, ticketCall.getId()) - .update(); - } else { - //用户端 - List userIds = channelUsers.stream() - .map(String::valueOf) - .filter(userId -> String.valueOf(userId).startsWith("1")) - .map(this::getUserId) - .collect(Collectors.toList()); - log.info("客户端用户:{}", userIds); - if (CollectionUtil.isNotEmpty(userIds)) { - ticketCallJoinService.lambdaUpdate() - .set(TicketCallJoin::getState, 2) -// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) - .eq(TicketCallJoin::getCallId, ticketCall.getId()) - .eq(TicketCallJoin::getFrom, Constant.FROM_APP) - .notIn(TicketCallJoin::getUserId, userIds) - .update(); - } - //管理端 - userIds = channelUsers.stream() - .map(String::valueOf) - .filter(userId -> String.valueOf(userId).startsWith("2")) - .map(this::getUserId) - .collect(Collectors.toList()); - log.info("管理端用户:{}", userIds); - if (CollectionUtil.isNotEmpty(userIds)) { - ticketCallJoinService.lambdaUpdate() - .set(TicketCallJoin::getState, 2) -// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) - .eq(TicketCallJoin::getCallId, ticketCall.getId()) - .eq(TicketCallJoin::getFrom, Constant.FROM_ADMIN) - .notIn(TicketCallJoin::getUserId, userIds) - .update(); - } - } - } - } - log.info("执行声网通话状态同步完毕"); +// MDC.put("traceId", IdUtil.getIdStr()); +// log.info("开始执行声网通话状态同步"); +// ShengWangChannelDTO dto = shengWangService.getAllChannels(); +// log.info("共{}个频道", dto.getTotalSize()); +// log.info("将不存在列表中的通话设置为已结束状态"); +// List ticketCalls = ticketCallService.lambdaQuery() +// .ne(TicketCall::getState, 2) +// .notIn(dto.getTotalSize() > 0, TicketCall::getTicketId, dto.getChannels() +// .stream() +// .map(o -> Integer.valueOf(o.getChannelName().replace("ticket", ""))) +// .collect(Collectors.toList())) +// .list(); +// if (CollectionUtil.isNotEmpty(ticketCalls)) { +// ticketCalls.forEach(ticketCall -> { +// ticketCall.setState(2); +// ticketCall.setHangupTime(LocalDateTime.now()); +// ticketCallService.updateById(ticketCall); +// ticketCallJoinService.lambdaUpdate() +// .set(TicketCallJoin::getState, 2) +//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) +// .eq(TicketCallJoin::getCallId, ticketCall.getId()) +// .update(); +// }); +// } +// for (ShengWangChannelInfoDTO info : dto.getChannels()) { +// log.info("处理频道:{}", info.getChannelName()); +// TicketCall ticketCall = ticketCallService.lambdaQuery() +// .eq(TicketCall::getTicketId, Integer.valueOf(info.getChannelName().replace("ticket", ""))) +// .eq(TicketCall::getState, 1) +// .one(); +// if (Objects.nonNull(ticketCall)) { +// log.info("获取频道用户"); +// List channelUsers = shengWangService.getChannelUsers(info.getChannelName()); +// log.info("频道用户:{}", channelUsers); +// if (CollectionUtil.isEmpty(channelUsers)) { +// ticketCallJoinService.lambdaUpdate() +// .set(TicketCallJoin::getState, 2) +//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) +// .eq(TicketCallJoin::getCallId, ticketCall.getId()) +// .update(); +// } else { +// //用户端 +// List userIds = channelUsers.stream() +// .map(String::valueOf) +// .filter(userId -> String.valueOf(userId).startsWith("1")) +// .map(this::getUserId) +// .collect(Collectors.toList()); +// log.info("客户端用户:{}", userIds); +// if (CollectionUtil.isNotEmpty(userIds)) { +// ticketCallJoinService.lambdaUpdate() +// .set(TicketCallJoin::getState, 2) +//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) +// .eq(TicketCallJoin::getCallId, ticketCall.getId()) +// .eq(TicketCallJoin::getFrom, Constant.FROM_APP) +// .notIn(TicketCallJoin::getUserId, userIds) +// .update(); +// } +// //管理端 +// userIds = channelUsers.stream() +// .map(String::valueOf) +// .filter(userId -> String.valueOf(userId).startsWith("2")) +// .map(this::getUserId) +// .collect(Collectors.toList()); +// log.info("管理端用户:{}", userIds); +// if (CollectionUtil.isNotEmpty(userIds)) { +// ticketCallJoinService.lambdaUpdate() +// .set(TicketCallJoin::getState, 2) +//// .set(TicketCallJoin::getHangupTime, LocalDateTime.now()) +// .eq(TicketCallJoin::getCallId, ticketCall.getId()) +// .eq(TicketCallJoin::getFrom, Constant.FROM_ADMIN) +// .notIn(TicketCallJoin::getUserId, userIds) +// .update(); +// } +// } +// } +// } +// log.info("执行声网通话状态同步完毕"); } private Integer getUserId(String userId){ 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 b4a7cce5..76e6be60 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 @@ -5,6 +5,7 @@ import cn.hutool.core.util.IdUtil; 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.ShengWangService; import com.nflg.mobilebroken.cfs.service.SsePushService; import com.nflg.mobilebroken.common.constant.Constant; import com.nflg.mobilebroken.common.constant.TicketState; @@ -13,10 +14,7 @@ import com.nflg.mobilebroken.common.pojo.PageData; import com.nflg.mobilebroken.common.pojo.dto.*; import com.nflg.mobilebroken.common.pojo.request.*; import com.nflg.mobilebroken.common.pojo.vo.*; -import com.nflg.mobilebroken.common.util.AppUserUtil; -import com.nflg.mobilebroken.common.util.MultilingualUtil; -import com.nflg.mobilebroken.common.util.PageUtil; -import com.nflg.mobilebroken.common.util.VUtils; +import com.nflg.mobilebroken.common.util.*; import com.nflg.mobilebroken.repository.entity.*; import com.nflg.mobilebroken.repository.service.*; import com.nflg.mobilebroken.starter.service.UniPushService; @@ -28,8 +26,10 @@ import javax.annotation.Resource; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.io.IOException; import java.time.Instant; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -99,6 +99,9 @@ public class TicketController extends ControllerBase { // @Resource // private ITicketCallJoinService ticketCallJoinService; + @Resource + private ShengWangService shengWangService; + /** * 搜索设备 * @param request 搜索条件 @@ -525,6 +528,8 @@ public class TicketController extends ControllerBase { ssePushService.sendTicketCallToAdmin(appUser, handlerUserId, ticketId); // ticketCallService.add(ticketId, AppUserUtil.getUserId(),Constant.FROM_APP, handlerUserId, Constant.FROM_ADMIN); ticketEventPublisher.publishTicketCallBeginEvent(ticketId,appUser.getName()); + stringRedisTemplate.opsForSet().add(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, Constant.FROM_ADMIN + "-" + handlerUserId); + stringRedisTemplate.expire(Constant.REDIS_KEY_TICKET_CALL_WAIT + ticketId, 1, TimeUnit.MINUTES); return ApiResult.success(); } @@ -533,7 +538,7 @@ public class TicketController extends ControllerBase { * @param ticketId 工单编号 */ @GetMapping("call/joinChannel") - public ApiResult joinChannel(@Valid @RequestParam @NotNull Integer ticketId){ + public ApiResult joinChannel(@Valid @RequestParam @NotNull Integer ticketId) throws IOException, InterruptedException { Ticket ticket = ticketService.getById(ticketId); VUtils.trueThrowBusinessError(Objects.isNull(ticket)).throwMessage("工单不存在"); VUtils.trueThrowBusinessError(!Objects.equals(ticket.getState(), TicketState.Processing.getState())) @@ -560,6 +565,24 @@ public class TicketController extends ControllerBase { // ) // ) // ); + ShengWangChannelUserListDTO channelUsers = shengWangService.getChannelUsers("ticket" + ticketId); + VUtils.trueThrowBusinessError(!channelUsers.isChannelEexist()).throwMessage("通话已结束"); + VUtils.trueThrowBusinessError(channelUsers.getUsers().contains(ShengWangUtil.getUserId(AppUserUtil.getUserId(), AppUserUtil.getFrom()))) + .throwMessage("你已在通话中"); + ssePushService.sendTicketCallJoined(AppUserUtil.getUserId(), ticketId, AppUserUtil.getFrom()); + uniPushService.send(new UniPushMessage() + .setSenderId(AppUserUtil.getFrom() + "-uid-" + AppUserUtil.getUserId())//不重要 + .setReceiverId(AppUserUtil.getFrom() + "-uid-" + AppUserUtil.getUserId()) + .setSendData(new UniPushMessageBody() + .setTitle("视频通话") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(ticketId) + .setUserId(AppUserUtil.getUserId()) + .setCategory("ticketCallJoined") + .setFrom("app") + ) + ) + ); return ApiResult.success(); } @@ -568,56 +591,91 @@ public class TicketController extends ControllerBase { * @param request 请求信息 */ @PostMapping("call/hangUp") - public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) { + public ApiResult hangUp(@Valid @RequestBody TicketCallHangUpRequest request) throws IOException, InterruptedException { // TicketCall ticketCall = ticketCallService.getLast(request.getTicketId()); - if (request.getReject()) { -// if (Objects.isNull(ticketCall)) return ApiResult.success(); - if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) { - AppUser appUser = appUserService.getById(AppUserUtil.getUserId()); - Ticket ticket = ticketService.getById(request.getTicketId()); - int handlerId = Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); - uniPushService.send(new UniPushMessage() - .setSenderId(ticket.getUserPlatform() + "-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); - } else { - AppUser appUser = appUserService.getById(AppUserUtil.getUserId()); - Ticket ticket = ticketService.getById(request.getTicketId()); - uniPushService.send(new UniPushMessage() - .setSenderId(ticket.getUserPlatform() + "-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); +// if (request.getReject()) { +//// if (Objects.isNull(ticketCall)) return ApiResult.success(); +// if (StrUtil.equals(request.getFrom(), Constant.FROM_APP) && Objects.equals(AppUserUtil.getUserId(), request.getFromUserId())) { +// AppUser appUser = appUserService.getById(AppUserUtil.getUserId()); +// Ticket ticket = ticketService.getById(request.getTicketId()); +// int handlerId = Integer.parseInt(StrUtil.split(ticket.getHandle(), ",").stream().findFirst().get()); +// uniPushService.send(new UniPushMessage() +// .setSenderId(ticket.getUserPlatform() + "-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); +// } else { +// AppUser appUser = appUserService.getById(AppUserUtil.getUserId()); +// Ticket ticket = ticketService.getById(request.getTicketId()); +// uniPushService.send(new UniPushMessage() +// .setSenderId(ticket.getUserPlatform() + "-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); +// } +// } +//// if (ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject())) { +// ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId()); +//// } + stringRedisTemplate.opsForSet().remove(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId(), Constant.FROM_ADMIN + "-" + AdminUserUtil.getUserId()); + if (Objects.equals(0L, stringRedisTemplate.opsForSet().size(Constant.REDIS_KEY_TICKET_CALL_WAIT + request.getTicketId()))) { + ShengWangChannelUserListDTO channelUserListDTO = shengWangService.getChannelUsers("ticket" + request.getTicketId()); + if (!channelUserListDTO.isChannelEexist() || channelUserListDTO.getUsers().size() <= 1) { + ssePushService.sendTicketCallEnd(request.getTicketId()); + Integer userId = CollectionUtil.get(channelUserListDTO.getUsers(), 0); + if (Objects.nonNull(userId)) { + String from = userId.toString().startsWith("1") ? "app" : "admin"; + userId = Integer.valueOf(userId.toString().substring(1)); + uniPushService.send(new UniPushMessage() + .setSenderId(from + "-uid-" + userId)//不重要 + .setReceiverId(from + "-uid-" + userId) + .setSendData(new UniPushMessageBody() + .setTitle("视频通话结束") + .setPayload(new UniPushMessageCallPayload() + .setTicketId(request.getTicketId()) + .setUserId(userId) + .setCategory("ticketCallEnd") + .setFrom("app") + ) + ) + ); + } } } -// if (ticketCallJoinService.hangUp(ticketCall.getId(), AppUserUtil.getUserId(), Constant.FROM_APP, request.getReject())) { - ticketEventPublisher.publishTicketCallEndEvent(request.getTicketId()); -// } return ApiResult.success(); } + + /** + * 获取声网频道用户列表 + * @param ticketId 工单ID + * @return 用户列表 + */ + @GetMapping("getShengWangChannelUsers") + public ApiResult> getShengWangChannelUsers(Integer ticketId) throws IOException, InterruptedException { + return ApiResult.success(shengWangService.getChannelUsers("ticket" + ticketId).getUsers()); + } } 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 index b9c203a4..2f0da567 100644 --- 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 @@ -1,20 +1,13 @@ package com.nflg.mobilebroken.cfs.event; -import cn.hutool.core.collection.CollectionUtil; import com.nflg.mobilebroken.cfs.service.ShengWangService; import com.nflg.mobilebroken.cfs.service.SsePushService; -import com.nflg.mobilebroken.common.constant.TicketState; -import com.nflg.mobilebroken.common.pojo.dto.ChatMessageDTO; 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.io.IOException; -import java.time.Instant; -import java.util.concurrent.TimeUnit; - public class TicketCallEndEvent extends ApplicationEvent implements ApplicationContextAware { private final Integer ticketId; @@ -35,21 +28,21 @@ public class TicketCallEndEvent extends ApplicationEvent implements ApplicationC this.shengWangService = applicationContext.getBean(ShengWangService.class); } - public void send() throws IOException, InterruptedException { - TimeUnit.SECONDS.sleep(2); - if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) { - ChatMessageDTO message = new ChatMessageDTO() - .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) - .setFrom("call") - .setTicketState(TicketState.Processing.getState()) - .setSenderId(0) - .setSenderName("通话助手") - .setContent("视频通话已结束") - .setCreateTime(Instant.now()); - ticketChatService.addMessage(ticketId, message); - //推送消息 - ssePushService.sendTicketMessageToAdmin(ticketId, message); - ssePushService.sendTicketMessageToApp(ticketId, message); - } - } +// public void send() throws IOException, InterruptedException { +// TimeUnit.SECONDS.sleep(2); +// if (CollectionUtil.isEmpty(shengWangService.getChannelUsers("ticket-" + ticketId))) { +// ChatMessageDTO message = new ChatMessageDTO() +// .setId(cn.hutool.core.util.IdUtil.getSnowflakeNextIdStr()) +// .setFrom("call") +// .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 155755f2..2582a26f 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 @@ -5,8 +5,6 @@ import org.springframework.context.event.EventListener; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; -import java.io.IOException; - @Component public class TicketEventListener { @@ -46,9 +44,9 @@ public class TicketEventListener { event.send(); } - @Async - @EventListener - public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException { - event.send(); - } +// @Async +// @EventListener +// public void handleTicketCallEndEvent(TicketCallEndEvent event) throws IOException, InterruptedException { +// event.send(); +// } } diff --git a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/ShengWangService.java b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/ShengWangService.java index cdd1ac1d..68abb7ac 100644 --- a/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/ShengWangService.java +++ b/nflg-mobilebroken-cfs-app/src/main/java/com/nflg/mobilebroken/cfs/service/ShengWangService.java @@ -60,6 +60,26 @@ public class ShengWangService { return result.getData(); } + /** + * 查询频道用户列表 + * @param channelName 频道名称 + * @return 用户列表 + */ + public ShengWangChannelUserListDTO getChannelUsers(String channelName) throws IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder() + .GET() + .header("Authorization", generateAuthorization(customerKey, customerSecret)) + .uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName)) + .build(); + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + log.debug("getChannelUsers Response:" + response.body()); + VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败"); + ShengWangResponse result = objectMapper.readValue(response.body(), new TypeReference<>() { + }); + VUtils.trueThrowBusinessError(!result.isSuccess()).throwMessage("查询用户列表失败"); + return result.getData(); + } + /** * 创建规则 * @param channelName 频道名称 @@ -142,18 +162,4 @@ public class ShengWangService { // 创建 authorization header return "Basic " + base64Credentials; } - - public List getChannelUsers(String channelName) throws IOException, InterruptedException { - HttpRequest request = HttpRequest.newBuilder() - .GET() - .header("Authorization", generateAuthorization(customerKey, customerSecret)) - .uri(URI.create(baseUrl + "/v1/channel/user/" + appId + "/" + channelName)) - .build(); - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - log.debug("getChannelUsers Response:" + response.body()); - VUtils.trueThrowBusinessError(response.statusCode() != 200).throwMessage("请求失败"); - ShengWangChannelUserResponseDTO result = objectMapper.readValue(response.body(), ShengWangChannelUserResponseDTO.class); - VUtils.trueThrowBusinessError(!result.getSuccess()).throwMessage("获取频道用户失败"); - return result.getData().isChannel_exist() ? result.getData().getUsers() : null; - } } 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 94347f66..03ea8a48 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 @@ -18,6 +18,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; +import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.time.ZoneId; @@ -244,4 +245,50 @@ public class SsePushService { log.error("发送消息出错", e); } } + + public void sendTicketCallJoined(Integer userId, @Valid @NotNull Integer ticketId, String to) { + try { + PushUserMessageRequest request = new PushUserMessageRequest() + .setUserId(userId) + .setMessage(new PushMessageDTO() + .setType("ticketCallJoined") + .setData(new PushMessageDataBody() + .setTargetId(ticketId) + .setType("ticketCallJoined") + .setData(new UniPushMessageCallPayload() + .setTicketId(ticketId) + .setFrom("app") + ) + ) + ); + ApiResult result = sendMessageByUser(request, to); + log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + } catch (Exception e) { + log.error("发送消息出错", e); + } + } + + public void sendTicketCallEnd(Integer ticketId) { + try { + TicketMessagePushRequest request = new TicketMessagePushRequest() + .setTicketId(ticketId) + .setMessage(new PushMessageDTO() + .setType("ticketCallEnd") + .setData(new PushMessageDataBody() + .setTargetId(ticketId) + .setType("ticketCallEnd") + .setData(new UniPushMessageCallPayload() + .setTicketId(ticketId) + .setFrom("app") + ) + ) + ); + ApiResult result = sendMessage(request, "app"); + log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + result = sendMessage(request, "admin"); + log.debug("发送消息结果:{}", JSONUtil.toJsonStr(result)); + } catch (Exception e) { + log.error("发送消息出错", e); + } + } } \ No newline at end of file diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java index c497e692..c498a803 100644 --- a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/constant/Constant.java @@ -135,4 +135,6 @@ public class Constant { public static final String DICTIONARY_PRODUCT_MODULE = "ProductModule"; public static final String TRACE_ID = "traceId"; + + public static final String REDIS_KEY_TICKET_CALL_WAIT = "ticket:called:wait:"; } diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/ShengWangChannelUserListDTO.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/ShengWangChannelUserListDTO.java new file mode 100644 index 00000000..8ec69fca --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/pojo/dto/ShengWangChannelUserListDTO.java @@ -0,0 +1,26 @@ +package com.nflg.mobilebroken.common.pojo.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class ShengWangChannelUserListDTO { + + /** + * 指定频道是否存在 + */ + @JsonProperty("channel_exist") + private boolean channelEexist; + + /** + * 频道内的总人数 + */ + private Integer total; + + /** + * 频道内所有用户的用户ID + */ + private List users; +} diff --git a/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ShengWangUtil.java b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ShengWangUtil.java new file mode 100644 index 00000000..cb1edef5 --- /dev/null +++ b/nflg-mobilebroken-common/src/main/java/com/nflg/mobilebroken/common/util/ShengWangUtil.java @@ -0,0 +1,18 @@ +package com.nflg.mobilebroken.common.util; + +import cn.hutool.core.util.StrUtil; +import com.nflg.mobilebroken.common.constant.Constant; + +public class ShengWangUtil { + + public static Integer getUserId(Integer userId, String from) { + switch (from) { + case Constant.FROM_APP: + return Integer.valueOf("1" + StrUtil.padPre(String.valueOf(userId), 9, '0')); + case Constant.FROM_ADMIN: + return Integer.valueOf("2" + StrUtil.padPre(String.valueOf(userId), 9, '0')); + default: + return null; + } + } +}