From 139cdf7a7afa4c767ebe4ebda4e8c47d855b5bb2 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 27 Feb 2025 11:58:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=A4=87=E6=B3=A8=E5=AD=97=E6=AE=B5=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/AICode.cmd | 7 +- src/main/resources/config/application-dev.yml | 1 - .../resources/config/liquibase/data/menu.csv | 5 +- .../webapp/app/admin/menu/menu.component.ts | 99 ++++++++++++++++--- src/main/webapp/app/admin/menu/menu.vue | 85 +++++++++------- .../app/shared/config/config-bootstrap-vue.ts | 2 + src/main/webapp/i18n/zh-cn/menu.json | 20 ++++ 7 files changed, 171 insertions(+), 48 deletions(-) create mode 100644 src/main/webapp/i18n/zh-cn/menu.json diff --git a/doc/AICode.cmd b/doc/AICode.cmd index 054ca1d..6a7a42d 100644 --- a/doc/AICode.cmd +++ b/doc/AICode.cmd @@ -26,6 +26,10 @@ MySQL数据库要求如下: 99. 请将项目前端和后端 打包生成一个运行jar包 + docker: + compose: + enabled: false + 重新启动项目 .\mvnw clean spring-boot:run npm run webapp:build && npm start @@ -47,4 +51,5 @@ java -jar target/jewpms-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev 请初始化git 连接到远程仓库 https://gitea.vxnet.cn/admingit/jewpms.git -提交更新项目代码 \ No newline at end of file +提交更新项目代码 +请修正此问题 \ No newline at end of file diff --git a/src/main/resources/config/application-dev.yml b/src/main/resources/config/application-dev.yml index d0d6e0e..81b7f39 100644 --- a/src/main/resources/config/application-dev.yml +++ b/src/main/resources/config/application-dev.yml @@ -48,7 +48,6 @@ spring: thymeleaf: cache: false docker: - enabled: false compose: enabled: false diff --git a/src/main/resources/config/liquibase/data/menu.csv b/src/main/resources/config/liquibase/data/menu.csv index 9fad78e..b004b7c 100644 --- a/src/main/resources/config/liquibase/data/menu.csv +++ b/src/main/resources/config/liquibase/data/menu.csv @@ -1,5 +1,5 @@ id,name,path,icon,parent_id,order_num,component,is_frame,visible,status,perms,query,remark,menu_type,createtime,updatetime,lastmodby,version -1,系统管理,/system,system,null,1,null,false,true,0,null,null,系统管理目录,M,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 +1,系统管理,/system,users-cog,null,1,null,false,true,0,null,null,系统管理目录,M,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 2,用户管理,/system/user,user,1,1,/system/user/index,false,true,0,system:user:list,null,用户管理菜单,C,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 3,角色管理,/system/role,peoples,1,2,/system/role/index,false,true,0,system:role:list,null,角色管理菜单,C,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 4,菜单管理,/system/menu,tree-table,1,3,/system/menu/index,false,true,0,system:menu:list,null,菜单管理菜单,C,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 @@ -14,4 +14,5 @@ id,name,path,icon,parent_id,order_num,component,is_frame,visible,status,perms,qu 13,菜单查询,/system/menu/query,null,4,1,null,false,true,0,system:menu:query,null,菜单查询按钮,F,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 14,菜单新增,/system/menu/add,null,4,2,null,false,true,0,system:menu:add,null,菜单新增按钮,F,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 15,菜单修改,/system/menu/edit,null,4,3,null,false,true,0,system:menu:edit,null,菜单修改按钮,F,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 -16,菜单删除,/system/menu/remove,null,4,4,null,false,true,0,system:menu:remove,null,菜单删除按钮,F,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 \ No newline at end of file +16,菜单删除,/system/menu/remove,null,4,4,null,false,true,0,system:menu:remove,null,菜单删除按钮,F,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 +17,首页,/home,home,null,0,/home/index,false,true,0,null,null,系统首页,C,2024-01-01 00:00:00,2024-01-01 00:00:00,admin,0 \ No newline at end of file diff --git a/src/main/webapp/app/admin/menu/menu.component.ts b/src/main/webapp/app/admin/menu/menu.component.ts index 45d9f9c..f167000 100644 --- a/src/main/webapp/app/admin/menu/menu.component.ts +++ b/src/main/webapp/app/admin/menu/menu.component.ts @@ -3,6 +3,7 @@ import { useI18n } from 'vue-i18n'; import { useVuelidate } from '@vuelidate/core'; import { required } from '@vuelidate/validators'; import axios from 'axios'; +import type { BTableField } from 'bootstrap-vue'; export default defineComponent({ name: 'Menu', @@ -14,6 +15,66 @@ export default defineComponent({ const removeId = ref(null); const dialogTitle = ref(''); + const fields: BTableField[] = [ + { key: 'name', label: t('jewpmsApp.menu.name'), sortable: true }, + { key: 'path', label: t('jewpmsApp.menu.path'), sortable: true }, + { key: 'icon', label: t('jewpmsApp.menu.icon') }, + { key: 'sort', label: t('jewpmsApp.menu.sort'), sortable: true }, + { key: 'visible', label: t('jewpmsApp.menu.visible'), sortable: true }, + { key: 'remark', label: t('jewpmsApp.menu.remark'), sortable: true }, + { key: 'actions', label: t('jewpmsApp.menu.actions') }, + ]; + + const treeMenus = computed(() => { + const buildTree = (items: any[], parentId: string | null = null, level = 0) => { + return items + .filter(item => item.parentId === parentId) + .map(item => { + const children = buildTree(items, item.id, level + 1); + return { + ...item, + _showChildren: children.length > 0, + _level: level, + _expanded: false, + children: children, + }; + }) + .sort((a, b) => a.sort - b.sort); + }; + return buildTree(menus.value); + }); + + const toggleChildren = (item: any) => { + item._expanded = !item._expanded; + if (item._expanded) { + item.children.forEach((child: any) => { + const index = menus.value.findIndex(m => m.id === child.id); + if (index > -1) { + menus.value.splice(index + 1, 0, { ...child, _level: item._level + 1 }); + } + }); + } else { + const removeChildren = (parent: any) => { + if (parent.children) { + parent.children.forEach((child: any) => { + const index = menus.value.findIndex(m => m.id === child.id); + if (index > -1) { + menus.value.splice(index, 1); + if (child._expanded) { + removeChildren(child); + } + } + }); + } + }; + removeChildren(item); + } + }; + + const rowClass = (item: any) => { + return item._level > 0 ? `tree-level-${item._level}` : ''; + }; + const menu = ref({ id: null, name: '', @@ -21,6 +82,8 @@ export default defineComponent({ icon: '', parentId: '', sort: 0, + visible: true, + remark: '', createtime: null, updatetime: null, lastmodby: '', @@ -36,7 +99,7 @@ export default defineComponent({ const loadAll = async () => { try { isFetching.value = true; - const res = await axios.get('/api/menus'); + const res = await axios.get('api/menus/tree'); menus.value = res.data; loadParentMenus(); } catch (err) { @@ -68,21 +131,28 @@ export default defineComponent({ icon: '', parentId: '', sort: 0, + visible: true, + remark: '', createtime: null, updatetime: null, lastmodby: '', version: 0, }; - const modal = document.getElementById('editDialog'); + // 使用$refs访问b-modal组件 + const modal = document.querySelector('#editDialog___BV_modal_content_'); if (modal) { - modal.style.display = 'block'; + modal.parentElement.parentElement.style.display = 'block'; + modal.parentElement.parentElement.classList.add('show'); + document.body.classList.add('modal-open'); } }; const closeDialog = () => { - const modal = document.getElementById('editDialog'); + const modal = document.querySelector('#editDialog___BV_modal_content_'); if (modal) { - modal.style.display = 'none'; + modal.parentElement.parentElement.style.display = 'none'; + modal.parentElement.parentElement.classList.remove('show'); + document.body.classList.remove('modal-open'); } }; @@ -91,15 +161,18 @@ export default defineComponent({ menu.value = { ...menuItem }; const modal = document.getElementById('editDialog'); if (modal) { - modal.style.display = 'block'; + modal.show(); } }; const prepareDelete = menuItem => { removeId.value = menuItem.id; - const modal = document.getElementById('removeDialog'); + menu.value = menuItem; + const modal = document.querySelector('#deleteDialog___BV_modal_content_'); if (modal) { - modal.style.display = 'block'; + modal.parentElement.parentElement.style.display = 'block'; + modal.parentElement.parentElement.classList.add('show'); + document.body.classList.add('modal-open'); } }; @@ -109,9 +182,9 @@ export default defineComponent({ if (!isValid) return; if (menu.value.id) { - await axios.put(`/api/menus/${menu.value.id}`, menu.value); + await axios.put(`api/menus/${menu.value.id}`, menu.value); } else { - await axios.post('/api/menus', menu.value); + await axios.post('api/menus', menu.value); } closeDialog(); @@ -123,7 +196,7 @@ export default defineComponent({ const removeMenu = async () => { try { - await axios.delete(`/api/menus/${removeId.value}`); + await axios.delete(`api/menus/${removeId.value}`); closeDialog(); loadAll(); } catch (err) { @@ -149,7 +222,11 @@ export default defineComponent({ prepareDelete, save, removeMenu, + deleteMenu: removeMenu, // 添加deleteMenu方法的引用 getParentName, + treeMenus, + fields, + rowClass, }; }, }); diff --git a/src/main/webapp/app/admin/menu/menu.vue b/src/main/webapp/app/admin/menu/menu.vue index 0d7495a..dd32530 100644 --- a/src/main/webapp/app/admin/menu/menu.vue +++ b/src/main/webapp/app/admin/menu/menu.vue @@ -19,39 +19,48 @@
- - - - - - - - - - - - - - - - - - - - - -
{{ menu.name }}{{ menu.path }}{{ getParentName(menu.parentId) }}{{ menu.sort }} -
- - -
-
+ + + + + + + + + +
@@ -79,6 +88,16 @@ +
+ + + {{ $t('jewpmsApp.menu.visibleHint') }} + +
+
+ + +
diff --git a/src/main/webapp/app/shared/config/config-bootstrap-vue.ts b/src/main/webapp/app/shared/config/config-bootstrap-vue.ts index 1a550cc..379b76e 100644 --- a/src/main/webapp/app/shared/config/config-bootstrap-vue.ts +++ b/src/main/webapp/app/shared/config/config-bootstrap-vue.ts @@ -23,6 +23,7 @@ import { BPagination, BProgress, BProgressBar, + BTable, ToastPlugin, VBModal, } from 'bootstrap-vue'; @@ -48,6 +49,7 @@ export function initBootstrapVue(vue) { vue.component('b-form-group', BFormGroup); vue.component('b-form-checkbox', BFormCheckbox); vue.component('b-collapse', BCollapse); + vue.component('b-table', BTable); vue.component('b-nav-item', BNavItem); vue.component('b-nav-item-dropdown', BNavItemDropdown); vue.component('b-modal', BModal); diff --git a/src/main/webapp/i18n/zh-cn/menu.json b/src/main/webapp/i18n/zh-cn/menu.json new file mode 100644 index 0000000..28fb443 --- /dev/null +++ b/src/main/webapp/i18n/zh-cn/menu.json @@ -0,0 +1,20 @@ +{ + "jewpmsApp": { + "menu": { + "home": { + "title": "菜单管理", + "createLabel": "创建新菜单", + "editLabel": "编辑菜单", + "deleteLabel": "删除菜单", + "refreshListLabel": "刷新列表" + }, + "name": "名称", + "path": "路径", + "icon": "图标", + "sort": "排序", + "visible": "可见性", + "remark": "备注", + "actions": "操作" + } + } +}