功能变化: 菜单懒加载

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.area import AreaViewSet
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.file_list import FileViewSet
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'role', RoleViewSet)
system_url.register(r'dept', DeptViewSet)
system_url.register(r'dept_query', DeptQueryViewSet)
system_url.register(r'user', UserViewSet)
system_url.register(r'operation_log', OperationLogViewSet)
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('login_log/', LoginLogViewSet.as_view({'get': 'list'})),
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

View File

@ -8,7 +8,7 @@
from rest_framework import serializers
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.viewset import CustomModelViewSet
@ -18,6 +18,10 @@ class DeptSerializer(CustomModelSerializer):
部门-序列化器
"""
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:
model = Dept
@ -67,21 +71,34 @@ class DeptViewSet(CustomModelViewSet):
serializer_class = DeptSerializer
create_serializer_class = DeptCreateUpdateSerializer
update_serializer_class = DeptCreateUpdateSerializer
filter_fields = ['name']
filter_fields = ['name', 'id', 'parent']
search_fields = []
# extra_filter_backends = []
# def list(self, request, *args, **kwargs):
# queryset = self.filter_queryset(self.get_queryset())
# 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="获取成功")
def list(self, request, *args, **kwargs):
# 如果懒加载,则只返回父级
queryset = self.filter_queryset(self.get_queryset())
lazy = self.request.query_params.get('lazy')
parent = self.request.query_params.get('parent')
if lazy:
# 如果懒加载模式,返回全部
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):
queryset = Dept.objects.all()
serializer_class = DeptQuerySerializer
filter_fields = ['name']
def dept_lazy_tree(self, request, *args, **kwargs):
parent = self.request.query_params.get('parent')
queryset = self.filter_queryset(self.get_queryset())
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 == 'all':
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:
data = self.queryset.filter(parent__value=dictionary_key, status=True).values('label', 'value', 'type',
'color')

View File

@ -208,4 +208,8 @@ class InitSettingsViewSet(APIView):
permission_classes = []
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
/dist
package-lock.json
yarn.lock
# local env files
.env.local
.env.*.local

View File

@ -1,5 +1,4 @@
import { request } from '@/api/service'
import XEUtils from 'xe-utils'
export const urlPrefix = '/api/system/dept/'
/**
@ -11,15 +10,9 @@ export function GetList (query) {
url: urlPrefix,
method: 'get',
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
})
}
/**
* 删除
*/
@ -52,97 +46,13 @@ export function DelObj (id) {
})
}
export function GetTreeChildrenByParentId (parentId) {
return TreeNodesLazyLoader.getChildren(parentId)
}
export function GetNodesByValues (values) {
return TreeNodesLazyLoader.getNodesByValues(values)
}
const getPcasData = request({
url: '/api/system/dept_query/',
method: 'get'
}).then((res) => {
// 将列表数据转换为树形数据
res.data.data = XEUtils.toArrayTree(res.data.data, {
parentKey: 'parent',
strict: false
/**
* 部门懒加载
*/
export function DeptLazy (query) {
return request({
url: '/api/system/dept_lazy_tree/',
method: 'get',
params: query
})
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) => {
return {
// pagination: false,
@ -13,7 +13,14 @@ export const crudOptions = (vm) => {
highlightCurrentRow: false,
defaultExpandAll: true,
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: {
@ -94,10 +101,17 @@ export const crudOptions = (vm) => {
dict: {
isTree: true,
label: 'name',
value: 'code',
getNodes (values) {
value: 'id',
cache: false,
getData: (url, dict, { form, component }) => { // 配置此参数会覆盖全局的getRemoteDictFunc
return api.DeptLazy().then(ret => { return ret.data })
},
getNodes (values, data) {
// 配置行展示远程获取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: {
@ -108,17 +122,11 @@ export const crudOptions = (vm) => {
multiple: false,
elProps: {
lazy: true,
hasChild: 'has_children',
load (node, resolve) {
// 懒加载
// console.log("懒加载");
if (node.level === 0) {
Api.GetTreeChildrenByParentId().then((data) => {
resolve(data)
})
return
}
Api.GetTreeChildrenByParentId(node.data.code).then((data) => {
resolve(data)
api.DeptLazy({ parent: node.data.id }).then((data) => {
resolve(data.data)
})
}
}

View File

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