diff --git a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtNotificationMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtNotificationMapper.xml index 027cc9e61f..9b319a28f4 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ext/ExtNotificationMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ext/ExtNotificationMapper.xml @@ -10,7 +10,7 @@ diff --git a/backend/src/main/java/io/metersphere/notice/service/NoticeService.java b/backend/src/main/java/io/metersphere/notice/service/NoticeService.java index 6bfe911955..d19412d64b 100644 --- a/backend/src/main/java/io/metersphere/notice/service/NoticeService.java +++ b/backend/src/main/java/io/metersphere/notice/service/NoticeService.java @@ -17,7 +17,6 @@ import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.StatusReference; import io.metersphere.log.vo.system.SystemReference; import io.metersphere.notice.domain.MessageDetail; -import io.metersphere.service.ProjectService; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/io/metersphere/notice/service/NotificationService.java b/backend/src/main/java/io/metersphere/notice/service/NotificationService.java index 9e82da315c..d6a020a966 100644 --- a/backend/src/main/java/io/metersphere/notice/service/NotificationService.java +++ b/backend/src/main/java/io/metersphere/notice/service/NotificationService.java @@ -48,7 +48,10 @@ public class NotificationService { } public int countNotification(Notification notification) { - notification.setReceiver(SessionUtils.getUser().getId()); + if (StringUtils.isBlank(notification.getReceiver())) { + notification.setReceiver(SessionUtils.getUser().getId()); + } + notification.setStatus(NotificationConstants.Status.UNREAD.name()); return extNotificationMapper.countNotification(notification); } @@ -65,7 +68,13 @@ public class NotificationService { if (StringUtils.isNotBlank(notification.getTitle())) { search = "%" + notification.getTitle() + "%"; } - return extNotificationMapper.listNotification(search, SessionUtils.getUser().getId()); + String receiver; + if (StringUtils.isBlank(notification.getReceiver())) { + receiver = SessionUtils.getUser().getId(); + } else { + receiver = notification.getReceiver(); + } + return extNotificationMapper.listNotification(search, receiver); } public List listReadNotification(Notification notification) { diff --git a/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java b/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java new file mode 100644 index 0000000000..a69b04495d --- /dev/null +++ b/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java @@ -0,0 +1,107 @@ +package io.metersphere.websocket; + +import io.metersphere.base.domain.Notification; +import io.metersphere.commons.constants.NotificationConstants; +import io.metersphere.commons.utils.LogUtil; +import io.metersphere.notice.service.NotificationService; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; + +@ServerEndpoint("/notification/count/{userId}") +@Component +public class NotificationWebSocket { + private static NotificationService notificationService; + private static ConcurrentHashMap refreshTasks = new ConcurrentHashMap<>(); + + @Resource + public void setNotificationService(NotificationService notificationService) { + NotificationWebSocket.notificationService = notificationService; + } + + /** + * 开启连接的操作 + */ + @OnOpen + public void onOpen(@PathParam("userId") String userId, Session session) { + Timer timer = new Timer(true); + NotificationCenter task = new NotificationCenter(session, userId); + timer.schedule(task, 0, 10 * 1000); + refreshTasks.putIfAbsent(session, timer); + } + + /** + * 连接关闭的操作 + */ + @OnClose + public void onClose(Session session) { + Timer timer = refreshTasks.get(session); + if (timer != null) { + timer.cancel(); + refreshTasks.remove(session); + } + } + + /** + * 推送消息 + */ + @OnMessage + public void onMessage(@PathParam("userId") String userId, Session session, String message) { + int refreshTime = 10; + try { + refreshTime = Integer.parseInt(message); + } catch (Exception e) { + } + try { + Timer timer = refreshTasks.get(session); + timer.cancel(); + + Timer newTimer = new Timer(true); + newTimer.schedule(new NotificationCenter(session, userId), 0, refreshTime * 1000L); + refreshTasks.put(session, newTimer); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + } + } + + /** + * 出错的操作 + */ + @OnError + public void onError(Throwable error) { + System.out.println(error); + error.printStackTrace(); + } + + public static class NotificationCenter extends TimerTask { + private Session session; + private String userId; + + NotificationCenter(Session session, String userId) { + this.session = session; + this.userId = userId; + } + + @Override + public void run() { + try { + if (!session.isOpen()) { + return; + } + Notification notification = new Notification(); + notification.setReceiver(userId); + notification.setStatus(NotificationConstants.Status.UNREAD.name()); + int count = notificationService.countNotification(notification); + session.getBasicRemote().sendText(count + ""); + } catch (Exception e) { + LogUtil.error(e.getMessage(), e); + } + } + } +} diff --git a/frontend/src/business/App.vue b/frontend/src/business/App.vue index 92d844e403..94c14f3441 100644 --- a/frontend/src/business/App.vue +++ b/frontend/src/business/App.vue @@ -17,7 +17,7 @@ - + @@ -37,7 +37,7 @@ import {hasLicense, saveLocalStorage, setColor, setDefaultTheme} from "@/common/ import {registerRequestHeaders} from "@/common/js/ajax"; import {ORIGIN_COLOR} from "@/common/js/constants"; import MsTaskCenter from "@/business/components/task/TaskCenter"; -import MsNoticeCenter from "@/business/components/notice/NoticeCenter"; +import MsNotification from "@/business/components/notice/Notification"; const requireComponent = require.context('@/business/components/xpack/', true, /\.vue$/); const header = requireComponent.keys().length > 0 ? requireComponent("./license/LicenseMessage.vue") : {}; const display = requireComponent.keys().length > 0 ? requireComponent("./display/Display.vue") : {}; @@ -183,7 +183,7 @@ export default { } }, components: { - MsNoticeCenter, + MsNotification, MsTaskCenter, MsLanguageSwitch, MsUser, diff --git a/frontend/src/business/components/notice/NoticeCenter.vue b/frontend/src/business/components/notice/NoticeCenter.vue deleted file mode 100644 index afe47ad3f5..0000000000 --- a/frontend/src/business/components/notice/NoticeCenter.vue +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - diff --git a/frontend/src/business/components/notice/Notification.vue b/frontend/src/business/components/notice/Notification.vue new file mode 100644 index 0000000000..eea63f19ca --- /dev/null +++ b/frontend/src/business/components/notice/Notification.vue @@ -0,0 +1,314 @@ + + + + + + +