功能变化:

1.优化websocket;
pull/84/head
猿小天 2023-01-03 01:29:46 +08:00
parent 62943431f2
commit c046b0e0a2
4 changed files with 132 additions and 44 deletions

View File

@ -8,20 +8,27 @@ import json
from channels.layers import get_channel_layer
from jwt import InvalidSignatureError
from rest_framework.request import Request
from application import settings
from dvadmin.system.models import MessageCenter, Users, MessageCenterTargetUser
from dvadmin.system.views.message_center import MessageCenterTargetUserSerializer
from dvadmin.utils.serializers import CustomModelSerializer
send_dict = {}
# 发送消息结构体
def set_message(sender, msg_type, msg):
def set_message(sender, msg_type, msg, unread=0):
text = {
'sender': sender,
'contentType': msg_type,
'content': msg,
'unread': unread
}
return text
# 异步获取消息中心的目标用户
@database_sync_to_async
def _get_message_center_instance(message_id):
@ -32,8 +39,10 @@ def _get_message_center_instance(message_id):
else:
return []
@database_sync_to_async
def _get_message_unread(user_id):
"""获取用户的未读消息数量"""
from dvadmin.system.models import MessageCenterTargetUser
count = MessageCenterTargetUser.objects.filter(users=user_id, is_read=False).count()
return count or 0
@ -44,6 +53,7 @@ def request_data(scope):
qs = urllib.parse.parse_qs(query_string)
return qs
class DvadminWebSocket(AsyncJsonWebsocketConsumer):
async def connect(self):
try:
@ -60,14 +70,15 @@ class DvadminWebSocket(AsyncJsonWebsocketConsumer):
)
await self.accept()
# 发送连接成功
await self.send_json(set_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}))
await self.send_json(
set_message('system', 'SYSTEM', "请查看您的未读消息~",
unread=unread_count))
except InvalidSignatureError:
await self.disconnect(None)
async def disconnect(self, close_code):
# Leave room group
await self.channel_layer.group_discard(self.chat_group_name, self.channel_name)
@ -92,16 +103,22 @@ class MegCenter(DvadminWebSocket):
)
async def push_message(self, event):
"""消息发送"""
message = event['json']
await self.send(text_data=json.dumps(message))
class MessageCreateSerializer(CustomModelSerializer):
"""
消息中心-新增-序列化器
"""
class Meta:
model = MessageCenter
fields = "__all__"
read_only_fields = ["id"]
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,
@ -110,3 +127,50 @@ def websocket_push(user_id, message):
"json": message
}
)
def create_message_push(title: str, content: str, target_type: int, target_user: list, target_dept=None, target_role=None,
message: dict = {'contentType': 'INFO', 'content': '测试~'}, request= Request):
if message is None:
message = {"contentType": "INFO", "content": None}
if target_role is None:
target_role = []
if target_dept is None:
target_dept = []
data = {
"title": title,
"content": content,
"target_type": target_type,
"target_user":target_user,
"target_dept":target_dept,
"target_role":target_role
}
message_center_instance = MessageCreateSerializer(data=data,request=request)
message_center_instance.is_valid(raise_exception=True)
message_center_instance.save()
users = target_user or []
if target_type in [1]: # 按角色
users = Users.objects.filter(role__id__in=target_role).values_list('id', flat=True)
if target_type in [2]: # 按部门
users = Users.objects.filter(dept__id__in=target_dept).values_list('id', flat=True)
if target_type in [3]: # 系统通知
users = Users.objects.values_list('id', flat=True)
targetuser_data = []
for user in users:
targetuser_data.append({
"messagecenter": message_center_instance.instance.id,
"users": user
})
targetuser_instance = MessageCenterTargetUserSerializer(data=targetuser_data, many=True, request=request)
targetuser_instance.is_valid(raise_exception=True)
targetuser_instance.save()
for user in users:
username = "user_" + str(user)
unread_count = async_to_sync(_get_message_unread)(user)
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
username,
{
"type": "push.message",
"json": {**message,'unread':unread_count}
}
)

View File

@ -1,15 +1,14 @@
# -*- coding: utf-8 -*-
import json
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django_restql.fields import DynamicSerializerMethodField
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
from dvadmin.system.views.user import UserSerializer
from dvadmin.utils.json_response import SuccessResponse, DetailResponse
from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet
@ -28,6 +27,7 @@ class MessageCenterSerializer(CustomModelSerializer):
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
from dvadmin.system.views.role import RoleSerializer
serializer = RoleSerializer(
roles,
many=True,
@ -39,6 +39,7 @@ class MessageCenterSerializer(CustomModelSerializer):
users = instance.target_user.all()
# You can do what ever you want in here
# `parsed_query` param is passed to BookSerializer to allow further querying
from dvadmin.system.views.user import UserSerializer
serializer = UserSerializer(
users,
many=True,
@ -50,6 +51,7 @@ class MessageCenterSerializer(CustomModelSerializer):
dept = instance.target_dept.all()
# You can do what ever you want in here
# `parsed_query` param is passed to BookSerializer to allow further querying
from dvadmin.system.views.dept import DeptSerializer
serializer = DeptSerializer(
dept,
many=True,
@ -78,20 +80,33 @@ class MessageCenterTargetUserListSerializer(CustomModelSerializer):
"""
目标用户序列化器-序列化器
"""
is_read = serializers.SerializerMethodField()
def get_is_read(self, instance):
user_id = self.request.user.id
message_center_id = instance.id
queryset = MessageCenterTargetUser.objects.filter(messagecenter__id=message_center_id,users_id=user_id).first()
return queryset.is_read
class Meta:
model = MessageCenterTargetUser
model = MessageCenter
fields = "__all__"
read_only_fields = ["id"]
def to_representation(self, instance):
data = super().to_representation(instance)
data['title'] = instance.messagecenter.title
data['content'] = instance.messagecenter.content
data['target_type'] = instance.messagecenter.target_type
data['id'] = instance.messagecenter.id
return data
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",
"json": message
}
)
class MessageCenterCreateSerializer(CustomModelSerializer):
"""
@ -105,10 +120,10 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
# 在保存之前,根据目标类型,把目标用户查询出来并保存
users = initial_data.get('target_user', [])
if target_type in [1]: # 按角色
target_role = initial_data.get('target_role')
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]: # 按部门
target_dept = initial_data.get('target_dept')
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)
@ -166,8 +181,8 @@ class MessageCenterViewSet(CustomModelViewSet):
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}})
websocket_push(user_id, message={"sender": 'system', "contentType": 'TEXT',
"content": '您查看了一条消息~', "unread": unread_count})
return DetailResponse(data=serializer.data, msg="获取成功")
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
@ -176,7 +191,9 @@ class MessageCenterViewSet(CustomModelViewSet):
获取接收到的消息
"""
self_user_id = self.request.user.id
queryset = MessageCenterTargetUser.objects.filter(users__id=self_user_id).order_by('-create_datetime')
# queryset = MessageCenterTargetUser.objects.filter(users__id=self_user_id).order_by('-create_datetime')
queryset = MessageCenter.objects.filter(target_user__id=self_user_id)
print(queryset)
# queryset = self.filter_queryset(queryset)
page = self.paginate_queryset(queryset)
if page is not None:

View File

@ -29,9 +29,11 @@ function webSocketOnError (e) {
*/
function webSocketOnMessage (e) {
const data = JSON.parse(e.data)
const {unread} = data
store.dispatch('d2admin/messagecenter/setUnread', unread || 0)
if (data.contentType === 'SYSTEM') {
ElementUI.Notification({
title: 'websocket',
title: '系统消息',
message: data.content,
type: 'success',
position: 'bottom-right',
@ -54,11 +56,13 @@ function webSocketOnMessage (e) {
duration: 0
})
} else {
const { content } = data
if (content.model === 'message_center') {
const unread = content.unread
store.dispatch('d2admin/messagecenter/setUnread', unread)
}
ElementUI.Notification({
title: '温馨提示',
message: data.content,
type: 'info',
position: 'bottom-right',
duration: 3000
})
}
}
// 关闭websiocket

View File

@ -6,6 +6,7 @@
v-bind="_crudProps"
v-on="_crudListeners"
@onView="onView"
@doDialogClosed="doDialogClosed"
>
<div slot="header">
<crud-search ref="search" :options="crud.searchOptions" @submit="handleSearch" />
@ -39,7 +40,6 @@ export default {
tabActivted: 'send'
}
},
computed: {
},
methods: {
@ -78,12 +78,15 @@ export default {
template: viewTemplate
})
this.infoRequest(row)
this.doRefresh()
},
onTabClick (tab) {
const { name } = tab
this.tabActivted = name
this.doRefresh()
},
//
doDialogClosed (context) {
this.doRefresh()
}
}
}