2022-08-14 11:11:21 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2022-11-15 09:36:05 +00:00
|
|
|
import urllib
|
2022-08-14 11:11:21 +00:00
|
|
|
|
2022-11-15 09:36:05 +00:00
|
|
|
from asgiref.sync import sync_to_async, async_to_sync
|
|
|
|
from channels.db import database_sync_to_async
|
|
|
|
from channels.generic.websocket import AsyncJsonWebsocketConsumer, AsyncWebsocketConsumer
|
2022-08-14 11:11:21 +00:00
|
|
|
import json
|
|
|
|
|
2022-11-15 09:36:05 +00:00
|
|
|
from channels.layers import get_channel_layer
|
2022-08-14 11:11:21 +00:00
|
|
|
from jwt import InvalidSignatureError
|
2023-01-02 17:29:46 +00:00
|
|
|
from rest_framework.request import Request
|
2022-08-14 11:11:21 +00:00
|
|
|
|
|
|
|
from application import settings
|
2023-01-02 17:29:46 +00:00
|
|
|
from dvadmin.system.models import MessageCenter, Users, MessageCenterTargetUser
|
|
|
|
from dvadmin.system.views.message_center import MessageCenterTargetUserSerializer
|
|
|
|
from dvadmin.utils.serializers import CustomModelSerializer
|
2022-08-14 11:11:21 +00:00
|
|
|
|
2022-11-15 09:36:05 +00:00
|
|
|
send_dict = {}
|
2022-08-14 11:11:21 +00:00
|
|
|
|
2023-01-02 17:29:46 +00:00
|
|
|
|
2022-08-14 11:11:21 +00:00
|
|
|
# 发送消息结构体
|
2023-01-02 17:29:46 +00:00
|
|
|
def set_message(sender, msg_type, msg, unread=0):
|
2022-11-15 09:36:05 +00:00
|
|
|
text = {
|
2022-08-14 11:11:21 +00:00
|
|
|
'sender': sender,
|
|
|
|
'contentType': msg_type,
|
|
|
|
'content': msg,
|
2023-01-02 17:29:46 +00:00
|
|
|
'unread': unread
|
2022-08-14 11:11:21 +00:00
|
|
|
}
|
2022-11-15 09:36:05 +00:00
|
|
|
return text
|
|
|
|
|
2023-01-02 17:29:46 +00:00
|
|
|
|
|
|
|
# 异步获取消息中心的目标用户
|
2022-11-15 09:36:05 +00:00
|
|
|
@database_sync_to_async
|
|
|
|
def _get_message_center_instance(message_id):
|
2022-11-16 16:02:23 +00:00
|
|
|
from dvadmin.system.models import MessageCenter
|
2023-01-02 17:29:46 +00:00
|
|
|
_MessageCenter = MessageCenter.objects.filter(id=message_id).values_list('target_user', flat=True)
|
2022-11-15 09:36:05 +00:00
|
|
|
if _MessageCenter:
|
|
|
|
return _MessageCenter
|
|
|
|
else:
|
|
|
|
return []
|
2022-08-14 11:11:21 +00:00
|
|
|
|
2023-01-02 17:29:46 +00:00
|
|
|
|
2022-11-16 14:09:16 +00:00
|
|
|
@database_sync_to_async
|
|
|
|
def _get_message_unread(user_id):
|
2023-01-02 17:29:46 +00:00
|
|
|
"""获取用户的未读消息数量"""
|
2022-11-16 16:02:23 +00:00
|
|
|
from dvadmin.system.models import MessageCenterTargetUser
|
2023-01-02 17:29:46 +00:00
|
|
|
count = MessageCenterTargetUser.objects.filter(users=user_id, is_read=False).count()
|
2022-11-16 14:09:16 +00:00
|
|
|
return count or 0
|
|
|
|
|
2022-08-14 11:11:21 +00:00
|
|
|
|
2022-11-15 09:36:05 +00:00
|
|
|
def request_data(scope):
|
|
|
|
query_string = scope.get('query_string', b'').decode('utf-8')
|
|
|
|
qs = urllib.parse.parse_qs(query_string)
|
|
|
|
return qs
|
|
|
|
|
2023-01-02 17:29:46 +00:00
|
|
|
|
2022-11-15 09:36:05 +00:00
|
|
|
class DvadminWebSocket(AsyncJsonWebsocketConsumer):
|
|
|
|
async def connect(self):
|
|
|
|
try:
|
|
|
|
import jwt
|
|
|
|
self.service_uid = self.scope["url_route"]["kwargs"]["service_uid"]
|
|
|
|
decoded_result = jwt.decode(self.service_uid, settings.SECRET_KEY, algorithms=["HS256"])
|
|
|
|
if decoded_result:
|
|
|
|
self.user_id = decoded_result.get('user_id')
|
2023-01-02 17:29:46 +00:00
|
|
|
self.chat_group_name = "user_" + str(self.user_id)
|
|
|
|
# 收到连接时候处理,
|
2022-11-15 09:36:05 +00:00
|
|
|
await self.channel_layer.group_add(
|
|
|
|
self.chat_group_name,
|
|
|
|
self.channel_name
|
|
|
|
)
|
|
|
|
await self.accept()
|
2022-11-16 14:09:16 +00:00
|
|
|
# 发送连接成功
|
2023-01-02 17:29:46 +00:00
|
|
|
#await self.send_json(set_message('system', 'SYSTEM', '连接成功'))
|
2022-11-16 14:09:16 +00:00
|
|
|
# 主动推送消息
|
|
|
|
unread_count = await _get_message_unread(self.user_id)
|
2023-01-02 17:29:46 +00:00
|
|
|
await self.send_json(
|
|
|
|
set_message('system', 'SYSTEM', "请查看您的未读消息~",
|
|
|
|
unread=unread_count))
|
2022-11-15 09:36:05 +00:00
|
|
|
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)
|
|
|
|
print("连接关闭")
|
|
|
|
await self.close(close_code)
|
|
|
|
|
|
|
|
|
|
|
|
class MegCenter(DvadminWebSocket):
|
|
|
|
"""
|
|
|
|
消息中心
|
|
|
|
"""
|
|
|
|
|
|
|
|
async def receive(self, text_data):
|
|
|
|
# 接受客户端的信息,你处理的函数
|
|
|
|
text_data_json = json.loads(text_data)
|
|
|
|
message_id = text_data_json.get('message_id', None)
|
|
|
|
user_list = await _get_message_center_instance(message_id)
|
|
|
|
for send_user in user_list:
|
|
|
|
await self.channel_layer.group_send(
|
|
|
|
"user_" + str(send_user),
|
2022-11-16 14:09:16 +00:00
|
|
|
{'type': 'push.message', 'json': text_data_json}
|
2022-11-15 09:36:05 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
async def push_message(self, event):
|
2023-01-02 17:29:46 +00:00
|
|
|
"""消息发送"""
|
2022-11-16 14:09:16 +00:00
|
|
|
message = event['json']
|
2022-11-15 09:36:05 +00:00
|
|
|
await self.send(text_data=json.dumps(message))
|
|
|
|
|
|
|
|
|
2023-01-02 17:29:46 +00:00
|
|
|
class MessageCreateSerializer(CustomModelSerializer):
|
2022-11-15 09:36:05 +00:00
|
|
|
"""
|
2023-01-02 17:29:46 +00:00
|
|
|
消息中心-新增-序列化器
|
2022-11-15 09:36:05 +00:00
|
|
|
"""
|
2023-01-02 17:29:46 +00:00
|
|
|
class Meta:
|
|
|
|
model = MessageCenter
|
|
|
|
fields = "__all__"
|
|
|
|
read_only_fields = ["id"]
|
|
|
|
|
|
|
|
def websocket_push(user_id,message):
|
|
|
|
username = "user_" + str(user_id)
|
2022-11-15 09:36:05 +00:00
|
|
|
channel_layer = get_channel_layer()
|
|
|
|
async_to_sync(channel_layer.group_send)(
|
2023-01-02 17:29:46 +00:00
|
|
|
username,
|
|
|
|
{
|
|
|
|
"type": "push.message",
|
|
|
|
"json": message
|
|
|
|
}
|
2022-11-16 16:02:23 +00:00
|
|
|
)
|
2023-01-02 17:29:46 +00:00
|
|
|
|
2023-01-02 17:31:17 +00:00
|
|
|
def create_message_push(title: str, content: str, target_type: int=0, target_user: list=[], target_dept=None, target_role=None,
|
2023-01-02 17:29:46 +00:00
|
|
|
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}
|
|
|
|
}
|
|
|
|
)
|