feat: 搭建后台管理框架

This commit is contained in:
Vicky committed 2026-10-13 13:58:05 +08:00
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
}
}