角色权限改为tree

This commit is contained in:
2026-05-09 14:47:20 +08:00
parent 8621178127
commit 616de27a3a
1 changed files with 85 additions and 178 deletions

View File

@ -8,95 +8,41 @@
<!-- 角色列表表格 -->
<RoleTable :table-data="roleTree" :columns="roleTableColumns" row-key="id">
<template #status="{ row }">
<el-switch
:model-value="row.status === 1"
:active-value="true"
:inactive-value="false"
active-text="启用"
inactive-text="禁用"
/>
<el-switch :model-value="row.status === 1" :active-value="true" :inactive-value="false" active-text="启用"
inactive-text="禁用" />
</template>
<template #createTime="{ row }">
{{ row.created_at }}
</template>
<template #action="{ row }">
<el-button
link
type="primary"
size="small"
@click="handleEditRole(row)"
v-auth="'roles_edit'"
>
<el-button link type="primary" size="small" @click="handleEditRole(row)" v-auth="'roles_edit'">
编辑
</el-button>
<el-button
link
type="primary"
size="small"
@click="handlePermission(row)"
v-auth="'roles_setPermission'"
>
<el-button link type="primary" size="small" @click="handlePermission(row)" v-auth="'roles_setPermission'">
设置权限
</el-button>
<el-button
link
type="danger"
size="small"
@click="handleDeleteRole(row)"
v-auth="'roles_del'"
>
<el-button link type="danger" size="small" @click="handleDeleteRole(row)" v-auth="'roles_del'">
删除
</el-button>
</template>
</RoleTable>
</div>
<!-- 角色新增/编辑弹窗 -->
<RoleDialog
:visible="dialogVisible"
:title="dialogTitle"
:type="dialogType"
@confirm="handleSubmit"
@cancel="handleCancel"
@close="handleClose"
:fullscreen="fullScreen"
>
<RoleForm
:form-data="roleForm"
:form-rules="roleFormRules"
:form-items="roleFormItemOptions"
ref="roleFormRef"
:options-map="roleFormOptionsMap"
:dialog-type="dialogType"
>
<!-- 角色新增/编辑抽屉 -->
<el-drawer v-model="dialogVisible" :title="dialogTitle" :size="'800px'" @close="handleClose">
<RoleForm :form-data="roleForm" :form-rules="roleFormRules" :form-items="roleFormItemOptions" ref="roleFormRef"
:options-map="roleFormOptionsMap" :dialog-type="dialogType">
<template #permissions="{ formData }">
<div class="permission-group">
<div
v-for="(group, module) in groupedPermissions"
:key="module"
class="permission-module"
>
<!-- 点击事件的 checked 参数 -->
<el-checkbox
:model-value="getModuleCheckedState(module)"
:indeterminate="getModuleIndeterminateState(module)"
@change="
(checked: boolean | string | number) => handleModuleCheckChange(module, !!checked)
"
class="module-title"
>
{{ module }}
</el-checkbox>
<!-- 添加子权限 change 事件监听 -->
<el-checkbox-group v-model="formData.permissions" @change="handlePermissionChange">
<el-checkbox v-for="perm in group" :key="perm.id" :value="perm.id">
{{ perm.title }} ({{ perm.name }})
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<el-tree ref="permissionTreeRef" :data="permissionTreeData" :props="treeProps" show-checkbox node-key="id"
:default-checked-keys="formData.permissions" :default-expand-all="true" class="permission-tree" />
</template>
</RoleForm>
</RoleDialog>
<template #footer>
<div style="flex: auto">
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</div>
</template>
</el-drawer>
</template>
<script lang="ts" setup>
@ -104,7 +50,7 @@
defineOptions({
name: 'Role'
})
import type { FormInstance } from 'element-plus'
import type { FormInstance, TreeInstance } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
//
@ -123,6 +69,18 @@ import {
setRolePermissionApi,
} from '@/api/modules/system/role'
// Treeref
const permissionTreeRef = ref<TreeInstance>()
//
const permissionTreeData = ref<any[]>([])
// Treeprops
const treeProps = {
label: 'title',
children: 'children',
}
// header
const roleTitle = ref('角色管理')
const roleHeaderButtons = [
@ -154,10 +112,8 @@ const roleFormOptionsMap = ref({
permissions: [] as any[],
})
//id
// id
const permissionIds = ref('')
// { : [1,2...] }
const groupedPermissions = ref<Record<string, any[]>>({})
//
const allPermissions = ref<any[]>([])
@ -232,58 +188,42 @@ const handleDialogType = (type: string) => {
}
}
//
const getModuleCheckedState = (module: string) => {
const group = groupedPermissions.value[module]
if (!group) return false
const groupIds = group.map((perm) => perm.id)
return groupIds.every((id) => roleForm.value.permissions.includes(id))
}
//
const transformPermissionsToTree = (permissions: any[]) => {
const moduleMap = new Map<string, any>()
const childrenMap = new Map<string, any[]>()
//
const getModuleIndeterminateState = (module: string) => {
const group = groupedPermissions.value[module]
if (!group) return false
const groupIds = group.map((perm) => perm.id)
const selectedCount = groupIds.filter((id) => roleForm.value.permissions.includes(id)).length
return selectedCount > 0 && selectedCount < group.length
}
// /
const handleModuleCheckChange = (module: string, checked: boolean) => {
const group = groupedPermissions.value[module]
if (!group) return
const groupIds = group.map((perm) => perm.id)
if (checked) {
roleForm.value.permissions = [...new Set([...roleForm.value.permissions, ...groupIds])]
} else {
roleForm.value.permissions = roleForm.value.permissions.filter((id) => !groupIds.includes(id))
}
}
//
const handlePermissionChange = () => {
roleForm.value = { ...roleForm.value }
}
// module
const groupPermissionsByModule = (permissions: any[]) => {
const grouped: Record<string, any[]> = {}
//
permissions.forEach((perm) => {
grouped[perm.module] = grouped[perm.module] || []
const item = {
...perm,
pId: permissions.find((p) => p.title === perm.module).id,
if (perm.module && !moduleMap.has(perm.module)) {
//
const moduleItem = permissions.find((p) => p.title === perm.module)
if (moduleItem) {
moduleMap.set(perm.module, {
id: moduleItem.id,
title: moduleItem.title,
children: [],
})
}
}
grouped[perm.module]!.push(item)
})
for (const key in grouped) {
console.log(key, grouped[key])
grouped[key] = grouped[key].filter((item) => item.pId !== item.id)
}
Object.values(grouped).forEach((group) => group.sort((a, b) => a.id - b.id))
return grouped
//
permissions.forEach((perm) => {
if (perm.module && moduleMap.has(perm.module)) {
const moduleItem = moduleMap.get(perm.module)!
//
if (perm.title !== perm.module) {
moduleItem.children.push({
id: perm.id,
title: `${perm.title} (${perm.name})`,
})
}
}
})
// ID
return Array.from(moduleMap.values()).sort((a, b) => a.id - b.id)
}
//
@ -295,13 +235,10 @@ const handlePermission = async (row: any) => {
permissionIds.value = row.id
try {
const data = await getRolePermissionApi({ id: row.id })
allPermissions.value = data.all_permission_info.map((item) => ({
...item,
pId: data.all_permission_info.find((p) => p.title === item.module)?.id,
}))
groupedPermissions.value = groupPermissionsByModule(data.all_permission_info)
allPermissions.value = data.all_permission_info
permissionTreeData.value = transformPermissionsToTree(data.all_permission_info)
roleForm.value.permissions = data.permission_ids || []
console.log('分组后的权限', groupedPermissions.value)
console.log('树形权限数据', permissionTreeData.value)
} catch (err) {
console.error('获取角色权限失败', err)
}
@ -311,12 +248,7 @@ const handlePermission = async (row: any) => {
@description: 处理弹窗提交/取消/关闭事件
**/
const handleSubmit = async () => {
console.log(
'提交菜单表单',
roleForm.value.permissions,
groupedPermissions.value,
allPermissions.value,
) // ID便
console.log('提交菜单表单', roleForm.value.permissions, allPermissions.value)
try {
await roleFormRef.value?.validate()
if (dialogType.value === 'add') {
@ -330,19 +262,14 @@ const handleSubmit = async () => {
await editRoleApi(roleForm.value)
await fetchRoleList()
} else {
let permissionIdList: any[] = [...roleForm.value.permissions]
for (let i = 0; i < allPermissions.value.length; i++) {
const flag = permissionIdList.includes(allPermissions.value[i]!.id)
if (flag) {
if (!permissionIdList.includes(allPermissions.value[i]!.pId))
permissionIdList.push(allPermissions.value[i]!.pId)
}
}
console.log('设置角色权限', permissionIdList.join(','))
// Tree
const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []
console.log('设置角色权限', checkedKeys.join(','))
await setRolePermissionApi({
id: permissionIds.value,
permission_ids: permissionIdList.join(','),
permission_ids: checkedKeys.join(','),
})
await fetchRoleList()
}
@ -377,42 +304,22 @@ const handleClose = () => {
</script>
<style scoped lang="scss">
.permission-group {
width: 100%;
}
:deep(.el-form-item__content) {
margin-left: 0 !important;
}
.system {
:deep(.el-drawer__header) {
margin-bottom: 0 !important;
}
}
.permission-module {
margin-bottom: 20px;
border: 1px solid #e5e7eb;
.permission-tree {
width: 100%;
// border: 1px solid #e5e7eb;
border-radius: 6px;
padding: 15px;
&:last-child {
margin-bottom: 0;
}
}
.module-title {
margin: 0 0 10px 0;
font-size: 16px;
font-weight: 600;
border-bottom: 1px solid #e5e7eb;
padding-bottom: 8px;
display: flex; // flex block
}
.permission-list {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.el-checkbox-group {
label {
margin-right: 15px;
}
// padding: 15px;
// max-height: 500px;
// overflow-y: auto;
}
</style>