功能变化: 完成websocket
parent
90e47bdee5
commit
f2f01f7043
|
@ -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
|
||||||
}
|
}
|
||||||
)
|
)
|
|
@ -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="获取成功")
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue