commit
3b5475aab1
|
@ -14,4 +14,14 @@ from django.core.asgi import get_asgi_application
|
|||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings')
|
||||
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
|
||||
|
||||
application = get_asgi_application()
|
||||
from application.websocketConfig import websocket_application
|
||||
|
||||
http_application = get_asgi_application()
|
||||
|
||||
async def application(scope,receive,send):
|
||||
if scope['type'] == 'http':
|
||||
await http_application(scope, receive, send)
|
||||
elif scope['type'] == 'websocket':
|
||||
await websocket_application(scope, receive, send)
|
||||
else:
|
||||
raise Exception("未知的scope类型,"+ scope['type'])
|
|
@ -0,0 +1,114 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import django
|
||||
|
||||
django.setup()
|
||||
import json
|
||||
import urllib
|
||||
|
||||
#处理websocket传参
|
||||
from jwt import InvalidSignatureError
|
||||
|
||||
from application import settings
|
||||
from dvadmin.system.models import MessageCenter
|
||||
|
||||
|
||||
def request_data(scope):
|
||||
query_string = scope.get('query_string', b'').decode('utf-8')
|
||||
qs = urllib.parse.parse_qs(query_string)
|
||||
return qs
|
||||
|
||||
|
||||
# 全部的websocket sender
|
||||
CONNECTIONS = {}
|
||||
|
||||
|
||||
# 判断用户是否已经连接
|
||||
def check_connection(key):
|
||||
return key in CONNECTIONS
|
||||
|
||||
|
||||
# 发送消息结构体
|
||||
def message(sender, msg_type, msg):
|
||||
text = json.dumps({
|
||||
'sender': sender,
|
||||
'contentType': msg_type,
|
||||
'content': msg,
|
||||
})
|
||||
return {
|
||||
'type': 'websocket.send',
|
||||
'text': text
|
||||
}
|
||||
|
||||
|
||||
async def websocket_application(scope, receive, send):
|
||||
while True:
|
||||
event = await receive()
|
||||
# print('[event] ', event)
|
||||
qs = request_data(scope)
|
||||
print(1,qs)
|
||||
auth = qs.get('auth', [''])[0]
|
||||
user_id = None
|
||||
# 收到建立WebSocket连接的消息
|
||||
if event['type'] == 'websocket.connect':
|
||||
# 昵称验证
|
||||
if not auth:
|
||||
break
|
||||
else:
|
||||
try:
|
||||
import jwt
|
||||
decoded_result = jwt.decode(auth, settings.SECRET_KEY, algorithms=["HS256"])
|
||||
if decoded_result:
|
||||
user_id = decoded_result.get('user_id')
|
||||
# 记录
|
||||
CONNECTIONS[user_id] = send
|
||||
except InvalidSignatureError:
|
||||
break
|
||||
if auth in CONNECTIONS:
|
||||
break
|
||||
|
||||
await send({'type': 'websocket.accept'})
|
||||
await send(message('system', 'INFO', '连接成功'))
|
||||
# # 发送好友列表
|
||||
# friends_list = list(CONNECTIONS.keys())
|
||||
# await send(message('system', 'INFO', friends_list))
|
||||
#
|
||||
# # 向其他人群发消息, 有人登录了
|
||||
# for other in CONNECTIONS.values():
|
||||
# await other(message('system', 'addFriend', auth))
|
||||
|
||||
|
||||
# 收到中断WebSocket连接的消息
|
||||
elif event['type'] == 'websocket.disconnect':
|
||||
# 移除记录
|
||||
if user_id in CONNECTIONS:
|
||||
CONNECTIONS.pop(user_id)
|
||||
|
||||
# # 向其他人群发消息, 有人离线了
|
||||
# for other in CONNECTIONS.values():
|
||||
# await other(message('system', 'removeFriend', user_id))
|
||||
|
||||
# 其他情况,正常的WebSocket消息
|
||||
elif event['type'] == 'websocket.receive':
|
||||
print(11,event)
|
||||
if event['text'] == 'ping':
|
||||
await send(message('system', 'text', 'pong!'))
|
||||
else:
|
||||
receive_msg = json.loads(event['text'])
|
||||
message_id = receive_msg.get('message_id', None)
|
||||
_MessageCenter = MessageCenter.objects.filter(id=message_id).first()
|
||||
if _MessageCenter:
|
||||
user_list = _MessageCenter.target_user.values_list('id',flat=True)
|
||||
for send_user in user_list:
|
||||
if send_user in CONNECTIONS:
|
||||
content_type = receive_msg.get('contentType', 'TEXT')
|
||||
content = receive_msg.get('content', '')
|
||||
msg = message(user_id, content_type, content)
|
||||
await CONNECTIONS[send_user](msg)
|
||||
else:
|
||||
msg = message('system', 'text', '对方已下线或不存在')
|
||||
await send(msg)
|
||||
else:
|
||||
print('a1a1a1')
|
||||
pass
|
||||
|
||||
print('[disconnect]')
|
|
@ -44,3 +44,6 @@ LOGIN_NO_CAPTCHA_AUTH = True
|
|||
# ================================================= #
|
||||
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
# daphne启动命令
|
||||
#daphne application.asgi:application -b 0.0.0.0 -p 8000
|
||||
|
|
|
@ -272,10 +272,57 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "消息中心",
|
||||
"icon": "bullhorn",
|
||||
"sort": 7,
|
||||
"is_link": false,
|
||||
"is_catalog": false,
|
||||
"web_path": "/messageCenter",
|
||||
"component": "system/messageCenter/index",
|
||||
"component_name": "messageCenter",
|
||||
"status": true,
|
||||
"cache": false,
|
||||
"visible": true,
|
||||
"parent": 277,
|
||||
"children": [],
|
||||
"menu_button": [
|
||||
{
|
||||
"name": "查询",
|
||||
"value": "Search",
|
||||
"api": "/api/system/message_center/",
|
||||
"method": 0
|
||||
},
|
||||
{
|
||||
"name": "详情",
|
||||
"value": "Retrieve",
|
||||
"api": "/api/system/message_center/{id}/",
|
||||
"method": 0
|
||||
},
|
||||
{
|
||||
"name": "新增",
|
||||
"value": "Create",
|
||||
"api": "/api/system/message_center/",
|
||||
"method": 1
|
||||
},
|
||||
{
|
||||
"name": "编辑",
|
||||
"value": "Update",
|
||||
"api": "/api/system/message_center/{id}/",
|
||||
"method": 2
|
||||
},
|
||||
{
|
||||
"name": "删除",
|
||||
"value": "Delete",
|
||||
"api": "/api/system/menu/{id}/",
|
||||
"method": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "接口白名单",
|
||||
"icon": "compass",
|
||||
"sort": 7,
|
||||
"sort": 8,
|
||||
"is_link": false,
|
||||
"is_catalog": false,
|
||||
"web_path": "/apiWhiteList",
|
||||
|
|
|
@ -34,8 +34,8 @@ class Users(CoreModel,AbstractUser):
|
|||
user_type = models.IntegerField(
|
||||
choices=USER_TYPE, default=0, verbose_name="用户类型", null=True, blank=True, help_text="用户类型"
|
||||
)
|
||||
post = models.ManyToManyField(to="Post", verbose_name="关联岗位", db_constraint=False, help_text="关联岗位")
|
||||
role = models.ManyToManyField(to="Role", verbose_name="关联角色", db_constraint=False, help_text="关联角色")
|
||||
post = models.ManyToManyField(to="Post",blank=True, verbose_name="关联岗位", db_constraint=False, help_text="关联岗位")
|
||||
role = models.ManyToManyField(to="Role", blank=True,verbose_name="关联角色", db_constraint=False, help_text="关联角色")
|
||||
dept = models.ForeignKey(
|
||||
to="Dept",
|
||||
verbose_name="所属部门",
|
||||
|
@ -416,10 +416,10 @@ class MessageCenter(CoreModel):
|
|||
title = models.CharField(max_length=100,verbose_name="标题",help_text="标题")
|
||||
content = models.TextField(verbose_name="内容",help_text="内容")
|
||||
target_type=models.IntegerField(default=0,verbose_name="目标类型",help_text="目标类型")
|
||||
target_user = models.ForeignKey(to=Users,related_name="target_user",null=True,blank=True,db_constraint=False,on_delete=models.CASCADE,verbose_name="目标用户",help_text="目标用户")
|
||||
target_dept = models.ForeignKey(to=Dept, null=True, blank=True, db_constraint=False, on_delete=models.CASCADE,
|
||||
target_user = models.ManyToManyField(to=Users,related_name="target_user",blank=True,db_constraint=False,verbose_name="目标用户",help_text="目标用户")
|
||||
target_dept = models.ManyToManyField(to=Dept, null=True, blank=True, db_constraint=False,
|
||||
verbose_name="目标部门", help_text="目标部门")
|
||||
target_role = models.ForeignKey(to=Role, null=True, blank=True, db_constraint=False, on_delete=models.CASCADE,
|
||||
target_role = models.ManyToManyField(to=Role, blank=True, db_constraint=False,
|
||||
verbose_name="目标角色", help_text="目标角色")
|
||||
is_read=models.BooleanField(default=False,blank=True,verbose_name="是否已读",help_text="是否已读")
|
||||
|
||||
|
@ -427,5 +427,4 @@ class MessageCenter(CoreModel):
|
|||
db_table = table_prefix + "message_center"
|
||||
verbose_name = "消息中心"
|
||||
verbose_name_plural = verbose_name
|
||||
ordering = ("-create_datetime",)
|
||||
|
||||
ordering = ("-create_datetime",)
|
|
@ -0,0 +1,105 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from itertools import chain
|
||||
|
||||
from django_restql.fields import DynamicSerializerMethodField
|
||||
from rest_framework.decorators import action, permission_classes
|
||||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||||
|
||||
from dvadmin.system.models import MessageCenter, Users
|
||||
from dvadmin.system.views.role import RoleSerializer
|
||||
from dvadmin.system.views.user import UserSerializer
|
||||
from dvadmin.utils.json_response import SuccessResponse
|
||||
from dvadmin.utils.serializers import CustomModelSerializer
|
||||
from dvadmin.utils.viewset import CustomModelViewSet
|
||||
|
||||
|
||||
class MessageCenterSerializer(CustomModelSerializer):
|
||||
"""
|
||||
消息中心-序列化器
|
||||
"""
|
||||
role_info = DynamicSerializerMethodField()
|
||||
user_info = DynamicSerializerMethodField()
|
||||
def get_role_info(self, instance, parsed_query):
|
||||
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
|
||||
serializer = RoleSerializer(
|
||||
roles,
|
||||
many=True,
|
||||
parsed_query=parsed_query
|
||||
)
|
||||
return serializer.data
|
||||
|
||||
def get_user_info(self, instance, parsed_query):
|
||||
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
|
||||
serializer = UserSerializer(
|
||||
users,
|
||||
many=True,
|
||||
parsed_query=parsed_query
|
||||
)
|
||||
return serializer.data
|
||||
|
||||
class Meta:
|
||||
model = MessageCenter
|
||||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
class MessageCenterCreateSerializer(CustomModelSerializer):
|
||||
"""
|
||||
消息中心-新增-序列化器
|
||||
"""
|
||||
|
||||
def save(self, **kwargs):
|
||||
data = super().save(**kwargs)
|
||||
initial_data = self.initial_data
|
||||
target_type = initial_data.get('target_type')
|
||||
# 在保存之前,根据目标类型,把目标用户查询出来并保存
|
||||
users = initial_data.get('target_user',[])
|
||||
if target_type in [1]:
|
||||
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')
|
||||
users = Users.objects.exclude(is_deleted=True).filter(dept__id__in=target_dept).values_list('id',flat=True)
|
||||
data.save()
|
||||
data.target_user.set(users)
|
||||
return data
|
||||
|
||||
class Meta:
|
||||
model = MessageCenter
|
||||
fields = "__all__"
|
||||
read_only_fields = ["id"]
|
||||
|
||||
|
||||
|
||||
|
||||
class MessageCenterViewSet(CustomModelViewSet):
|
||||
"""
|
||||
消息中心接口
|
||||
list:查询
|
||||
create:新增
|
||||
update:修改
|
||||
retrieve:单例
|
||||
destroy:删除
|
||||
"""
|
||||
queryset = MessageCenter.objects.all()
|
||||
serializer_class = MessageCenterSerializer
|
||||
create_serializer_class = MessageCenterCreateSerializer
|
||||
extra_filter_backends = []
|
||||
|
||||
@action(methods=['GET'],detail=False,permission_classes=[IsAuthenticated])
|
||||
def get_self_receive(self,request):
|
||||
"""
|
||||
获取接收到的消息
|
||||
"""
|
||||
self_user_id = self.request.user.id
|
||||
queryset = MessageCenter.objects.filter(target_user__id=self_user_id)
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
serializer = self.get_serializer(page, many=True, request=request)
|
||||
return self.get_paginated_response(serializer.data)
|
||||
serializer = self.get_serializer(queryset, many=True, request=request)
|
||||
return SuccessResponse(data=serializer.data, msg="获取成功")
|
|
@ -0,0 +1,69 @@
|
|||
import ElementUI from 'element-ui'
|
||||
import util from '@/libs/util'
|
||||
function initWebSocket (e) {
|
||||
const token = util.cookies.get('token')
|
||||
if (token) {
|
||||
const wsUri = 'ws://127.0.0.1:8000/?auth=' + token
|
||||
this.socket = new WebSocket(wsUri)// 这里面的this都指向vue
|
||||
this.socket.onerror = webSocketOnError
|
||||
this.socket.onmessage = webSocketOnMessage
|
||||
this.socket.onclose = closeWebsocket
|
||||
}
|
||||
}
|
||||
|
||||
function webSocketOnError (e) {
|
||||
ElementUI.Notification({
|
||||
title: '',
|
||||
message: 'WebSocket连接发生错误' + JSON.stringify(e),
|
||||
type: 'error',
|
||||
duration: 0
|
||||
})
|
||||
}
|
||||
function webSocketOnMessage (e) {
|
||||
const data = JSON.parse(e.data)
|
||||
if (data.contentType === 'INFO') {
|
||||
ElementUI.Notification({
|
||||
title: 'websocket',
|
||||
message: data.content,
|
||||
type: 'success',
|
||||
position: 'bottom-right',
|
||||
duration: 3000
|
||||
})
|
||||
} else if (data.contentType === 'ERROR') {
|
||||
ElementUI.Notification({
|
||||
title: '',
|
||||
message: data.content,
|
||||
type: 'error',
|
||||
position: 'bottom-right',
|
||||
duration: 0
|
||||
})
|
||||
} else if (data.contentType === 'TEXT') {
|
||||
ElementUI.Notification({
|
||||
title: '温馨提示',
|
||||
message: data.content,
|
||||
type: 'success',
|
||||
position: 'bottom-right',
|
||||
duration: 0
|
||||
})
|
||||
} else {
|
||||
console.log(data.content)
|
||||
}
|
||||
}
|
||||
// 关闭websiocket
|
||||
function closeWebsocket () {
|
||||
console.log('连接已关闭...')
|
||||
close()
|
||||
}
|
||||
function close () {
|
||||
this.socket.close() // 关闭 websocket
|
||||
this.socket.onclose = function (e) {
|
||||
console.log(e)// 监听关闭事件
|
||||
console.log('关闭')
|
||||
}
|
||||
}
|
||||
function webSocketSend (message) {
|
||||
this.socket.send(JSON.stringify(message))
|
||||
}
|
||||
export default {
|
||||
initWebSocket, close, webSocketSend
|
||||
}
|
|
@ -191,6 +191,13 @@ export default {
|
|||
this.showView = true // DOM更新后再通过v-if添加router-view节点
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.$websocket.initWebSocket()
|
||||
},
|
||||
destroyed () {
|
||||
// 离开路由之后断开websocket连接
|
||||
this.$websocket.close()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import { request } from '@/api/service'
|
||||
export const urlPrefix = '/api/system/message_center/'
|
||||
export function GetList (query) {
|
||||
return request({
|
||||
url: urlPrefix,
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取自己接收的消息
|
||||
* @param query
|
||||
* @returns {*}
|
||||
* @constructor
|
||||
*/
|
||||
export function GetSelfReceive (query) {
|
||||
return request({
|
||||
url: urlPrefix + 'get_self_receive/',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
export function GetObj (obj) {
|
||||
return request({
|
||||
url: urlPrefix + obj.id + '/',
|
||||
method: 'get',
|
||||
params: {}
|
||||
})
|
||||
}
|
||||
|
||||
export function AddObj (obj) {
|
||||
return request({
|
||||
url: urlPrefix,
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
|
||||
export function UpdateObj (obj) {
|
||||
return request({
|
||||
url: urlPrefix + obj.id + '/',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
}
|
||||
export function DelObj (id) {
|
||||
return request({
|
||||
url: urlPrefix + id + '/',
|
||||
method: 'delete',
|
||||
data: { id }
|
||||
})
|
||||
}
|
|
@ -0,0 +1,301 @@
|
|||
import { request } from '@/api/service'
|
||||
|
||||
export const crudOptions = (vm) => {
|
||||
return {
|
||||
indexRow: { // 或者直接传true,不显示title,不居中
|
||||
title: '序号',
|
||||
align: 'center'
|
||||
},
|
||||
options: {
|
||||
height: '100%' // 表格高度100%, 使用toolbar必须设置
|
||||
},
|
||||
viewOptions: {
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
sortable: true,
|
||||
width: 100,
|
||||
form: { disabled: true }
|
||||
},
|
||||
{
|
||||
title: '标题',
|
||||
key: 'title',
|
||||
search: {
|
||||
disabled: false
|
||||
},
|
||||
width: 400,
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '必填项'
|
||||
}
|
||||
],
|
||||
component: { span: 24 }
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '目标类型',
|
||||
key: 'target_type',
|
||||
type: 'radio',
|
||||
dict: { data: [{ value: 0, label: '按用户' }, { value: 1, label: '按角色' }, { value: 2, label: '按部门' }] },
|
||||
form: {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: '必选项',
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '目标用户',
|
||||
key: 'target_user',
|
||||
search: {
|
||||
disabled: true
|
||||
},
|
||||
minWidth: 130,
|
||||
type: 'table-selector',
|
||||
dict: {
|
||||
cache: false,
|
||||
url: '/api/system/user/',
|
||||
value: 'id', // 数据字典中value字段的属性名
|
||||
label: 'name', // 数据字典中label字段的属性名
|
||||
getData: (url, dict, {
|
||||
form,
|
||||
component
|
||||
}) => {
|
||||
return request({
|
||||
url: url,
|
||||
params: {
|
||||
page: 1,
|
||||
limit: 10
|
||||
}
|
||||
}).then(ret => {
|
||||
component._elProps.page = ret.data.page
|
||||
component._elProps.limit = ret.data.limit
|
||||
component._elProps.total = ret.data.total
|
||||
return ret.data.data
|
||||
})
|
||||
}
|
||||
},
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '必填项'
|
||||
}
|
||||
],
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
},
|
||||
component: {
|
||||
span: 24,
|
||||
show (context) {
|
||||
return context.form.target_type === 0
|
||||
},
|
||||
pagination: true,
|
||||
props: { multiple: true },
|
||||
elProps: {
|
||||
columns: [
|
||||
{
|
||||
field: 'name',
|
||||
title: '用户名称'
|
||||
},
|
||||
{
|
||||
field: 'phone',
|
||||
title: '用户电话'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
component: {
|
||||
name: 'manyToMany',
|
||||
valueBinding: 'user_info',
|
||||
children: 'name'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '目标角色',
|
||||
key: 'target_role',
|
||||
search: {
|
||||
disabled: true
|
||||
},
|
||||
|
||||
minWidth: 130,
|
||||
type: 'table-selector',
|
||||
dict: {
|
||||
cache: false,
|
||||
url: '/api/system/role/',
|
||||
value: 'id', // 数据字典中value字段的属性名
|
||||
label: 'name', // 数据字典中label字段的属性名
|
||||
getData: (url, dict, {
|
||||
form,
|
||||
component
|
||||
}) => {
|
||||
return request({
|
||||
url: url,
|
||||
params: {
|
||||
page: 1,
|
||||
limit: 10
|
||||
}
|
||||
}).then(ret => {
|
||||
component._elProps.page = ret.data.page
|
||||
component._elProps.limit = ret.data.limit
|
||||
component._elProps.total = ret.data.total
|
||||
return ret.data.data
|
||||
})
|
||||
}
|
||||
},
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '必填项'
|
||||
}
|
||||
],
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
},
|
||||
component: {
|
||||
span: 24,
|
||||
show (context) {
|
||||
return context.form.target_type === 1
|
||||
},
|
||||
pagination: true,
|
||||
props: { multiple: true },
|
||||
elProps: {
|
||||
columns: [
|
||||
{
|
||||
field: 'name',
|
||||
title: '角色名称'
|
||||
},
|
||||
{
|
||||
field: 'key',
|
||||
title: '权限标识'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
component: {
|
||||
name: 'manyToMany',
|
||||
valueBinding: 'role_info',
|
||||
children: 'name'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '目标部门',
|
||||
key: 'target_dept',
|
||||
search: {
|
||||
disabled: true
|
||||
},
|
||||
minWidth: 130,
|
||||
type: 'table-selector',
|
||||
dict: {
|
||||
cache: false,
|
||||
url: '/api/system/dept/',
|
||||
isTree: true,
|
||||
value: 'id', // 数据字典中value字段的属性名
|
||||
label: 'name', // 数据字典中label字段的属性名
|
||||
children: 'children', // 数据字典中children字段的属性名
|
||||
getData: (url, dict, {
|
||||
form,
|
||||
component
|
||||
}) => {
|
||||
return request({
|
||||
url: url,
|
||||
params: {
|
||||
page: 1,
|
||||
limit: 999
|
||||
}
|
||||
}).then(ret => {
|
||||
return ret.data.data
|
||||
})
|
||||
}
|
||||
},
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '必填项'
|
||||
}
|
||||
],
|
||||
itemProps: {
|
||||
class: { yxtInput: true }
|
||||
},
|
||||
component: {
|
||||
span: 24,
|
||||
show (context) {
|
||||
return context.form.target_type === 2
|
||||
},
|
||||
props: {
|
||||
multiple: true,
|
||||
elProps: {
|
||||
treeConfig: {
|
||||
transform: true,
|
||||
rowField: 'id',
|
||||
parentField: 'parent',
|
||||
expandAll: true
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'name',
|
||||
title: '部门名称',
|
||||
treeNode: true
|
||||
},
|
||||
{
|
||||
field: 'status_label',
|
||||
title: '状态'
|
||||
},
|
||||
{
|
||||
field: 'parent_name',
|
||||
title: '父级部门'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
component: {
|
||||
name: 'manyToMany',
|
||||
valueBinding: 'dept_info',
|
||||
children: 'name'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '内容',
|
||||
key: 'content',
|
||||
width: 300,
|
||||
type: 'editor-quill', // 富文本图片上传依赖file-uploader,请先配置好file-uploader
|
||||
form: {
|
||||
rules: [ // 表单校验规则
|
||||
{
|
||||
required: true,
|
||||
message: '必填项'
|
||||
}
|
||||
],
|
||||
component: {
|
||||
disabled: () => {
|
||||
return vm.getEditForm().disable
|
||||
},
|
||||
props: {
|
||||
uploader: {
|
||||
type: 'form' // 上传后端类型【cos,aliyun,oss,form】
|
||||
}
|
||||
},
|
||||
events: {
|
||||
'text-change': (event) => {
|
||||
console.log('text-change:', event)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
<template>
|
||||
<d2-container :class="{'page-compact':crud.pageOptions.compact}">
|
||||
|
||||
<d2-crud-x
|
||||
ref="d2Crud"
|
||||
v-bind="_crudProps"
|
||||
v-on="_crudListeners"
|
||||
@form-component-ready="handleFormComponentReady"
|
||||
>
|
||||
<div slot="header">
|
||||
<crud-search ref="search" :options="crud.searchOptions" @submit="handleSearch" />
|
||||
<el-button size="small" type="primary" @click="addRow"><i class="el-icon-plus"/> 新增</el-button>
|
||||
<el-tabs v-model="tabActivted" @tab-click="onTabClick">
|
||||
<el-tab-pane label="我的发布" name="send"></el-tab-pane>
|
||||
<el-tab-pane label="我的接收" name="receive"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<crud-toolbar :search.sync="crud.searchOptions.show"
|
||||
:compact.sync="crud.pageOptions.compact"
|
||||
:columns="crud.columns"
|
||||
@refresh="doRefresh()"
|
||||
@columns-filter-changed="handleColumnsFilterChanged"/>
|
||||
</div>
|
||||
|
||||
</d2-crud-x>
|
||||
</d2-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { AddObj, GetObj, GetList, UpdateObj, DelObj, GetSelfReceive } from './api'
|
||||
import { crudOptions } from './crud'
|
||||
import { d2CrudPlus } from 'd2-crud-plus'
|
||||
export default {
|
||||
name: 'messageCenter',
|
||||
components: {},
|
||||
mixins: [d2CrudPlus.crud],
|
||||
data () {
|
||||
return {
|
||||
tabActivted: 'send'
|
||||
}
|
||||
},
|
||||
created () {
|
||||
// 配置编辑前获取详情
|
||||
this.crud.options.fetchDetail = this.fetchDetail
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
getCrudOptions () {
|
||||
return crudOptions(this)
|
||||
},
|
||||
pageRequest (query) {
|
||||
if (this.tabActivted === 'receive') {
|
||||
return GetSelfReceive({ ...query })
|
||||
}
|
||||
return GetList(query)
|
||||
},
|
||||
infoRequest (query) {
|
||||
return GetObj(query)
|
||||
},
|
||||
addRequest (row) {
|
||||
return AddObj(row).then(res => {
|
||||
const message = {
|
||||
message_id: res.data.id,
|
||||
contentType: 'TEXT',
|
||||
content: '您有新的消息,请到消息中心查看~'
|
||||
}
|
||||
this.$websocket.webSocketSend(message)
|
||||
})
|
||||
},
|
||||
updateRequest (row) {
|
||||
return UpdateObj(row)
|
||||
},
|
||||
delRequest (row) {
|
||||
return DelObj(row.id)
|
||||
},
|
||||
// 编辑对话框打开前获取详情
|
||||
fetchDetail (index, row) {
|
||||
if (index == null) {
|
||||
// 添加
|
||||
return {}
|
||||
}
|
||||
return GetObj(row).then(res => {
|
||||
return res.data
|
||||
})
|
||||
},
|
||||
handleFormComponentReady (event, key, form) {
|
||||
// console.log('form component ready:', event, key, form)
|
||||
},
|
||||
onTabClick (obj) {
|
||||
this.doRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue