功能变化: 完成websocket

pull/79/head
猿小天 2022-11-16 22:09:16 +08:00
parent 90e47bdee5
commit f2f01f7043
6 changed files with 127 additions and 41 deletions

View File

@ -10,12 +10,12 @@ from channels.layers import get_channel_layer
from jwt import InvalidSignatureError from jwt import InvalidSignatureError
from application import settings from application import settings
from dvadmin.system.models import MessageCenter from dvadmin.system.models import MessageCenter, MessageCenterTargetUser
send_dict = {} send_dict = {}
# 发送消息结构体 # 发送消息结构体
def message(sender, msg_type, msg): def set_message(sender, msg_type, msg):
text = { text = {
'sender': sender, 'sender': sender,
'contentType': msg_type, 'contentType': msg_type,
@ -32,6 +32,11 @@ def _get_message_center_instance(message_id):
else: else:
return [] 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): def request_data(scope):
query_string = scope.get('query_string', b'').decode('utf-8') query_string = scope.get('query_string', b'').decode('utf-8')
@ -53,7 +58,11 @@ class DvadminWebSocket(AsyncJsonWebsocketConsumer):
self.channel_name self.channel_name
) )
await self.accept() 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: except InvalidSignatureError:
await self.disconnect(None) await self.disconnect(None)
@ -78,23 +87,25 @@ class MegCenter(DvadminWebSocket):
for send_user in user_list: for send_user in user_list:
await self.channel_layer.group_send( await self.channel_layer.group_send(
"user_" + str(send_user), "user_" + str(send_user),
{'type': 'push.message', 'message': text_data_json} {'type': 'push.message', 'json': text_data_json}
) )
async def push_message(self, event): async def push_message(self, event):
message = event['message'] message = event['json']
await self.send(text_data=json.dumps(message)) 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() 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",
"event": event "json": message
} }
) )

View File

@ -5,6 +5,7 @@ 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.dept import DeptSerializer
from dvadmin.system.views.role import RoleSerializer from dvadmin.system.views.role import RoleSerializer
@ -21,9 +22,10 @@ class MessageCenterSerializer(CustomModelSerializer):
role_info = DynamicSerializerMethodField() role_info = DynamicSerializerMethodField()
user_info = DynamicSerializerMethodField() user_info = DynamicSerializerMethodField()
dept_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): 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 # 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
serializer = RoleSerializer( serializer = RoleSerializer(
@ -54,6 +56,7 @@ class MessageCenterSerializer(CustomModelSerializer):
parsed_query=parsed_query parsed_query=parsed_query
) )
return serializer.data return serializer.data
class Meta: class Meta:
model = MessageCenter model = MessageCenter
fields = "__all__" fields = "__all__"
@ -64,15 +67,18 @@ class MessageCenterTargetUserSerializer(CustomModelSerializer):
""" """
目标用户序列化器-序列化器 目标用户序列化器-序列化器
""" """
class Meta: class Meta:
model = MessageCenterTargetUser model = MessageCenterTargetUser
fields = "__all__" fields = "__all__"
read_only_fields = ["id"] read_only_fields = ["id"]
class MessageCenterTargetUserListSerializer(CustomModelSerializer): class MessageCenterTargetUserListSerializer(CustomModelSerializer):
""" """
目标用户序列化器-序列化器 目标用户序列化器-序列化器
""" """
class Meta: class Meta:
model = MessageCenterTargetUser model = MessageCenterTargetUser
fields = "__all__" fields = "__all__"
@ -97,22 +103,28 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
initial_data = self.initial_data initial_data = self.initial_data
target_type = initial_data.get('target_type') target_type = initial_data.get('target_type')
# 在保存之前,根据目标类型,把目标用户查询出来并保存 # 在保存之前,根据目标类型,把目标用户查询出来并保存
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)
targetuser_data = [{ targetuser_data = []
"messagecenter": data.id, for user in users:
"users": user targetuser_data.append({
} for user in users] "messagecenter": data.id,
"users": user
})
targetuser_instance = MessageCenterTargetUserSerializer(data=targetuser_data, many=True, request=self.request) targetuser_instance = MessageCenterTargetUserSerializer(data=targetuser_data, many=True, request=self.request)
targetuser_instance.is_valid(raise_exception=True) targetuser_instance.is_valid(raise_exception=True)
targetuser_instance.save() 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 return data
class Meta: class Meta:
@ -121,8 +133,6 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
read_only_fields = ["id"] read_only_fields = ["id"]
class MessageCenterViewSet(CustomModelViewSet): class MessageCenterViewSet(CustomModelViewSet):
""" """
消息中心接口 消息中心接口
@ -138,7 +148,7 @@ class MessageCenterViewSet(CustomModelViewSet):
extra_filter_backends = [] extra_filter_backends = []
def get_queryset(self): 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.filter(creator=self.request.user.id).all()
return MessageCenter.objects.all() return MessageCenter.objects.all()
@ -148,22 +158,26 @@ class MessageCenterViewSet(CustomModelViewSet):
""" """
pk = kwargs.get('pk') pk = kwargs.get('pk')
user_id = self.request.user.id 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: if queryset:
queryset.is_read = True queryset.is_read = True
queryset.save() queryset.save()
instance = self.get_object() instance = self.get_object()
serializer = self.get_serializer(instance) 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="获取成功") return DetailResponse(data=serializer.data, msg="获取成功")
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated])
@action(methods=['GET'],detail=False,permission_classes=[IsAuthenticated]) def get_self_receive(self, request):
def get_self_receive(self,request):
""" """
获取接收到的消息 获取接收到的消息
""" """
self_user_id = self.request.user.id 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) # 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:
@ -173,7 +187,7 @@ class MessageCenterViewSet(CustomModelViewSet):
return SuccessResponse(data=serializer.data, msg="获取成功") return SuccessResponse(data=serializer.data, msg="获取成功")
@action(methods=['GET'], detail=False, permission_classes=[IsAuthenticated]) @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: if queryset:
serializer = MessageCenterTargetUserListSerializer(queryset, many=False, request=request) serializer = MessageCenterTargetUserListSerializer(queryset, many=False, request=request)
data = serializer.data data = serializer.data
return DetailResponse(data=data, msg="获取成功") return DetailResponse(data=data, msg="获取成功")

View File

@ -44,7 +44,7 @@
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-i18n": "^8.15.1", "vue-i18n": "^8.15.1",
"vue-infinite-scroll": "^2.0.2", "vue-infinite-scroll": "^2.0.2",
"vue-router": "^3.1.3", "vue-router": "^3.6.5",
"vue-splitpane": "^1.0.6", "vue-splitpane": "^1.0.6",
"vuex": "^3.1.2", "vuex": "^3.1.2",
"vxe-table": "^3.3.2", "vxe-table": "^3.3.2",

View File

@ -1,5 +1,6 @@
import ElementUI from 'element-ui' import ElementUI from 'element-ui'
import util from '@/libs/util' import util from '@/libs/util'
import store from '@/store'
function initWebSocket (e) { function initWebSocket (e) {
const token = util.cookies.get('token') const token = util.cookies.get('token')
if (token) { if (token) {
@ -53,15 +54,23 @@ function webSocketOnMessage (e) {
duration: 0 duration: 0
}) })
} else { } else {
console.log(data.content) const { content } = data
return data if (content.model === 'message_center') {
const unread = content.unread
store.dispatch('d2admin/messagecenter/setUnread',unread)
}
} }
} }
// 关闭websiocket // 关闭websiocket
function closeWebsocket () { function closeWebsocket () {
console.log('连接已关闭...') console.log('连接已关闭...')
// close() ElementUI.Notification({
this.socket.close() title: 'websocket',
message: '连接已关闭...',
type: 'danger',
position: 'bottom-right',
duration: 3000
})
} }
/** /**
@ -72,5 +81,5 @@ function webSocketSend (message) {
this.socket.send(JSON.stringify(message)) this.socket.send(JSON.stringify(message))
} }
export default { export default {
initWebSocket, closeWebsocket, webSocketSend,webSocketOnMessage initWebSocket, closeWebsocket, webSocketSend
} }

View File

@ -14,8 +14,19 @@
class="d2-ml-0 d2-mr btn-text can-hover" class="d2-ml-0 d2-mr btn-text can-hover"
type="text" type="text"
slot="reference" @click="getList"> slot="reference" @click="getList">
<el-badge
v-if="unread > 0"
:max="99"
:value="unread"
:is-dot="unread === 0"
>
<d2-icon
:name="unread === 0 ? 'dot-circle-o' : 'bell-o'"
style="font-size: 20px"
/>
</el-badge>
<d2-icon <d2-icon
v-else
name="bell-o" name="bell-o"
style="font-size: 16px"/> style="font-size: 16px"/>
</el-button> </el-button>
@ -27,23 +38,29 @@
<script> <script>
import msgList from './components/msg-list' import msgList from './components/msg-list'
import { request } from '@/api/service' import { request } from '@/api/service'
import { mapGetters } from 'vuex'
export default { export default {
components:{ computed: {
...mapGetters('d2admin', {
unread: 'messagecenter/unread'
})
},
components: {
msgList msgList
}, },
data () { data () {
return { return {
msgObj:null msgObj: null
} }
}, },
methods:{ methods: {
getList () { getList () {
request({ request({
url: '/api/system/message_center/get_newest_msg/', url: '/api/system/message_center/get_newest_msg/',
method: 'get', method: 'get',
params: {} params: {}
}).then(res => { }).then(res => {
const {data} = res const { data } = res
this.msgObj = data this.msgObj = data
}) })
} }

View File

@ -0,0 +1,35 @@
export default {
namespaced: true,
state: {
// 未读消息
unread: 0
},
getters: {
unread (state) {
return state.unread
}
},
actions: {
/**
* @description 添加一个日志
* @param {Object} context
* @param {String} param message {String} 信息
* @param {String} param type {String} 类型
* @param {Object} payload meta {Object} 附带的信息
*/
async setUnread ({ state,commit },number) {
commit('set',number)
}
},
mutations: {
/**
* 设置未读消息
* @param state
* @param number
*/
async set (state, number) {
state.unread = number
}
}
}