From f2f01f7043fc68ee986f3ae72e13f84c2cb39641 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com>
Date: Wed, 16 Nov 2022 22:09:16 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96:=20?=
=?UTF-8?q?=E5=AE=8C=E6=88=90websocket?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/application/websocketConfig.py | 25 +++++---
.../dvadmin/system/views/message_center.py | 60 ++++++++++++-------
web/package.json | 2 +-
web/src/api/websocket.js | 19 ++++--
.../components/header-message/index.vue | 27 +++++++--
.../modules/d2admin/modules/messagecenter.js | 35 +++++++++++
6 files changed, 127 insertions(+), 41 deletions(-)
create mode 100644 web/src/store/modules/d2admin/modules/messagecenter.js
diff --git a/backend/application/websocketConfig.py b/backend/application/websocketConfig.py
index 1c811b2..a4be5c5 100644
--- a/backend/application/websocketConfig.py
+++ b/backend/application/websocketConfig.py
@@ -10,12 +10,12 @@ from channels.layers import get_channel_layer
from jwt import InvalidSignatureError
from application import settings
-from dvadmin.system.models import MessageCenter
+from dvadmin.system.models import MessageCenter, MessageCenterTargetUser
send_dict = {}
# 发送消息结构体
-def message(sender, msg_type, msg):
+def set_message(sender, msg_type, msg):
text = {
'sender': sender,
'contentType': msg_type,
@@ -32,6 +32,11 @@ def _get_message_center_instance(message_id):
else:
return []
+@database_sync_to_async
+def _get_message_unread(user_id):
+ count = MessageCenterTargetUser.objects.filter(users=user_id,is_read=False).count()
+ return count or 0
+
def request_data(scope):
query_string = scope.get('query_string', b'').decode('utf-8')
@@ -53,7 +58,11 @@ class DvadminWebSocket(AsyncJsonWebsocketConsumer):
self.channel_name
)
await self.accept()
- await self.send_json(message('system', 'SYSTEM', '连接成功'))
+ # 发送连接成功
+ await self.send_json(set_message('system', 'SYSTEM', '连接成功'))
+ # 主动推送消息
+ unread_count = await _get_message_unread(self.user_id)
+ await self.send_json(set_message('system', 'TEXT', {"model":'message_center',"unread":unread_count}))
except InvalidSignatureError:
await self.disconnect(None)
@@ -78,23 +87,25 @@ class MegCenter(DvadminWebSocket):
for send_user in user_list:
await self.channel_layer.group_send(
"user_" + str(send_user),
- {'type': 'push.message', 'message': text_data_json}
+ {'type': 'push.message', 'json': text_data_json}
)
async def push_message(self, event):
- message = event['message']
+ message = event['json']
await self.send(text_data=json.dumps(message))
-def push(username, event):
+def websocket_push(user_id, message):
"""
主动推送消息
"""
+ username = "user_"+str(user_id)
+ print(103,message)
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
username,
{
"type": "push.message",
- "event": event
+ "json": message
}
)
\ No newline at end of file
diff --git a/backend/dvadmin/system/views/message_center.py b/backend/dvadmin/system/views/message_center.py
index bbda1f9..7475814 100644
--- a/backend/dvadmin/system/views/message_center.py
+++ b/backend/dvadmin/system/views/message_center.py
@@ -5,6 +5,7 @@ from rest_framework import serializers
from rest_framework.decorators import action, permission_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
+from application.websocketConfig import websocket_push
from dvadmin.system.models import MessageCenter, Users, MessageCenterTargetUser
from dvadmin.system.views.dept import DeptSerializer
from dvadmin.system.views.role import RoleSerializer
@@ -21,9 +22,10 @@ class MessageCenterSerializer(CustomModelSerializer):
role_info = DynamicSerializerMethodField()
user_info = DynamicSerializerMethodField()
dept_info = DynamicSerializerMethodField()
- is_read = serializers.BooleanField(read_only=True,source='target_user__is_read')
+ is_read = serializers.BooleanField(read_only=True, source='target_user__is_read')
+
def get_role_info(self, instance, parsed_query):
- roles =instance.target_role.all()
+ roles = instance.target_role.all()
# You can do what ever you want in here
# `parsed_query` param is passed to BookSerializer to allow further querying
serializer = RoleSerializer(
@@ -54,6 +56,7 @@ class MessageCenterSerializer(CustomModelSerializer):
parsed_query=parsed_query
)
return serializer.data
+
class Meta:
model = MessageCenter
fields = "__all__"
@@ -64,15 +67,18 @@ class MessageCenterTargetUserSerializer(CustomModelSerializer):
"""
目标用户序列化器-序列化器
"""
+
class Meta:
model = MessageCenterTargetUser
fields = "__all__"
read_only_fields = ["id"]
+
class MessageCenterTargetUserListSerializer(CustomModelSerializer):
"""
目标用户序列化器-序列化器
"""
+
class Meta:
model = MessageCenterTargetUser
fields = "__all__"
@@ -97,22 +103,28 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
initial_data = self.initial_data
target_type = initial_data.get('target_type')
# 在保存之前,根据目标类型,把目标用户查询出来并保存
- users = initial_data.get('target_user',[])
- if target_type in [1]: #按角色
+ users = initial_data.get('target_user', [])
+ if target_type in [1]: # 按角色
target_role = initial_data.get('target_role')
- users = Users.objects.exclude(is_deleted=True).filter(role__id__in=target_role).values_list('id',flat=True)
- if target_type in [2]: #按部门
+ users = Users.objects.exclude(is_deleted=True).filter(role__id__in=target_role).values_list('id', flat=True)
+ if target_type in [2]: # 按部门
target_dept = initial_data.get('target_dept')
- users = Users.objects.exclude(is_deleted=True).filter(dept__id__in=target_dept).values_list('id',flat=True)
- if target_type in [3]: #系统通知
- users = Users.objects.exclude(is_deleted=True).values_list('id',flat=True)
- targetuser_data = [{
- "messagecenter": data.id,
- "users": user
- } for user in users]
+ users = Users.objects.exclude(is_deleted=True).filter(dept__id__in=target_dept).values_list('id', flat=True)
+ if target_type in [3]: # 系统通知
+ users = Users.objects.exclude(is_deleted=True).values_list('id', flat=True)
+ targetuser_data = []
+ for user in users:
+ targetuser_data.append({
+ "messagecenter": data.id,
+ "users": user
+ })
targetuser_instance = MessageCenterTargetUserSerializer(data=targetuser_data, many=True, request=self.request)
targetuser_instance.is_valid(raise_exception=True)
targetuser_instance.save()
+ for user in users:
+ unread_count = MessageCenterTargetUser.objects.filter(users__id=user, is_read=False).count()
+ websocket_push(user, {"sender": 'system', "contentType": 'TEXT',
+ "content": {"model": 'message_center', "unread": unread_count}})
return data
class Meta:
@@ -121,8 +133,6 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
read_only_fields = ["id"]
-
-
class MessageCenterViewSet(CustomModelViewSet):
"""
消息中心接口
@@ -138,7 +148,7 @@ class MessageCenterViewSet(CustomModelViewSet):
extra_filter_backends = []
def get_queryset(self):
- if self.action=='list':
+ if self.action == 'list':
return MessageCenter.objects.filter(creator=self.request.user.id).all()
return MessageCenter.objects.all()
@@ -148,22 +158,26 @@ class MessageCenterViewSet(CustomModelViewSet):
"""
pk = kwargs.get('pk')
user_id = self.request.user.id
- queryset = MessageCenterTargetUser.objects.filter(users__id=user_id,messagecenter__id=pk).first()
+ queryset = MessageCenterTargetUser.objects.filter(users__id=user_id, messagecenter__id=pk).first()
if queryset:
queryset.is_read = True
queryset.save()
instance = self.get_object()
serializer = self.get_serializer(instance)
+ # 主动推送消息
+ unread_count = MessageCenterTargetUser.objects.filter(users__id=user_id, is_read=False).count()
+ websocket_push(user_id, {"sender": 'system', "contentType": 'TEXT',
+ "content": {"model": 'message_center', "unread": unread_count}})
return DetailResponse(data=serializer.data, msg="获取成功")
-
- @action(methods=['GET'],detail=False,permission_classes=[IsAuthenticated])
- def get_self_receive(self,request):
+ @action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
+ def get_self_receive(self, request):
"""
获取接收到的消息
"""
self_user_id = self.request.user.id
- queryset = MessageCenterTargetUser.objects.filter(users__id=self_user_id).exclude(messagecenter__is_deleted=True).order_by('-create_datetime')
+ queryset = MessageCenterTargetUser.objects.filter(users__id=self_user_id).exclude(
+ messagecenter__is_deleted=True).order_by('-create_datetime')
# queryset = self.filter_queryset(queryset)
page = self.paginate_queryset(queryset)
if page is not None:
@@ -173,7 +187,7 @@ class MessageCenterViewSet(CustomModelViewSet):
return SuccessResponse(data=serializer.data, msg="获取成功")
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
- def get_newest_msg(self,request):
+ def get_newest_msg(self, request):
"""
获取最新的一条消息
"""
@@ -184,4 +198,4 @@ class MessageCenterViewSet(CustomModelViewSet):
if queryset:
serializer = MessageCenterTargetUserListSerializer(queryset, many=False, request=request)
data = serializer.data
- return DetailResponse(data=data, msg="获取成功")
\ No newline at end of file
+ return DetailResponse(data=data, msg="获取成功")
diff --git a/web/package.json b/web/package.json
index 1aa01a4..32044c8 100644
--- a/web/package.json
+++ b/web/package.json
@@ -44,7 +44,7 @@
"vue": "^2.6.11",
"vue-i18n": "^8.15.1",
"vue-infinite-scroll": "^2.0.2",
- "vue-router": "^3.1.3",
+ "vue-router": "^3.6.5",
"vue-splitpane": "^1.0.6",
"vuex": "^3.1.2",
"vxe-table": "^3.3.2",
diff --git a/web/src/api/websocket.js b/web/src/api/websocket.js
index d38ad05..e9b24e1 100644
--- a/web/src/api/websocket.js
+++ b/web/src/api/websocket.js
@@ -1,5 +1,6 @@
import ElementUI from 'element-ui'
import util from '@/libs/util'
+import store from '@/store'
function initWebSocket (e) {
const token = util.cookies.get('token')
if (token) {
@@ -53,15 +54,23 @@ function webSocketOnMessage (e) {
duration: 0
})
} else {
- console.log(data.content)
- return data
+ const { content } = data
+ if (content.model === 'message_center') {
+ const unread = content.unread
+ store.dispatch('d2admin/messagecenter/setUnread',unread)
+ }
}
}
// 关闭websiocket
function closeWebsocket () {
console.log('连接已关闭...')
- // close()
- this.socket.close()
+ ElementUI.Notification({
+ title: 'websocket',
+ message: '连接已关闭...',
+ type: 'danger',
+ position: 'bottom-right',
+ duration: 3000
+ })
}
/**
@@ -72,5 +81,5 @@ function webSocketSend (message) {
this.socket.send(JSON.stringify(message))
}
export default {
- initWebSocket, closeWebsocket, webSocketSend,webSocketOnMessage
+ initWebSocket, closeWebsocket, webSocketSend
}
diff --git a/web/src/layout/header-aside/components/header-message/index.vue b/web/src/layout/header-aside/components/header-message/index.vue
index 6c6eab1..1d46f8d 100644
--- a/web/src/layout/header-aside/components/header-message/index.vue
+++ b/web/src/layout/header-aside/components/header-message/index.vue
@@ -14,8 +14,19 @@
class="d2-ml-0 d2-mr btn-text can-hover"
type="text"
slot="reference" @click="getList">
+
+
+
@@ -27,23 +38,29 @@