From f89a5228cd6a20b086d7784f65c5168ad1c9b99e Mon Sep 17 00:00:00 2001 From: H0nGzA1 <2505811377@qq.com> Date: Thu, 30 Mar 2023 15:37:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E7=AE=A1=E7=90=86=E9=87=8D=E6=9E=84=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/views/menu.py | 18 +- web/src/views/system/menu/api.ts | 31 +- .../menu/components/menuButton/curd.tsx | 367 +++++++++--------- .../menu/components/menuButton/index.vue | 112 +++--- web/src/views/system/menu/index.vue | 144 +++++-- web/src/views/system/user/crud.tsx | 2 +- web/src/views/system/user/index.vue | 6 +- 7 files changed, 409 insertions(+), 271 deletions(-) diff --git a/backend/dvadmin/system/views/menu.py b/backend/dvadmin/system/views/menu.py index 3566dde..527ee7e 100644 --- a/backend/dvadmin/system/views/menu.py +++ b/backend/dvadmin/system/views/menu.py @@ -112,6 +112,18 @@ class MenuViewSet(CustomModelViewSet): data = serializer.data return SuccessResponse(data=data, total=len(data), msg="获取成功") + @action(methods=['POST'], detail=False, permission_classes=[]) + def drag_menu(self, request): + """前端拖拽菜单之后重写parent""" + menu_id = request.data['menu_id'] + parent_id = request.data['parent_id'] + print(parent_id) + menu = Menu.objects.get(id=menu_id) + menu.parent_id = parent_id + menu.save() + + return SuccessResponse(data=[], msg="拖拽菜单成功") + def list(self, request): """懒加载""" request.query_params._mutable = True @@ -125,11 +137,11 @@ class MenuViewSet(CustomModelViewSet): del params['limit'] if params: if parent: - queryset = self.queryset.filter(status=1, parent=parent) + queryset = self.queryset.filter(parent=parent) else: - queryset = self.queryset.filter(status=1) + queryset = self.queryset.filter() else: - queryset = self.queryset.filter(status=1, parent__isnull=True) + queryset = self.queryset.filter(parent__isnull=True) queryset = self.filter_queryset(queryset) serializer = MenuSerializer(queryset, many=True, request=request) data = serializer.data diff --git a/web/src/views/system/menu/api.ts b/web/src/views/system/menu/api.ts index 8dbaf69..08d08ee 100644 --- a/web/src/views/system/menu/api.ts +++ b/web/src/views/system/menu/api.ts @@ -9,13 +9,6 @@ export function GetList(query: PageQuery) { params: query, }); } -export function GetAllMenu(query: PageQuery) { - return request({ - url: apiPrefix + 'get_all_menu/', - method: 'get', - params: query, - }); -} export function GetObj(id: InfoReq) { return request({ @@ -46,3 +39,27 @@ export function DelObj(obj: DelReq) { method: 'delete', }); } + +export function GetAllMenu(query: PageQuery) { + return request({ + url: apiPrefix + 'get_all_menu/', + method: 'get', + params: query, + }); +} + +export function lazyLoadMenu(query: PageQuery) { + return request({ + url: apiPrefix, + method: 'get', + params: query, + }); +} + +export function dragMenu(obj: AddReq) { + return request({ + url: apiPrefix + 'drag_menu/', + method: 'post', + data: obj, + }); +} diff --git a/web/src/views/system/menu/components/menuButton/curd.tsx b/web/src/views/system/menu/components/menuButton/curd.tsx index 40ed2b6..7e42c5d 100644 --- a/web/src/views/system/menu/components/menuButton/curd.tsx +++ b/web/src/views/system/menu/components/menuButton/curd.tsx @@ -1,186 +1,195 @@ -import {CrudOptions, AddReq, DelReq, EditReq, dict, CrudExpose} from '@fast-crud/fast-crud'; +import { CrudOptions, AddReq, DelReq, EditReq, dict, CrudExpose } from '@fast-crud/fast-crud'; import _ from 'lodash-es'; -import * as api from "./api"; -import {dictionary} from '/@/utils/dictionary'; +import * as api from './api'; +import { dictionary } from '/@/utils/dictionary'; interface CreateCrudOptionsTypes { - crudOptions: CrudOptions; + crudOptions: CrudOptions; } -import {request} from '/@/utils/service'; +import { request } from '/@/utils/service'; //此处为crudOptions配置 -export const createCrudOptions = function ({ - crudExpose, - selectOptions - }: { crudExpose: CrudExpose, selectOptions: any }): CreateCrudOptionsTypes { - - const pageRequest = async (query: any) => { - return await api.GetList({ menu: selectOptions.value.id}); - }; - const editRequest = async ({form, row}: EditReq) => { - form.id = row.id; - return await api.UpdateObj(form); - }; - const delRequest = async ({row}: DelReq) => { - return await api.DelObj(row.id); - }; - const addRequest = async ({form}: AddReq) => { - return await api.AddObj(form); - }; - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest, - }, - form: { - col: {span: 24}, - labelWidth: '100px', - wrapper: { - is: 'el-dialog', - width: '600px', - }, - }, - columns: { - _index: { - title: '序号', - form: {show: false}, - column: { - //type: 'index', - align: 'center', - width: '70px', - columnSetDisabled: true, //禁止在列设置中选择 - }, - }, - search: { - title: '关键词', - column: {show: false}, - type: 'text', - search: {show: true}, - form: { - show: false, - component: { - placeholder: '输入关键词搜索', - }, - }, - }, - id: { - title: 'ID', - type: 'text', - column: {show: false}, - search: {show: false}, - form: {show: false}, - }, - name: { - title: '权限名称', - type: 'text', - search: {show: true}, - column: { - minWidth: 120, - sortable: true, - }, - form: { - rules: [{required: true, message: '权限名称必填'}], - component: { - placeholder: '输入权限名称搜索', - props: { - clearable: true, - allowCreate: true, - filterable: true, - - } - }, - helper: { - render (h) { - return (< el-alert title="手动输入" type="warning" description="页面中按钮的名称或者自定义一个名称"/> - ) - } - } - }, - }, - value: { - title: '权限值', - type: 'text', - search: {show: false}, - column: { - width: 120, - sortable: true, - }, - form: { - rules: [{required: true, message: '权限标识必填'}], - placeholder: '输入权限标识', - helper: { - render (h) { - return (< el-alert title="唯一值" type="warning" description="用于判断前端按钮权限或接口权限"/> - ) - } - } - }, - - }, - method: { - title: '请求方式', - search: {show: false}, - type: 'dict-select', - column: { - width: 120, - sortable: true, - }, - dict: dict({ - data: [ - {label: 'GET', value: 0}, - {label: 'POST', value: 1, color: 'success'}, - {label: 'PUT', value: 2, color: 'warning'}, - {label: 'DELETE', value: 3, color: 'danger'} - ] - }), - form:{ - rules: [{required: true, message: '必填项'}], - } - }, - api: { - title: '接口地址', - search: {show: false}, - type: 'dict-select', - dict: dict({ - getData() { - return request({url: '/swagger.json'}).then((res: any) => { - const ret = Object.keys(res.paths) - const data = [] - for (const item of ret) { - const obj: any = {} - obj.label = item - obj.value = item - data.push(obj) - } - return data - }) - } - }), - column: { - minWidth: 200, - sortable: true, - }, - form: { - rules: [{required: true, message: '必填项'}], - component:{ - props:{ - allowCreate: true, - filterable: true, - clearable: true - } - }, - helper: { - render (h) { - return (< el-alert title="请正确填写,以免请求时被拦截。匹配单例使用正则,例如:/api/xx/.*?/" type="warning" /> - ) - } - } - }, - } - }, - }, - }; +export const createCrudOptions = function ({ crudExpose, selectOptions }: { crudExpose: CrudExpose; selectOptions: any }): CreateCrudOptionsTypes { + const pageRequest = async (query: any) => { + return await api.GetList({ menu: selectOptions.value.id } as any); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; + return { + crudOptions: { + rowHandle: { + //固定右侧 + fixed: 'right', + width: 200, + buttons: { + view: { + show: false, + }, + edit: { + iconRight: 'Edit', + type: 'text', + }, + remove: { + iconRight: 'Delete', + type: 'text', + }, + }, + }, + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + form: { + col: { span: 24 }, + labelWidth: '100px', + wrapper: { + is: 'el-dialog', + width: '600px', + }, + }, + columns: { + _index: { + title: '序号', + form: { show: false }, + column: { + type: 'index', + align: 'center', + width: '70px', + columnSetDisabled: true, //禁止在列设置中选择 + }, + }, + search: { + title: '关键词', + column: { show: false }, + type: 'text', + search: { show: true }, + form: { + show: false, + component: { + placeholder: '输入关键词搜索', + }, + }, + }, + id: { + title: 'ID', + type: 'text', + column: { show: false }, + search: { show: false }, + form: { show: false }, + }, + name: { + title: '权限名称', + type: 'text', + search: { show: true }, + column: { + minWidth: 120, + sortable: true, + }, + form: { + rules: [{ required: true, message: '权限名称必填' }], + component: { + placeholder: '输入权限名称搜索', + props: { + clearable: true, + allowCreate: true, + filterable: true, + }, + }, + helper: { + render(h) { + return ; + }, + }, + }, + }, + value: { + title: '权限值', + type: 'text', + search: { show: false }, + column: { + width: 120, + sortable: true, + }, + form: { + rules: [{ required: true, message: '权限标识必填' }], + placeholder: '输入权限标识', + helper: { + render(h) { + return ; + }, + }, + }, + }, + method: { + title: '请求方式', + search: { show: false }, + type: 'dict-select', + column: { + width: 120, + sortable: true, + }, + dict: dict({ + data: [ + { label: 'GET', value: 0 }, + { label: 'POST', value: 1, color: 'success' }, + { label: 'PUT', value: 2, color: 'warning' }, + { label: 'DELETE', value: 3, color: 'danger' }, + ], + }), + form: { + rules: [{ required: true, message: '必填项' }], + }, + }, + api: { + title: '接口地址', + search: { show: false }, + type: 'dict-select', + dict: dict({ + getData() { + return request({ url: '/swagger.json' }).then((res: any) => { + const ret = Object.keys(res.paths); + const data = []; + for (const item of ret) { + const obj: any = {}; + obj.label = item; + obj.value = item; + data.push(obj); + } + return data; + }); + }, + }), + column: { + minWidth: 200, + sortable: true, + }, + form: { + rules: [{ required: true, message: '必填项' }], + component: { + props: { + allowCreate: true, + filterable: true, + clearable: true, + }, + }, + helper: { + render(h) { + return ; + }, + }, + }, + }, + }, + }, + }; }; diff --git a/web/src/views/system/menu/components/menuButton/index.vue b/web/src/views/system/menu/components/menuButton/index.vue index 4e58964..b65410b 100644 --- a/web/src/views/system/menu/components/menuButton/index.vue +++ b/web/src/views/system/menu/components/menuButton/index.vue @@ -1,69 +1,83 @@ - - - 当前菜单: - {{ selectOptions.name }} - - - - - - - - - - + + + + 当前菜单: + {{ selectOptions.name }} + + + + + + + + diff --git a/web/src/views/system/menu/index.vue b/web/src/views/system/menu/index.vue index 88769b5..10e4595 100644 --- a/web/src/views/system/menu/index.vue +++ b/web/src/views/system/menu/index.vue @@ -16,11 +16,19 @@ :data="data" :props="treeProps" :filter-node-method="filterNode" + :load="loadNode" + :allow-drag="allowDrag" + :allow-drop="allowDrop" + @node-drop="nodeDrop" + lazy + icon="ArrowRightBold" + :indent="12" + draggable @node-click="handleNodeClick" > - {{ node.label }} - {{ node.label }} + {{ node.label }} + {{ node.label }} @@ -28,6 +36,7 @@ + 菜单配置 @@ -36,7 +45,7 @@ - + @@ -71,16 +80,13 @@ - - + + 全选 - - - - - - + + + 其他权限 @@ -102,16 +108,15 @@ +