Files
gao-customer-h5/src/pages/permission/PermissionSettings.vue
T
2026-08-26 21:18:02 +08:00

184 lines
5.5 KiB
Vue

<template>
<div
v-can="{ value: [corePermissionCodes.role.read, corePermissionCodes.permission.read], mode: 'and' }"
class="permission-settings"
>
<t-cell-group title="权限配置" theme="card">
<t-cell
v-can="corePermissionCodes.role.read"
title="角色管理"
:note="`${roleCount} 个角色`"
arrow
@click="router.push('/management/permissions/roles')"
>
<template #leftIcon>
<t-icon name="user-setting" size="1.75rem" />
</template>
</t-cell>
<t-cell
v-can="corePermissionCodes.permission.read"
title="权限管理"
:note="`${permissionCount} 个权限`"
arrow
@click="router.push('/management/permissions/items')"
>
<template #leftIcon>
<t-icon name="secured" size="1.75rem" />
</template>
</t-cell>
<t-cell
v-can="rolePermissionAssignAccess"
title="角色直接授权 P"
arrow
@click="router.push('/management/permissions/assign/p')"
>
<template #leftIcon>
<t-icon name="secured" size="1.75rem" />
</template>
</t-cell>
<t-cell
v-can="rolePermissionAssignAccess"
title="角色转授权限 D"
arrow
@click="router.push('/management/permissions/assign/d')"
>
<template #leftIcon>
<t-icon name="user-checked" size="1.75rem" />
</template>
</t-cell>
<t-cell
v-can="corePermissionCodes.userRole.read"
title="用户角色授权"
arrow
@click="router.push('/management/permissions/user-roles')"
>
<template #leftIcon>
<t-icon name="usergroup" size="1.75rem" />
</template>
</t-cell>
</t-cell-group>
<t-cell-group v-entrance-transition title="当前角色结构" theme="card">
<t-cell
v-can="{ value: [corePermissionCodes.role.read, corePermissionCodes.permission.read], mode: 'and' }"
v-for="item in visibleRoleTree"
:key="item.id"
:arrow="canAssignRole(item)"
:hover="canAssignRole(item)"
@click="canAssignRole(item) && toAssign(item.id)"
>
<template #title>
<div class="title" v-text="item.name" :style="{ paddingLeft: `${item.level * 1.25}rem` }" />
</template>
</t-cell>
</t-cell-group>
</div>
</template>
<script setup lang="ts">
import { useUserStore } from "timi-web-api";
import type { Role } from "@/store/permissionSettingsStore";
import { usePermissionSettingsStore } from "@/store/permissionSettingsStore";
import { corePermissionCodes, coreRoleCodes } from "@/utils/permission";
defineOptions({
name: "PermissionSettings"
});
const router = useRouter();
const userStore = useUserStore();
const permissionStore = usePermissionSettingsStore();
const authorizationRoleList = ref<Role[]>([]);
const isSystemAdmin = computed(() => userStore.hasRoles(coreRoleCodes.admin));
const roleCount = computed(() => authorizationRoleList.value.length);
const permissionCount = computed(() => permissionStore.permissionList.length);
type RoleTreeItem = Pick<Role, "id" | "name" | "parentRoleId" | "protectedRole"> & { level: number };
const visibleRoleTree = computed<RoleTreeItem[]>(() => {
if (isSystemAdmin.value) {
return permissionStore.roleTree;
}
const roleMap = new Map(authorizationRoleList.value.map(item => [item.id, item]));
const roleIdSet = new Set(authorizationRoleList.value.map(item => item.id));
const roots = authorizationRoleList.value.filter(item => !item.parentRoleId || !roleIdSet.has(item.parentRoleId));
const buildTree = (roleId: string, level: number, visitedRoleIds: Set<string>): RoleTreeItem[] => {
const role = roleMap.get(roleId);
if (!role || visitedRoleIds.has(roleId)) {
return [];
}
const nextVisitedRoleIds = new Set(visitedRoleIds);
nextVisitedRoleIds.add(roleId);
const childRoleIdList = authorizationRoleList.value
.filter(item => item.parentRoleId === roleId)
.map(item => item.id);
return [{ ...role, level }, ...childRoleIdList.flatMap(childRoleId => buildTree(childRoleId, level + 1, nextVisitedRoleIds))];
};
return roots.flatMap(item => buildTree(item.id, 0, new Set<string>()));
});
// ---------- 权限入口 ----------
const rolePermissionAssignAccess = {
value: [
corePermissionCodes.role.read,
corePermissionCodes.permission.read,
corePermissionCodes.rolePermission.read
],
mode: "and"
} as const;
async function toAssign(roleId: string): Promise<void> {
await router.push({
path: "/management/permissions/assign/p",
query: {
roleId
}
});
}
function canAssignRole(role: Pick<Role, "protectedRole">): boolean {
return isSystemAdmin.value || role.protectedRole !== true;
}
// ---------- 页面数据 ----------
onMounted(async () => {
if (isSystemAdmin.value) {
await permissionStore.loadAll();
authorizationRoleList.value = permissionStore.roleList;
return;
}
await permissionStore.loadAll();
const roleList = await permissionStore.loadManageableRoles();
authorizationRoleList.value = roleList;
});
</script>
<style scoped lang="less">
.permission-settings {
gap: 1rem;
padding: calc(var(--app-nav-height) + 1rem) 0 1rem 0;
display: flex;
flex-direction: column;
.struct {
.header {
display: flex;
padding: 0 var(--td-cell-group-title-padding-left, 16px);
font-size: var(--td-cell-group-title-font-size, 14px);
text-align: left;
background: var(--td-cell-group-title-bg-color, var(--td-bg-color-secondarycontainer, var(--td-gray-color-1, #f3f3f3)));
line-height: var(--td-cell-group-title-line-height, 45px);
justify-content: space-between;
.title {
color: var(--td-cell-group-title-color, var(--td-text-color-placeholder, var(--td-font-gray-3, rgba(0, 0, 0, 0.4))));
}
}
}
}
</style>