feat: 搭建后台管理框架
This commit is contained in:
1 parent
6d28bab72b
commit
40546bfd01
238 files changed
+18160
-3837
No files matched your search
@@ -5,38 +5,102 @@ import { useRbac } from '../../../stores/rbac'
|
||||
import router, { registerCustomMenu } from '../../../router'
|
||||
|
||||
const builtInMenus = [
|
||||
{ id: 'builtin-content', label: '内容管理', children: [
|
||||
{ id: 'builtin-dramas', label: '短剧管理', route: '/dramas', permission: '查看短剧列表' },
|
||||
{ id: 'builtin-episodes', label: '剧集管理', route: '/episodes', permission: '查看剧集列表' },
|
||||
] },
|
||||
{ id: 'builtin-admin', label: '后台管理', children: [
|
||||
{ id: 'builtin-access', label: '角色权限配置', route: '/access', permission: '角色与权限配置' },
|
||||
{ id: 'builtin-users', label: '管理员用户列表', route: '/admin-users', permission: '管理员用户列表' },
|
||||
{ id: 'builtin-menus', label: '菜单管理', route: '/menus', permission: '菜单管理' },
|
||||
{ id: 'builtin-categories', label: '角色分类', route: '/role-categories', permission: '角色分类管理' },
|
||||
] },
|
||||
{
|
||||
id: 'builtin-content',
|
||||
label: '内容管理',
|
||||
children: [
|
||||
{
|
||||
id: 'builtin-dramas',
|
||||
label: '短剧管理',
|
||||
route: '/content/dramas',
|
||||
permission: '查看短剧列表'
|
||||
},
|
||||
{
|
||||
id: 'builtin-episodes',
|
||||
label: '剧集管理',
|
||||
route: '/content/episodes',
|
||||
permission: '查看剧集列表'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'builtin-admin',
|
||||
label: '后台管理',
|
||||
children: [
|
||||
{
|
||||
id: 'builtin-access',
|
||||
label: '角色权限配置',
|
||||
route: '/system/access',
|
||||
permission: '角色与权限配置'
|
||||
},
|
||||
{
|
||||
id: 'builtin-users',
|
||||
label: '管理员用户列表',
|
||||
route: '/system/admin-users',
|
||||
permission: '管理员用户列表'
|
||||
},
|
||||
{ id: 'builtin-menus', label: '菜单管理', route: '/system/menus', permission: '菜单管理' },
|
||||
{
|
||||
id: 'builtin-categories',
|
||||
label: '角色分类',
|
||||
route: '/system/role-categories',
|
||||
permission: '角色分类管理'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
function buildCustomNodes(parent) {
|
||||
return customMenus.filter(menu => (menu.parent || '后台管理') === parent).map(menu => ({
|
||||
id: menu.key,
|
||||
label: menu.title,
|
||||
menu,
|
||||
children: buildCustomNodes(menu.title),
|
||||
}))
|
||||
return customMenus
|
||||
.filter((menu) => (menu.parent || '后台管理') === parent)
|
||||
.map((menu) => ({
|
||||
id: menu.key,
|
||||
label: menu.title,
|
||||
menu,
|
||||
children: buildCustomNodes(menu.title)
|
||||
}))
|
||||
}
|
||||
|
||||
export function useMenuManagement() {
|
||||
const { createPermission, removePermission } = useRbac()
|
||||
const selectedKey = ref('')
|
||||
const selectedParent = ref('后台管理')
|
||||
const form = reactive({ key: '', title: '', route: '', permission: '', parent: '后台管理', type: '页面', icon: 'Document', method: '', sort: 1 })
|
||||
const menuTree = computed(() => builtInMenus.map(group => ({ ...group, children: [...group.children, ...buildCustomNodes(group.label)] })))
|
||||
const parentOptions = computed(() => ['内容管理', '后台管理', ...customMenus.filter(menu => menu.type !== '按钮').map(menu => menu.title)])
|
||||
const form = reactive({
|
||||
key: '',
|
||||
title: '',
|
||||
route: '',
|
||||
permission: '',
|
||||
parent: '后台管理',
|
||||
type: '页面',
|
||||
icon: 'Document',
|
||||
method: '',
|
||||
sort: 1
|
||||
})
|
||||
const menuTree = computed(() =>
|
||||
builtInMenus.map((group) => ({
|
||||
...group,
|
||||
children: [...group.children, ...buildCustomNodes(group.label)]
|
||||
}))
|
||||
)
|
||||
const parentOptions = computed(() => [
|
||||
'内容管理',
|
||||
'后台管理',
|
||||
...customMenus.filter((menu) => menu.type !== '按钮').map((menu) => menu.title)
|
||||
])
|
||||
|
||||
function resetForm(parent = selectedParent.value) {
|
||||
selectedKey.value = ''
|
||||
Object.assign(form, { key: '', title: '', route: '', permission: '', parent, type: '页面', icon: 'Document', method: '', sort: 1 })
|
||||
Object.assign(form, {
|
||||
key: '',
|
||||
title: '',
|
||||
route: '',
|
||||
permission: '',
|
||||
parent,
|
||||
type: '页面',
|
||||
icon: 'Document',
|
||||
method: '',
|
||||
sort: 1
|
||||
})
|
||||
}
|
||||
function selectNode(node) {
|
||||
if (node.menu) {
|
||||
@@ -48,7 +112,7 @@ export function useMenuManagement() {
|
||||
permission: node.menu.permission || `访问菜单:${node.menu.title}`,
|
||||
type: node.menu.type || '页面',
|
||||
method: node.menu.method || '',
|
||||
sort: node.menu.sort || 1,
|
||||
sort: node.menu.sort || 1
|
||||
})
|
||||
} else if (node.children) {
|
||||
selectedParent.value = node.label
|
||||
@@ -58,11 +122,13 @@ export function useMenuManagement() {
|
||||
function saveMenu() {
|
||||
if (!form.title.trim()) return ElMessage.warning('请填写菜单名称')
|
||||
if (form.type !== '按钮' && !form.route.trim()) return ElMessage.warning('请填写对应路由')
|
||||
const duplicate = customMenus.some(menu => menu.title === form.title.trim() && menu.key !== selectedKey.value)
|
||||
const duplicate = customMenus.some(
|
||||
(menu) => menu.title === form.title.trim() && menu.key !== selectedKey.value
|
||||
)
|
||||
if (duplicate) return ElMessage.warning('菜单名称已存在')
|
||||
const isNew = !selectedKey.value
|
||||
const key = selectedKey.value || `${Date.now()}`
|
||||
const existingMenu = customMenus.find(menu => menu.key === key)
|
||||
const existingMenu = customMenus.find((menu) => menu.key === key)
|
||||
const permission = form.permission.trim() || `访问菜单:${form.title.trim()}`
|
||||
if (existingMenu) {
|
||||
if (router.hasRoute(`custom-menu-${key}`)) router.removeRoute(`custom-menu-${key}`)
|
||||
@@ -70,26 +136,40 @@ export function useMenuManagement() {
|
||||
removePermission(existingMenu.permission)
|
||||
createPermission(permission)
|
||||
}
|
||||
Object.assign(existingMenu, { ...form, key, title: form.title.trim(), permission, route: form.route.trim(), sort: Number(form.sort) || 1 })
|
||||
Object.assign(existingMenu, {
|
||||
...form,
|
||||
key,
|
||||
title: form.title.trim(),
|
||||
permission,
|
||||
route: form.route.trim(),
|
||||
sort: Number(form.sort) || 1
|
||||
})
|
||||
} else {
|
||||
customMenus.push({ ...form, key, title: form.title.trim(), permission, route: form.route.trim(), sort: Number(form.sort) || 1 })
|
||||
customMenus.push({
|
||||
...form,
|
||||
key,
|
||||
title: form.title.trim(),
|
||||
permission,
|
||||
route: form.route.trim(),
|
||||
sort: Number(form.sort) || 1
|
||||
})
|
||||
createPermission(permission)
|
||||
}
|
||||
const savedMenu = customMenus.find(menu => menu.key === key)
|
||||
const savedMenu = customMenus.find((menu) => menu.key === key)
|
||||
if (savedMenu?.type !== '按钮') registerCustomMenu(savedMenu)
|
||||
saveCustomMenus()
|
||||
selectedKey.value = key
|
||||
ElMessage.success(isNew ? '菜单已添加' : '菜单已保存')
|
||||
}
|
||||
async function deleteMenu() {
|
||||
const menu = customMenus.find(item => item.key === selectedKey.value)
|
||||
const menu = customMenus.find((item) => item.key === selectedKey.value)
|
||||
if (!menu) return ElMessage.warning('请先在左侧选择一个自定义菜单')
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认删除「${menu.title}」菜单吗?`, '删除确认', {
|
||||
confirmButtonText: '确认删除',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
confirmButtonClass: 'el-button--danger',
|
||||
confirmButtonClass: 'el-button--danger'
|
||||
})
|
||||
customMenus.splice(customMenus.indexOf(menu), 1)
|
||||
removePermission(menu.permission)
|
||||
@@ -102,5 +182,15 @@ export function useMenuManagement() {
|
||||
}
|
||||
}
|
||||
|
||||
return { selectedKey, selectedParent, form, menuTree, parentOptions, resetForm, selectNode, saveMenu, deleteMenu }
|
||||
return {
|
||||
selectedKey,
|
||||
selectedParent,
|
||||
form,
|
||||
menuTree,
|
||||
parentOptions,
|
||||
resetForm,
|
||||
selectNode,
|
||||
saveMenu,
|
||||
deleteMenu
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user