功能变化: 菜单懒加载

treebeard
李强 2022-05-17 13:50:26 +08:00
parent e8404ba8b9
commit dcd39758df
8 changed files with 75 additions and 131 deletions

View File

@ -4,7 +4,7 @@ from rest_framework import routers
from dvadmin.system.views.api_white_list import ApiWhiteListViewSet from dvadmin.system.views.api_white_list import ApiWhiteListViewSet
from dvadmin.system.views.area import AreaViewSet from dvadmin.system.views.area import AreaViewSet
from dvadmin.system.views.button import ButtonViewSet from dvadmin.system.views.button import ButtonViewSet
from dvadmin.system.views.dept import DeptViewSet, DeptQueryViewSet from dvadmin.system.views.dept import DeptViewSet
from dvadmin.system.views.dictionary import DictionaryViewSet from dvadmin.system.views.dictionary import DictionaryViewSet
from dvadmin.system.views.file_list import FileViewSet from dvadmin.system.views.file_list import FileViewSet
from dvadmin.system.views.login_log import LoginLogViewSet from dvadmin.system.views.login_log import LoginLogViewSet
@ -21,7 +21,6 @@ system_url.register(r'button', ButtonViewSet)
system_url.register(r'menu_button', MenuButtonViewSet) system_url.register(r'menu_button', MenuButtonViewSet)
system_url.register(r'role', RoleViewSet) system_url.register(r'role', RoleViewSet)
system_url.register(r'dept', DeptViewSet) system_url.register(r'dept', DeptViewSet)
system_url.register(r'dept_query', DeptQueryViewSet)
system_url.register(r'user', UserViewSet) system_url.register(r'user', UserViewSet)
system_url.register(r'operation_log', OperationLogViewSet) system_url.register(r'operation_log', OperationLogViewSet)
system_url.register(r'dictionary', DictionaryViewSet) system_url.register(r'dictionary', DictionaryViewSet)
@ -45,5 +44,6 @@ urlpatterns = [
path('system_config/get_relation_info/', SystemConfigViewSet.as_view({'get': 'get_relation_info'})), path('system_config/get_relation_info/', SystemConfigViewSet.as_view({'get': 'get_relation_info'})),
path('login_log/', LoginLogViewSet.as_view({'get': 'list'})), path('login_log/', LoginLogViewSet.as_view({'get': 'list'})),
path('login_log/<int:pk>/', LoginLogViewSet.as_view({'get': 'retrieve'})), path('login_log/<int:pk>/', LoginLogViewSet.as_view({'get': 'retrieve'})),
path('dept_lazy_tree/', DeptViewSet.as_view({'get': 'dept_lazy_tree'})),
] ]
urlpatterns += system_url.urls urlpatterns += system_url.urls

View File

@ -8,7 +8,7 @@
from rest_framework import serializers from rest_framework import serializers
from dvadmin.system.models import Dept from dvadmin.system.models import Dept
from dvadmin.utils.json_response import SuccessResponse from dvadmin.utils.json_response import DetailResponse, SuccessResponse
from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.serializers import CustomModelSerializer
from dvadmin.utils.viewset import CustomModelViewSet from dvadmin.utils.viewset import CustomModelViewSet
@ -18,6 +18,10 @@ class DeptSerializer(CustomModelSerializer):
部门-序列化器 部门-序列化器
""" """
parent_name = serializers.CharField(read_only=True, source='parent.name') parent_name = serializers.CharField(read_only=True, source='parent.name')
has_children = serializers.SerializerMethodField()
def get_has_children(self, obj: Dept):
return Dept.objects.filter(parent_id=obj.id).count()
class Meta: class Meta:
model = Dept model = Dept
@ -67,21 +71,34 @@ class DeptViewSet(CustomModelViewSet):
serializer_class = DeptSerializer serializer_class = DeptSerializer
create_serializer_class = DeptCreateUpdateSerializer create_serializer_class = DeptCreateUpdateSerializer
update_serializer_class = DeptCreateUpdateSerializer update_serializer_class = DeptCreateUpdateSerializer
filter_fields = ['name'] filter_fields = ['name', 'id', 'parent']
search_fields = [] search_fields = []
# extra_filter_backends = [] # extra_filter_backends = []
# def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
# queryset = self.filter_queryset(self.get_queryset()) # 如果懒加载,则只返回父级
# page = self.paginate_queryset(queryset) queryset = self.filter_queryset(self.get_queryset())
# if page is not None: lazy = self.request.query_params.get('lazy')
# serializer = self.get_serializer(page, many=True, request=request) parent = self.request.query_params.get('parent')
# return self.get_paginated_response(serializer.data) if lazy:
# serializer = self.get_serializer(queryset, many=True, request=request) # 如果懒加载模式,返回全部
# return SuccessResponse(data=serializer.data, msg="获取成功") if not parent:
queryset = self.queryset.filter(parent__isnull=True)
serializer = self.get_serializer(queryset, many=True, request=request)
return SuccessResponse(data=serializer.data, msg="获取成功")
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="获取成功")
class DeptQueryViewSet(CustomModelViewSet): def dept_lazy_tree(self, request, *args, **kwargs):
queryset = Dept.objects.all() parent = self.request.query_params.get('parent')
serializer_class = DeptQuerySerializer queryset = self.filter_queryset(self.get_queryset())
filter_fields = ['name'] if not parent:
queryset = queryset.filter(parent__isnull=True)
data = queryset.filter(status=True).order_by('sort').values('name', 'id', 'parent')
return DetailResponse(data=data, msg="获取成功")

View File

@ -65,6 +65,9 @@ class InitDictionaryViewSet(APIView):
if dictionary_key: if dictionary_key:
if dictionary_key == 'all': if dictionary_key == 'all':
data = [ele for ele in dispatch.get_dictionary_config().values()] data = [ele for ele in dispatch.get_dictionary_config().values()]
if not data:
dispatch.refresh_dictionary()
data = [ele for ele in dispatch.get_dictionary_config().values()]
else: else:
data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type', data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type',
'color') 'color')

View File

@ -208,4 +208,8 @@ class InitSettingsViewSet(APIView):
permission_classes = [] permission_classes = []
def get(self, request): def get(self, request):
return DetailResponse(data=dispatch.get_system_config()) data = dispatch.get_system_config()
if not data:
dispatch.refresh_system_config()
data = dispatch.get_system_config()
return DetailResponse(data=data)

1
web/.gitignore vendored
View File

@ -2,6 +2,7 @@
node_modules node_modules
/dist /dist
package-lock.json package-lock.json
yarn.lock
# local env files # local env files
.env.local .env.local
.env.*.local .env.*.local

View File

@ -1,5 +1,4 @@
import { request } from '@/api/service' import { request } from '@/api/service'
import XEUtils from 'xe-utils'
export const urlPrefix = '/api/system/dept/' export const urlPrefix = '/api/system/dept/'
/** /**
@ -11,15 +10,9 @@ export function GetList (query) {
url: urlPrefix, url: urlPrefix,
method: 'get', method: 'get',
params: query params: query
}).then((res) => {
// 将列表数据转换为树形数据
res.data.data = XEUtils.toArrayTree(res.data.data, {
parentKey: 'parent',
strict: false
})
return res
}) })
} }
/** /**
* 新增 * 新增
*/ */
@ -41,6 +34,7 @@ export function UpdateObj (obj) {
data: obj data: obj
}) })
} }
/** /**
* 删除 * 删除
*/ */
@ -52,97 +46,13 @@ export function DelObj (id) {
}) })
} }
export function GetTreeChildrenByParentId (parentId) { /**
return TreeNodesLazyLoader.getChildren(parentId) * 部门懒加载
} */
export function DeptLazy (query) {
export function GetNodesByValues (values) { return request({
return TreeNodesLazyLoader.getNodesByValues(values) url: '/api/system/dept_lazy_tree/',
} method: 'get',
params: query
const getPcasData = request({
url: '/api/system/dept_query/',
method: 'get'
}).then((res) => {
// 将列表数据转换为树形数据
res.data.data = XEUtils.toArrayTree(res.data.data, {
parentKey: 'parent',
strict: false
}) })
return res.data.data
})
export default getPcasData
export const TreeNodesLazyLoader = {
getNodesByValues (values) {
// console.log("getNodesByValues", values);
if (!(values instanceof Array)) {
values = [values]
}
return getPcasData.then((data) => {
const nodes = []
for (const value of values) {
const found = this.getNode(data, value)
if (found) {
nodes.push(found)
}
}
return nodes
})
},
getNode (list, value) {
for (const item of list) {
if (item.code === value) {
return item
}
if (item.children && item.children.length > 0) {
const found = this.getNode(item.children, value)
if (found) {
return found
}
}
}
},
getChildren (parent) {
return getPcasData.then((data) => {
const list = this.getChildrenByParent(parent, data)
if (list == null) {
return []
}
return this.cloneAndDeleteChildren(list)
})
},
getChildrenByParent (parentId, tree) {
if (!parentId) {
// 取第一级
return tree
} else {
for (const node of tree) {
if (node.code === parentId) {
return node.children
}
if (node.children && node.children.length > 0) {
// 递归查找
const list = this.getChildrenByParent(parentId, node.children)
if (list) {
return list
}
}
}
}
},
cloneAndDeleteChildren (list) {
const newList = []
for (const node of list) {
const newNode = {}
Object.assign(newNode, node)
if (newNode.children == null || newNode.children.length === 0) {
newNode.isLeaf = true
newNode.leaf = true
}
delete newNode.children
newList.push(newNode)
}
// console.log("found children:", newList);
return newList
}
} }

View File

@ -1,4 +1,4 @@
import * as Api from './api' import * as api from './api'
export const crudOptions = (vm) => { export const crudOptions = (vm) => {
return { return {
// pagination: false, // pagination: false,
@ -13,7 +13,14 @@ export const crudOptions = (vm) => {
highlightCurrentRow: false, highlightCurrentRow: false,
defaultExpandAll: true, defaultExpandAll: true,
treeConfig: { treeConfig: {
lazy: true lazy: true,
hasChild: 'has_children',
loadMethod: ({ row }) => {
return api.GetList({ parent: row.id, lazy: true }).then(ret => {
return ret.data.data
})
},
iconLoaded: 'el-icon-loading' // 美化loading图标
} }
}, },
rowHandle: { rowHandle: {
@ -94,10 +101,17 @@ export const crudOptions = (vm) => {
dict: { dict: {
isTree: true, isTree: true,
label: 'name', label: 'name',
value: 'code', value: 'id',
getNodes (values) { cache: false,
getData: (url, dict, { form, component }) => { // 配置此参数会覆盖全局的getRemoteDictFunc
return api.DeptLazy().then(ret => { return ret.data })
},
getNodes (values, data) {
// 配置行展示远程获取nodes // 配置行展示远程获取nodes
return Api.GetNodesByValues(values) return new Promise((resolve, reject) => {
const row = vm.getEditRow()
resolve(row.parent !== null ? [{ name: row.parent_name, id: row.parent }] : [])
})
} }
}, },
form: { form: {
@ -108,17 +122,11 @@ export const crudOptions = (vm) => {
multiple: false, multiple: false,
elProps: { elProps: {
lazy: true, lazy: true,
hasChild: 'has_children',
load (node, resolve) { load (node, resolve) {
// 懒加载 // 懒加载
// console.log("懒加载"); api.DeptLazy({ parent: node.data.id }).then((data) => {
if (node.level === 0) { resolve(data.data)
Api.GetTreeChildrenByParentId().then((data) => {
resolve(data)
})
return
}
Api.GetTreeChildrenByParentId(node.data.code).then((data) => {
resolve(data)
}) })
} }
} }

View File

@ -44,6 +44,7 @@ export default {
return crudOptions(this) return crudOptions(this)
}, },
pageRequest (query) { pageRequest (query) {
query.lazy = true
return api.GetList(query) return api.GetList(query)
}, },
addRequest (row) { addRequest (row) {