parent
62943431f2
commit
c046b0e0a2
|
@ -8,34 +8,43 @@ import json
|
||||||
|
|
||||||
from channels.layers import get_channel_layer
|
from channels.layers import get_channel_layer
|
||||||
from jwt import InvalidSignatureError
|
from jwt import InvalidSignatureError
|
||||||
|
from rest_framework.request import Request
|
||||||
|
|
||||||
from application import settings
|
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 = {}
|
send_dict = {}
|
||||||
|
|
||||||
|
|
||||||
# 发送消息结构体
|
# 发送消息结构体
|
||||||
def set_message(sender, msg_type, msg):
|
def set_message(sender, msg_type, msg, unread=0):
|
||||||
text = {
|
text = {
|
||||||
'sender': sender,
|
'sender': sender,
|
||||||
'contentType': msg_type,
|
'contentType': msg_type,
|
||||||
'content': msg,
|
'content': msg,
|
||||||
|
'unread': unread
|
||||||
}
|
}
|
||||||
return text
|
return text
|
||||||
|
|
||||||
#异步获取消息中心的目标用户
|
|
||||||
|
# 异步获取消息中心的目标用户
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
def _get_message_center_instance(message_id):
|
def _get_message_center_instance(message_id):
|
||||||
from dvadmin.system.models import MessageCenter
|
from dvadmin.system.models import MessageCenter
|
||||||
_MessageCenter = MessageCenter.objects.filter(id=message_id).values_list('target_user',flat=True)
|
_MessageCenter = MessageCenter.objects.filter(id=message_id).values_list('target_user', flat=True)
|
||||||
if _MessageCenter:
|
if _MessageCenter:
|
||||||
return _MessageCenter
|
return _MessageCenter
|
||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
@database_sync_to_async
|
@database_sync_to_async
|
||||||
def _get_message_unread(user_id):
|
def _get_message_unread(user_id):
|
||||||
|
"""获取用户的未读消息数量"""
|
||||||
from dvadmin.system.models import MessageCenterTargetUser
|
from dvadmin.system.models import MessageCenterTargetUser
|
||||||
count = MessageCenterTargetUser.objects.filter(users=user_id,is_read=False).count()
|
count = MessageCenterTargetUser.objects.filter(users=user_id, is_read=False).count()
|
||||||
return count or 0
|
return count or 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +53,7 @@ def request_data(scope):
|
||||||
qs = urllib.parse.parse_qs(query_string)
|
qs = urllib.parse.parse_qs(query_string)
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class DvadminWebSocket(AsyncJsonWebsocketConsumer):
|
class DvadminWebSocket(AsyncJsonWebsocketConsumer):
|
||||||
async def connect(self):
|
async def connect(self):
|
||||||
try:
|
try:
|
||||||
|
@ -52,22 +62,23 @@ class DvadminWebSocket(AsyncJsonWebsocketConsumer):
|
||||||
decoded_result = jwt.decode(self.service_uid, settings.SECRET_KEY, algorithms=["HS256"])
|
decoded_result = jwt.decode(self.service_uid, settings.SECRET_KEY, algorithms=["HS256"])
|
||||||
if decoded_result:
|
if decoded_result:
|
||||||
self.user_id = decoded_result.get('user_id')
|
self.user_id = decoded_result.get('user_id')
|
||||||
self.chat_group_name = "user_"+str(self.user_id)
|
self.chat_group_name = "user_" + str(self.user_id)
|
||||||
#收到连接时候处理,
|
# 收到连接时候处理,
|
||||||
await self.channel_layer.group_add(
|
await self.channel_layer.group_add(
|
||||||
self.chat_group_name,
|
self.chat_group_name,
|
||||||
self.channel_name
|
self.channel_name
|
||||||
)
|
)
|
||||||
await self.accept()
|
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)
|
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:
|
except InvalidSignatureError:
|
||||||
await self.disconnect(None)
|
await self.disconnect(None)
|
||||||
|
|
||||||
|
|
||||||
async def disconnect(self, close_code):
|
async def disconnect(self, close_code):
|
||||||
# Leave room group
|
# Leave room group
|
||||||
await self.channel_layer.group_discard(self.chat_group_name, self.channel_name)
|
await self.channel_layer.group_discard(self.chat_group_name, self.channel_name)
|
||||||
|
@ -92,21 +103,74 @@ class MegCenter(DvadminWebSocket):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def push_message(self, event):
|
async def push_message(self, event):
|
||||||
|
"""消息发送"""
|
||||||
message = event['json']
|
message = event['json']
|
||||||
await self.send(text_data=json.dumps(message))
|
await self.send(text_data=json.dumps(message))
|
||||||
|
|
||||||
|
|
||||||
def websocket_push(user_id, message):
|
class MessageCreateSerializer(CustomModelSerializer):
|
||||||
"""
|
"""
|
||||||
主动推送消息
|
消息中心-新增-序列化器
|
||||||
"""
|
"""
|
||||||
username = "user_"+str(user_id)
|
class Meta:
|
||||||
print(103,message)
|
model = MessageCenter
|
||||||
|
fields = "__all__"
|
||||||
|
read_only_fields = ["id"]
|
||||||
|
|
||||||
|
def websocket_push(user_id,message):
|
||||||
|
username = "user_" + str(user_id)
|
||||||
channel_layer = get_channel_layer()
|
channel_layer = get_channel_layer()
|
||||||
async_to_sync(channel_layer.group_send)(
|
async_to_sync(channel_layer.group_send)(
|
||||||
username,
|
username,
|
||||||
{
|
{
|
||||||
"type": "push.message",
|
"type": "push.message",
|
||||||
"json": 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}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from asgiref.sync import async_to_sync
|
||||||
|
from channels.layers import get_channel_layer
|
||||||
from django_restql.fields import DynamicSerializerMethodField
|
from django_restql.fields import DynamicSerializerMethodField
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.decorators import action, permission_classes
|
from rest_framework.decorators import action, permission_classes
|
||||||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||||||
|
|
||||||
from application.websocketConfig import websocket_push
|
|
||||||
from dvadmin.system.models import MessageCenter, Users, MessageCenterTargetUser
|
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.json_response import SuccessResponse, DetailResponse
|
||||||
from dvadmin.utils.serializers import CustomModelSerializer
|
from dvadmin.utils.serializers import CustomModelSerializer
|
||||||
from dvadmin.utils.viewset import CustomModelViewSet
|
from dvadmin.utils.viewset import CustomModelViewSet
|
||||||
|
@ -28,6 +27,7 @@ class MessageCenterSerializer(CustomModelSerializer):
|
||||||
roles = instance.target_role.all()
|
roles = instance.target_role.all()
|
||||||
# You can do what ever you want in here
|
# You can do what ever you want in here
|
||||||
# `parsed_query` param is passed to BookSerializer to allow further querying
|
# `parsed_query` param is passed to BookSerializer to allow further querying
|
||||||
|
from dvadmin.system.views.role import RoleSerializer
|
||||||
serializer = RoleSerializer(
|
serializer = RoleSerializer(
|
||||||
roles,
|
roles,
|
||||||
many=True,
|
many=True,
|
||||||
|
@ -39,6 +39,7 @@ class MessageCenterSerializer(CustomModelSerializer):
|
||||||
users = instance.target_user.all()
|
users = instance.target_user.all()
|
||||||
# You can do what ever you want in here
|
# You can do what ever you want in here
|
||||||
# `parsed_query` param is passed to BookSerializer to allow further querying
|
# `parsed_query` param is passed to BookSerializer to allow further querying
|
||||||
|
from dvadmin.system.views.user import UserSerializer
|
||||||
serializer = UserSerializer(
|
serializer = UserSerializer(
|
||||||
users,
|
users,
|
||||||
many=True,
|
many=True,
|
||||||
|
@ -50,6 +51,7 @@ class MessageCenterSerializer(CustomModelSerializer):
|
||||||
dept = instance.target_dept.all()
|
dept = instance.target_dept.all()
|
||||||
# You can do what ever you want in here
|
# You can do what ever you want in here
|
||||||
# `parsed_query` param is passed to BookSerializer to allow further querying
|
# `parsed_query` param is passed to BookSerializer to allow further querying
|
||||||
|
from dvadmin.system.views.dept import DeptSerializer
|
||||||
serializer = DeptSerializer(
|
serializer = DeptSerializer(
|
||||||
dept,
|
dept,
|
||||||
many=True,
|
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:
|
class Meta:
|
||||||
model = MessageCenterTargetUser
|
model = MessageCenter
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
read_only_fields = ["id"]
|
read_only_fields = ["id"]
|
||||||
|
|
||||||
def to_representation(self, instance):
|
def websocket_push(user_id, message):
|
||||||
data = super().to_representation(instance)
|
"""
|
||||||
data['title'] = instance.messagecenter.title
|
主动推送消息
|
||||||
data['content'] = instance.messagecenter.content
|
"""
|
||||||
data['target_type'] = instance.messagecenter.target_type
|
username = "user_"+str(user_id)
|
||||||
data['id'] = instance.messagecenter.id
|
print(103,message)
|
||||||
return data
|
channel_layer = get_channel_layer()
|
||||||
|
async_to_sync(channel_layer.group_send)(
|
||||||
|
username,
|
||||||
|
{
|
||||||
|
"type": "push.message",
|
||||||
|
"json": message
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
class MessageCenterCreateSerializer(CustomModelSerializer):
|
class MessageCenterCreateSerializer(CustomModelSerializer):
|
||||||
"""
|
"""
|
||||||
|
@ -105,10 +120,10 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
|
||||||
# 在保存之前,根据目标类型,把目标用户查询出来并保存
|
# 在保存之前,根据目标类型,把目标用户查询出来并保存
|
||||||
users = initial_data.get('target_user', [])
|
users = initial_data.get('target_user', [])
|
||||||
if target_type in [1]: # 按角色
|
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)
|
users = Users.objects.exclude(is_deleted=True).filter(role__id__in=target_role).values_list('id', flat=True)
|
||||||
if target_type in [2]: # 按部门
|
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)
|
users = Users.objects.exclude(is_deleted=True).filter(dept__id__in=target_dept).values_list('id', flat=True)
|
||||||
if target_type in [3]: # 系统通知
|
if target_type in [3]: # 系统通知
|
||||||
users = Users.objects.exclude(is_deleted=True).values_list('id', flat=True)
|
users = Users.objects.exclude(is_deleted=True).values_list('id', flat=True)
|
||||||
|
@ -166,8 +181,8 @@ class MessageCenterViewSet(CustomModelViewSet):
|
||||||
serializer = self.get_serializer(instance)
|
serializer = self.get_serializer(instance)
|
||||||
# 主动推送消息
|
# 主动推送消息
|
||||||
unread_count = MessageCenterTargetUser.objects.filter(users__id=user_id, is_read=False).count()
|
unread_count = MessageCenterTargetUser.objects.filter(users__id=user_id, is_read=False).count()
|
||||||
websocket_push(user_id, {"sender": 'system', "contentType": 'TEXT',
|
websocket_push(user_id, message={"sender": 'system', "contentType": 'TEXT',
|
||||||
"content": {"model": 'message_center', "unread": unread_count}})
|
"content": '您查看了一条消息~', "unread": unread_count})
|
||||||
return DetailResponse(data=serializer.data, msg="获取成功")
|
return DetailResponse(data=serializer.data, msg="获取成功")
|
||||||
|
|
||||||
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
|
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
|
||||||
|
@ -176,7 +191,9 @@ class MessageCenterViewSet(CustomModelViewSet):
|
||||||
获取接收到的消息
|
获取接收到的消息
|
||||||
"""
|
"""
|
||||||
self_user_id = self.request.user.id
|
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)
|
# queryset = self.filter_queryset(queryset)
|
||||||
page = self.paginate_queryset(queryset)
|
page = self.paginate_queryset(queryset)
|
||||||
if page is not None:
|
if page is not None:
|
||||||
|
|
|
@ -29,9 +29,11 @@ function webSocketOnError (e) {
|
||||||
*/
|
*/
|
||||||
function webSocketOnMessage (e) {
|
function webSocketOnMessage (e) {
|
||||||
const data = JSON.parse(e.data)
|
const data = JSON.parse(e.data)
|
||||||
|
const {unread} = data
|
||||||
|
store.dispatch('d2admin/messagecenter/setUnread', unread || 0)
|
||||||
if (data.contentType === 'SYSTEM') {
|
if (data.contentType === 'SYSTEM') {
|
||||||
ElementUI.Notification({
|
ElementUI.Notification({
|
||||||
title: 'websocket',
|
title: '系统消息',
|
||||||
message: data.content,
|
message: data.content,
|
||||||
type: 'success',
|
type: 'success',
|
||||||
position: 'bottom-right',
|
position: 'bottom-right',
|
||||||
|
@ -54,11 +56,13 @@ function webSocketOnMessage (e) {
|
||||||
duration: 0
|
duration: 0
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const { content } = data
|
ElementUI.Notification({
|
||||||
if (content.model === 'message_center') {
|
title: '温馨提示',
|
||||||
const unread = content.unread
|
message: data.content,
|
||||||
store.dispatch('d2admin/messagecenter/setUnread', unread)
|
type: 'info',
|
||||||
}
|
position: 'bottom-right',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 关闭websiocket
|
// 关闭websiocket
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
v-bind="_crudProps"
|
v-bind="_crudProps"
|
||||||
v-on="_crudListeners"
|
v-on="_crudListeners"
|
||||||
@onView="onView"
|
@onView="onView"
|
||||||
|
@doDialogClosed="doDialogClosed"
|
||||||
>
|
>
|
||||||
<div slot="header">
|
<div slot="header">
|
||||||
<crud-search ref="search" :options="crud.searchOptions" @submit="handleSearch" />
|
<crud-search ref="search" :options="crud.searchOptions" @submit="handleSearch" />
|
||||||
|
@ -39,7 +40,6 @@ export default {
|
||||||
tabActivted: 'send'
|
tabActivted: 'send'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -78,12 +78,15 @@ export default {
|
||||||
template: viewTemplate
|
template: viewTemplate
|
||||||
})
|
})
|
||||||
this.infoRequest(row)
|
this.infoRequest(row)
|
||||||
this.doRefresh()
|
|
||||||
},
|
},
|
||||||
onTabClick (tab) {
|
onTabClick (tab) {
|
||||||
const { name } = tab
|
const { name } = tab
|
||||||
this.tabActivted = name
|
this.tabActivted = name
|
||||||
this.doRefresh()
|
this.doRefresh()
|
||||||
|
},
|
||||||
|
//关闭事件
|
||||||
|
doDialogClosed (context) {
|
||||||
|
this.doRefresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue