From cfe970bd45eef8c14f247be4412706c723793bf7 Mon Sep 17 00:00:00 2001 From: huangdeliang Date: Wed, 2 Jun 2021 14:06:21 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=BC=80=E5=8F=91ws=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/WebSocketController.java | 54 ++++++++ .../stdiet/web/server/WebSocketServer.java | 122 ++++++++++++++++++ .../java/com/stdiet/custom/utils/WsUtils.java | 8 ++ stdiet-framework/pom.xml | 17 +++ .../framework/config/SecurityConfig.java | 1 + .../framework/config/WebsocketConfig.java | 18 +++ stdiet-ui/src/main.js | 15 ++- stdiet-ui/src/utils/websocket.js | 57 ++++++++ 8 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java create mode 100644 stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java create mode 100644 stdiet-framework/src/main/java/com/stdiet/framework/config/WebsocketConfig.java create mode 100644 stdiet-ui/src/utils/websocket.js diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java new file mode 100644 index 000000000..128b8d067 --- /dev/null +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java @@ -0,0 +1,54 @@ +package com.stdiet.web.controller.custom; + +import com.alibaba.fastjson.JSONObject; +import com.stdiet.common.core.controller.BaseController; +import com.stdiet.custom.utils.WsUtils; +import com.stdiet.web.server.WebSocketServer; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +@Controller +@EnableScheduling +@RequestMapping("/ws/api") +public class WebSocketController extends BaseController { + + @ResponseBody + @RequestMapping("/push/{cid}") + public Map pushToWeb(@PathVariable String cid, String message) { + if (message == null) { + message = "我是消息44"; + } + Map result = new HashMap(); + try { + WebSocketServer.sendInfo(message, cid); + result.put("code", 200); + result.put("msg", "success"); + } catch (IOException e) { + e.printStackTrace(); + } + return result; + + } + + @Scheduled(fixedRate = 30000) + public void boardCast() { + try { + JSONObject heartBeat = new JSONObject(); + heartBeat.put("type", WsUtils.WS_TYPE_HEART_BEAT); + heartBeat.put("msg", "ping"); + + WebSocketServer.sendInfo(heartBeat.toJSONString(), null); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java b/stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java new file mode 100644 index 000000000..8dfbb8deb --- /dev/null +++ b/stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java @@ -0,0 +1,122 @@ +package com.stdiet.web.server; + +import com.alibaba.fastjson.JSONObject; +import com.stdiet.common.core.domain.model.LoginUser; +import com.stdiet.custom.utils.WsUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.concurrent.CopyOnWriteArraySet; + +@ServerEndpoint(value = "/ws") +@Component +@Slf4j +public class WebSocketServer { + + // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 + private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); + //private static ConcurrentHashMap websocketList = new ConcurrentHashMap<>(); + // 与某个客户端的连接会话,需要通过它来给客户端发送数据 + private Session session; + // 接收sid + private String sid = ""; + + public static CopyOnWriteArraySet getWebSocketSet() { + return webSocketSet; + } + + /** + * 群发自定义消息 + */ + public static void sendInfo(String message, String sid) throws IOException { + log.info("推送消息到窗口" + sid + ",推送内容:" + message + "目标:" + webSocketSet.size()); + for (WebSocketServer item : webSocketSet) { + try { + // 这里可以设定只推送给这个sid的,为null则全部推送 + if (sid == null) { + item.sendMessage(message); + } else if (item.sid.equals(sid)) { + item.sendMessage(message); + } + } catch (IOException e) { + // 清理断开的连接 + webSocketSet.remove(item); + continue; + } + } + } + + // * 连接建立成功调用的方法* + @OnOpen + public void onOpen(Session session) { + this.session = session; + this.sid = String.valueOf(getUserId(session)); + + webSocketSet.add(this); // 加入set中 + + try { + JSONObject object = new JSONObject(); + object.put("type", WsUtils.WS_TYPE_SYSTEM_MESSAGE); + object.put("msg", "连接成功"); + sendMessage(object.toJSONString()); + } catch (IOException e) { + log.error("websocket IO异常"); + } + } + + @OnClose + public void onClose() { + webSocketSet.remove(this); // 从set中删除 + log.info("有一连接关闭!"); + } + + // */ + /// ** + // * 收到客户端消息后调用的方法 + // * + // * @param message 客户端发送过来的消息*//* + @OnMessage + public void onMessage(String message, Session session) { + log.info("收到来自窗口" + sid + "的信息:" + message); +// // 群发消息 +// for (WebSocketServer item : webSocketSet) { +// try { +// item.sendMessage(message); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } + } + + /** + * @param session + * @param error + */ + @OnError + public void onError(Session session, Throwable error) { + log.error("发生错误"); + error.printStackTrace(); + } + + /** + * 实现服务器主动推送 + */ + public void sendMessage(String message) throws IOException { + log.info("服务器消息推送:" + message); + this.session.getBasicRemote().sendText(message); + } + + public Long getUserId(Session session) { + try { + return ((LoginUser) ((UsernamePasswordAuthenticationToken) session.getUserPrincipal()).getPrincipal()).getUser().getUserId(); + } catch (Exception e) { + return 0L; + } + } + + +} \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java new file mode 100644 index 000000000..6d8e8f43c --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java @@ -0,0 +1,8 @@ +package com.stdiet.custom.utils; + +public class WsUtils { + + public static final String WS_TYPE_HEART_BEAT = "WS_TYPE_HEART_BEAT"; + + public static final String WS_TYPE_SYSTEM_MESSAGE = "WS_TYPE_SYSTEM_MESSAGE"; +} diff --git a/stdiet-framework/pom.xml b/stdiet-framework/pom.xml index 6db2e7872..c94845c5d 100644 --- a/stdiet-framework/pom.xml +++ b/stdiet-framework/pom.xml @@ -59,6 +59,23 @@ stdiet-system + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + org.springframework.boot + spring-boot-configuration-processor + true + + \ No newline at end of file diff --git a/stdiet-framework/src/main/java/com/stdiet/framework/config/SecurityConfig.java b/stdiet-framework/src/main/java/com/stdiet/framework/config/SecurityConfig.java index af34f5aa1..07f5dc900 100644 --- a/stdiet-framework/src/main/java/com/stdiet/framework/config/SecurityConfig.java +++ b/stdiet-framework/src/main/java/com/stdiet/framework/config/SecurityConfig.java @@ -102,6 +102,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/custom/wxUserInfo/wx/**", "/custom/wxUserLog/wx/**", "/wx/**", +// "/ws/**", "/wap/**", "/investigate/**", "/common/customerUploadFile", diff --git a/stdiet-framework/src/main/java/com/stdiet/framework/config/WebsocketConfig.java b/stdiet-framework/src/main/java/com/stdiet/framework/config/WebsocketConfig.java new file mode 100644 index 000000000..795c5a971 --- /dev/null +++ b/stdiet-framework/src/main/java/com/stdiet/framework/config/WebsocketConfig.java @@ -0,0 +1,18 @@ +package com.stdiet.framework.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +@Configuration +@ConditionalOnWebApplication +public class WebsocketConfig { + + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + + +} diff --git a/stdiet-ui/src/main.js b/stdiet-ui/src/main.js index 28ac40c5a..79469f5f8 100644 --- a/stdiet-ui/src/main.js +++ b/stdiet-ui/src/main.js @@ -18,12 +18,15 @@ import "./permission"; // permission control import { getDicts } from "@/api/system/dict/data"; import { getConfigKey } from "@/api/system/config"; import VueScrollTo from "vue-scrollto"; -import VueResource from "vue-resource" -import HighchartsVue from 'highcharts-vue' -import Highcharts from 'highcharts' +import VueResource from "vue-resource"; +import HighchartsVue from "highcharts-vue"; +import Highcharts from "highcharts"; +import { init } from "@/utils/websocket"; //图片导出模块 -import exportingInit from 'highcharts/modules/exporting' -exportingInit(Highcharts) +import exportingInit from "highcharts/modules/exporting"; +exportingInit(Highcharts); + +init(); import { addDateRange, @@ -111,7 +114,7 @@ Vue.use(VueScrollTo, { y: true }); -Vue.use(VueResource) +Vue.use(VueResource); new Vue({ el: "#app", diff --git a/stdiet-ui/src/utils/websocket.js b/stdiet-ui/src/utils/websocket.js new file mode 100644 index 000000000..1098bc150 --- /dev/null +++ b/stdiet-ui/src/utils/websocket.js @@ -0,0 +1,57 @@ +import { getToken } from "./auth"; + +const { protocol, hostname, origin, port } = window.location; +const wsProtocol = protocol.startsWith("https") ? "wss" : "ws"; +const url = `${wsProtocol}://${hostname}${ + port === "80" || port === "443" ? "" : `:${8091}` +}/ws`; +let ws = undefined; +let intervalRef = undefined; + +function handleOnMessageReceive(event) { + console.log({ event }); +} + +function connect() { + try { + ws = new WebSocket(url); + + ws.onopen = event => { + console.log("ws连接成功"); + intervalRef && clearInterval(intervalRef); + + document.addEventListener("message", handleOnMessageReceive); + }; + + ws.onmessage = event => { + console.log({ event }); + + const dataObj = JSON.parse(event.data || "{}"); + + if (dataObj.type && dataObj.type !== "WS_TYPE_HEART_BEAT") { + window.postMessage(dataObj, origin); + } + }; + + ws.onerror = event => { + console.log({ event }); + ws = undefined; + document.removeEventListener("message", handleOnMessageReceive); + }; + + ws.onclose = event => { + ws = undefined; + document.removeEventListener("message", handleOnMessageReceive); + }; + } catch (error) { + console.log(error); + console.log("浏览器不支持websocket"); + } +} + +export function init() { + intervalRef = setInterval(() => { + console.log("尝试连接websocket"); + !ws && connect(); + }, 10000); +} From a4252af6ed90b91a8531c49cf22be3830a0c5ed9 Mon Sep 17 00:00:00 2001 From: huangdeliang Date: Wed, 2 Jun 2021 14:11:15 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dws?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stdiet-ui/src/utils/websocket.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/stdiet-ui/src/utils/websocket.js b/stdiet-ui/src/utils/websocket.js index 1098bc150..93ef5146a 100644 --- a/stdiet-ui/src/utils/websocket.js +++ b/stdiet-ui/src/utils/websocket.js @@ -1,9 +1,7 @@ -import { getToken } from "./auth"; - const { protocol, hostname, origin, port } = window.location; const wsProtocol = protocol.startsWith("https") ? "wss" : "ws"; const url = `${wsProtocol}://${hostname}${ - port === "80" || port === "443" ? "" : `:${8091}` + hostname === "localhost" ? `:${8091}` : "" }/ws`; let ws = undefined; let intervalRef = undefined; From 953d188f5004945b3ceb5bc282501cdb167f824d Mon Sep 17 00:00:00 2001 From: huangdeliang Date: Wed, 2 Jun 2021 14:13:03 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stdiet-ui/src/utils/websocket.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdiet-ui/src/utils/websocket.js b/stdiet-ui/src/utils/websocket.js index 93ef5146a..94a85698b 100644 --- a/stdiet-ui/src/utils/websocket.js +++ b/stdiet-ui/src/utils/websocket.js @@ -1,7 +1,7 @@ const { protocol, hostname, origin, port } = window.location; const wsProtocol = protocol.startsWith("https") ? "wss" : "ws"; const url = `${wsProtocol}://${hostname}${ - hostname === "localhost" ? `:${8091}` : "" + hostname === "localhost" ? ":8091" : "" }/ws`; let ws = undefined; let intervalRef = undefined; From ea8276e6a0d72c8ad21cc161c11bce659992372e Mon Sep 17 00:00:00 2001 From: huangdeliang Date: Thu, 3 Jun 2021 10:36:21 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/WebSocketController.java | 27 ++-- stdiet-custom/pom.xml | 5 + .../custom/domain/SysServicesTopic.java | 2 + .../custom/mapper/SysServicesTopicMapper.java | 2 + .../custom}/server/WebSocketServer.java | 59 ++++++--- .../service/ISysServicesTopicService.java | 2 + .../impl/SysServicesTopicServiceImp.java | 79 +++++++++++- .../java/com/stdiet/custom/utils/WsUtils.java | 8 ++ .../mapper/custom/SysServicesTopicMapper.xml | 18 +++ stdiet-ui/src/layout/components/Navbar.vue | 49 ++++--- stdiet-ui/src/main.js | 1 + stdiet-ui/src/store/actions.js | 3 + stdiet-ui/src/store/getters.js | 3 +- stdiet-ui/src/store/modules/global.js | 3 +- stdiet-ui/src/store/modules/message.js | 37 ++++-- stdiet-ui/src/utils/websocket.js | 41 ++++-- .../custom/message/messageBrowser/index.vue | 122 ++++++++++++++---- 17 files changed, 348 insertions(+), 113 deletions(-) rename {stdiet-admin/src/main/java/com/stdiet/web => stdiet-custom/src/main/java/com/stdiet/custom}/server/WebSocketServer.java (70%) diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java index 128b8d067..4ae0335ec 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/WebSocketController.java @@ -3,11 +3,10 @@ package com.stdiet.web.controller.custom; import com.alibaba.fastjson.JSONObject; import com.stdiet.common.core.controller.BaseController; import com.stdiet.custom.utils.WsUtils; -import com.stdiet.web.server.WebSocketServer; +import com.stdiet.custom.server.WebSocketServer; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -39,16 +38,16 @@ public class WebSocketController extends BaseController { } - @Scheduled(fixedRate = 30000) - public void boardCast() { - try { - JSONObject heartBeat = new JSONObject(); - heartBeat.put("type", WsUtils.WS_TYPE_HEART_BEAT); - heartBeat.put("msg", "ping"); - - WebSocketServer.sendInfo(heartBeat.toJSONString(), null); - } catch (IOException e) { - e.printStackTrace(); - } - } +// @Scheduled(fixedRate = 30000) +// public void boardCast() { +// try { +// JSONObject heartBeat = new JSONObject(); +// heartBeat.put("type", WsUtils.WS_TYPE_HEART_BEAT); +// heartBeat.put("msg", "ping"); +// +// WebSocketServer.sendInfo(heartBeat.toJSONString(), null); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } } diff --git a/stdiet-custom/pom.xml b/stdiet-custom/pom.xml index 5db28a2cc..a7e81b668 100644 --- a/stdiet-custom/pom.xml +++ b/stdiet-custom/pom.xml @@ -99,6 +99,11 @@ ikanalyzer 2012_u6 + + org.apache.tomcat.embed + tomcat-embed-websocket + + \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysServicesTopic.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysServicesTopic.java index f465d7522..3ce77b0bd 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysServicesTopic.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysServicesTopic.java @@ -89,4 +89,6 @@ public class SysServicesTopic { List replys; + Integer count; + } diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysServicesTopicMapper.java b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysServicesTopicMapper.java index 333417f81..0217a94e8 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysServicesTopicMapper.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysServicesTopicMapper.java @@ -18,4 +18,6 @@ public interface SysServicesTopicMapper { int inserSysServicesTopicReply(SysServicesTopic topic); List selectSysServicesTopicSessionByTopicId(String topicId); + + List selectUnreadTopicCount(List topics); } diff --git a/stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java b/stdiet-custom/src/main/java/com/stdiet/custom/server/WebSocketServer.java similarity index 70% rename from stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java rename to stdiet-custom/src/main/java/com/stdiet/custom/server/WebSocketServer.java index 8dfbb8deb..7bc506c04 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/server/WebSocketServer.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/server/WebSocketServer.java @@ -1,7 +1,10 @@ -package com.stdiet.web.server; +package com.stdiet.custom.server; import com.alibaba.fastjson.JSONObject; import com.stdiet.common.core.domain.model.LoginUser; +import com.stdiet.common.utils.spring.SpringUtils; +import com.stdiet.custom.domain.SysServicesTopic; +import com.stdiet.custom.service.ISysServicesTopicService; import com.stdiet.custom.utils.WsUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -10,15 +13,17 @@ import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.CopyOnWriteArraySet; @ServerEndpoint(value = "/ws") @Component @Slf4j public class WebSocketServer { - // concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); + //private static ConcurrentHashMap websocketList = new ConcurrentHashMap<>(); // 与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; @@ -74,23 +79,6 @@ public class WebSocketServer { log.info("有一连接关闭!"); } - // */ - /// ** - // * 收到客户端消息后调用的方法 - // * - // * @param message 客户端发送过来的消息*//* - @OnMessage - public void onMessage(String message, Session session) { - log.info("收到来自窗口" + sid + "的信息:" + message); -// // 群发消息 -// for (WebSocketServer item : webSocketSet) { -// try { -// item.sendMessage(message); -// } catch (IOException e) { -// e.printStackTrace(); -// } -// } - } /** * @param session @@ -118,5 +106,38 @@ public class WebSocketServer { } } + @OnMessage + public void onMessage(String message, Session session) { + log.info("收到来自窗口" + sid + "的信息:" + message); + try { + String sid = String.valueOf(getUserId(session)); + if (sid.equals("0")) { + return; + } + JSONObject resultObj = new JSONObject(); + if (message.equals(WsUtils.WS_GET_UNREAD_COUNT)) { + SysServicesTopic topic = new SysServicesTopic(); + topic.setUid(sid); + List statusList = new ArrayList<>(); + statusList.add(topic); + ISysServicesTopicService servicesTopicService = SpringUtils.getBean(ISysServicesTopicService.class); + List result = servicesTopicService.selectUnreadTopicCount(statusList); + + JSONObject dataObj = new JSONObject(); + dataObj.put("count", result.get(0).getCount()); + + resultObj.put("type", WsUtils.WS_TYPE_MESSAGE_COUNT); + resultObj.put("msg", "未读消息数"); + resultObj.put("data", dataObj); + + } else if (message.equals(WsUtils.WS_PING)) { + + } + WebSocketServer.sendInfo(resultObj.toJSONString(), sid); + } catch (IOException e) { + e.printStackTrace(); + } + } + } \ No newline at end of file diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysServicesTopicService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysServicesTopicService.java index 1b9b14291..054424584 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysServicesTopicService.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysServicesTopicService.java @@ -17,4 +17,6 @@ public interface ISysServicesTopicService { SysServicesTopic inserSysServicesTopicComment(SysServicesTopic topic); List selectSysServicesTopicSessionByTopicId(String topicId); + + List selectUnreadTopicCount(List topic); } diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysServicesTopicServiceImp.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysServicesTopicServiceImp.java index dcecfdd49..941518c5b 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysServicesTopicServiceImp.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysServicesTopicServiceImp.java @@ -1,15 +1,19 @@ package com.stdiet.custom.service.impl; +import com.alibaba.fastjson.JSONObject; import com.stdiet.common.utils.DateUtils; import com.stdiet.common.utils.uuid.UUID; import com.stdiet.custom.domain.SysCustomer; import com.stdiet.custom.domain.SysServicesTopic; import com.stdiet.custom.mapper.SysCustomerMapper; import com.stdiet.custom.mapper.SysServicesTopicMapper; +import com.stdiet.custom.server.WebSocketServer; import com.stdiet.custom.service.ISysServicesTopicService; +import com.stdiet.custom.utils.WsUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -40,35 +44,58 @@ public class SysServicesTopicServiceImp implements ISysServicesTopicService { List statusList = new ArrayList<>(); + String customerId = String.valueOf(customer.getId()); SysServicesTopic customerStatus = new SysServicesTopic(); - customerStatus.setUid(String.valueOf(customer.getId())); + customerStatus.setUid(customerId); customerStatus.setRole("customer"); customerStatus.setRead(1); customerStatus.setTopicId(topic.getTopicId()); statusList.add(customerStatus); + String dieticianId = String.valueOf(customer.getMainDietitian()); SysServicesTopic dieticianStatus = new SysServicesTopic(); - dieticianStatus.setUid(String.valueOf(customer.getMainDietitian())); + dieticianStatus.setUid(dieticianId); dieticianStatus.setRole("dietician"); dieticianStatus.setRead(0); dieticianStatus.setTopicId(topic.getTopicId()); statusList.add(dieticianStatus); + String afterSaleId = String.valueOf(customer.getAfterDietitian()); SysServicesTopic afterSaleStatus = new SysServicesTopic(); - afterSaleStatus.setUid(String.valueOf(customer.getAfterDietitian())); + afterSaleStatus.setUid(afterSaleId); afterSaleStatus.setRole("after_sale"); afterSaleStatus.setRead(0); afterSaleStatus.setTopicId(topic.getTopicId()); statusList.add(afterSaleStatus); + String dieticianAssistantId = String.valueOf(customer.getAssistantDietitian()); SysServicesTopic dieticianAssistantStatus = new SysServicesTopic(); - dieticianAssistantStatus.setUid(String.valueOf(customer.getAssistantDietitian())); + dieticianAssistantStatus.setUid(dieticianAssistantId); dieticianAssistantStatus.setRole("dietician_assistant"); dieticianAssistantStatus.setRead(0); dieticianAssistantStatus.setTopicId(topic.getTopicId()); statusList.add(dieticianAssistantStatus); - servicesTopicMapper.insertSysServicesTopicStatus(statusList); + int rows = servicesTopicMapper.insertSysServicesTopicStatus(statusList); + if (rows > 0) { + try { + List counts = servicesTopicMapper.selectUnreadTopicCount(statusList); + for (int i = 0; i < counts.size(); i++) { + topic.setId(statusList.get(i).getId()); + JSONObject dataObj = new JSONObject(); + dataObj.put("count", counts.get(i).getCount()); + dataObj.put("data", topic); + + JSONObject msgObj = new JSONObject(); + msgObj.put("type", WsUtils.WS_TYPE_MESSAGE_COUNT); + msgObj.put("msg", "未读消息数"); + msgObj.put("data", dataObj); + WebSocketServer.sendInfo(msgObj.toJSONString(), counts.get(i).getUid()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } topic.setId(customerStatus.getId()); topic.setUid(null); @@ -94,10 +121,13 @@ public class SysServicesTopicServiceImp implements ISysServicesTopicService { status.setTopicId(topic.getTopicId()); status.setRole(topic.getRole()); servicesTopicMapper.updateSysServicesTopicStatus(status); + + afterReply(topic); } return topic; } + @Override public SysServicesTopic inserSysServicesTopicComment(SysServicesTopic topic) { String uuid = java.util.UUID.randomUUID().toString().replace("-", ""); @@ -110,12 +140,51 @@ public class SysServicesTopicServiceImp implements ISysServicesTopicService { status.setTopicId(topic.getTopicId()); status.setRole(topic.getRole()); servicesTopicMapper.updateSysServicesTopicStatus(status); + + afterReply(topic); } return topic; } + public void afterReply(SysServicesTopic topic) { + SysCustomer customer = sysCustomerMapper.selectSysCustomerById(Long.parseLong(topic.getFromUid())); + + List statusList = new ArrayList<>(); + SysServicesTopic dieticianStatus = new SysServicesTopic(); + dieticianStatus.setUid(String.valueOf(customer.getMainDietitian())); + statusList.add(dieticianStatus); + SysServicesTopic afterSaleStatus = new SysServicesTopic(); + afterSaleStatus.setUid(String.valueOf(customer.getAfterDietitian())); + statusList.add(afterSaleStatus); + SysServicesTopic dieticianAssistantStatus = new SysServicesTopic(); + dieticianAssistantStatus.setUid(String.valueOf(customer.getAssistantDietitian())); + statusList.add(dieticianAssistantStatus); + + try { + List counts = servicesTopicMapper.selectUnreadTopicCount(statusList); + for (int i = 0; i < counts.size(); i++) { + JSONObject dataObj = new JSONObject(); + dataObj.put("count", counts.get(i).getCount()); + dataObj.put("topicId", topic.getTopicId()); + + JSONObject msgObj = new JSONObject(); + msgObj.put("type", WsUtils.WS_TYPE_NEW_CUSTOMER_REPLY); + msgObj.put("msg", "新客户回复"); + msgObj.put("data", dataObj); + WebSocketServer.sendInfo(msgObj.toJSONString(), counts.get(i).getUid()); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override public List selectSysServicesTopicSessionByTopicId(String topicId) { return servicesTopicMapper.selectSysServicesTopicSessionByTopicId(topicId); } + + @Override + public List selectUnreadTopicCount(List statusList) { + return servicesTopicMapper.selectUnreadTopicCount(statusList); + } } diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java index 6d8e8f43c..a1b2286bf 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WsUtils.java @@ -5,4 +5,12 @@ public class WsUtils { public static final String WS_TYPE_HEART_BEAT = "WS_TYPE_HEART_BEAT"; public static final String WS_TYPE_SYSTEM_MESSAGE = "WS_TYPE_SYSTEM_MESSAGE"; + + public static final String WS_TYPE_MESSAGE_COUNT = "WS_TYPE_MESSAGE_COUNT"; + + public static final String WS_TYPE_NEW_CUSTOMER_REPLY = "WS_TYPE_NEW_CUSTOMER_REPLY"; + + public static final String WS_GET_UNREAD_COUNT = "GET_UNREAD_COUNT"; + + public static final String WS_PING = "ping"; } diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysServicesTopicMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysServicesTopicMapper.xml index 688494714..a1dc84685 100644 --- a/stdiet-custom/src/main/resources/mapper/custom/SysServicesTopicMapper.xml +++ b/stdiet-custom/src/main/resources/mapper/custom/SysServicesTopicMapper.xml @@ -225,5 +225,23 @@ + + + + + \ No newline at end of file diff --git a/stdiet-ui/src/layout/components/Navbar.vue b/stdiet-ui/src/layout/components/Navbar.vue index af5333114..cb6a5d8b8 100644 --- a/stdiet-ui/src/layout/components/Navbar.vue +++ b/stdiet-ui/src/layout/components/Navbar.vue @@ -11,26 +11,11 @@