Files
gao-customer-h5/src/pages/permission/PermissionList.vue
T
2026-09-21 13:05:37 +08:00

177 lines
4.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div v-can="{ value: [corePermissionCodes.role.read, corePermissionCodes.permission.read], mode: 'and' }" class="permission-list">
<t-pull-down-refresh
class="list-wrapper"
v-model="isRefreshing"
:refresh-timeout="30000"
@refresh="refresh"
>
<div class="content">
<t-cell-group v-entrance-transition class="header" theme="card">
<t-cell title="当前账号角色聚合权限 P">
<template #description>
<div>你拥有以下权限,可执行权限对应的功能,这些权限来自上级角色直接授权或子角色继承。</div>
<permission-legend />
</template>
</t-cell>
</t-cell-group>
<t-cell-group v-if="sortedPermissions.length" theme="card">
<t-swipe-cell
v-entrance-transition="index * 30"
v-for="(item, index) in sortedPermissions"
:key="item.id"
class="item"
>
<permission-cell :permission="item" :source="item.source" />
</t-swipe-cell>
</t-cell-group>
<t-empty v-if="!permissionStore.loading && !isSourceLoading" description="暂无权限" />
</div>
</t-pull-down-refresh>
</div>
</template>
<script setup lang="ts">
import { type Role as UserRole, RoleAPI, useUserStore } from "timi-web-api";
import type { Permission } from "@/store/permissionSettingsStore";
import { moduleCode, usePermissionSettingsStore } from "@/store/permissionSettingsStore";
import { corePermissionCodes } from "@/utils/permission";
import PermissionCell from "@/pages/permission/component/PermissionCell.vue";
import PermissionLegend from "@/pages/permission/component/PermissionLegend.vue";
defineOptions({
name: "PermissionList"
});
const permissionStore = usePermissionSettingsStore();
const userStore = useUserStore();
const isRefreshing = ref(false);
const isSourceLoading = ref(false);
// ---------- 列表数据 ----------
type PermissionSource = "direct" | "inherited" | "unknown";
type PermissionWithSource = Permission & {
source: PermissionSource;
};
const sourceRoleList = ref<UserRole[]>([]);
const sortedPermissions = computed<PermissionWithSource[]>(() => {
const permissionMap = new Map<string, PermissionWithSource>();
for (const role of sourceRoleList.value) {
for (const permission of getRoleAggregatePermissions(role)) {
permissionMap.set(permission.id, {
...permission,
source: getPermissionSource(permission.id)
});
}
}
for (const permission of getLoginUserPermissions()) {
if (!permissionMap.has(permission.id)) {
permissionMap.set(permission.id, {
...permission,
source: "unknown"
});
}
}
return Array.from(permissionMap.values()).sort((left, right) => formatPermissionCode(left).localeCompare(formatPermissionCode(right)));
});
function getRoleAggregatePermissions(role: UserRole): Permission[] {
if (role.allPermissionList?.length) {
return role.allPermissionList;
}
if (role.permissionList?.length) {
return role.permissionList;
}
return (role.permissionIdList || []).map(permissionStore.getPermissionById).filter(Boolean) as Permission[];
}
function getLoginUserPermissions(): Permission[] {
const permissionCodeSet = new Set(userStore.getPermissionList());
return permissionStore.permissionList.filter(item => permissionCodeSet.has(formatPermissionCode(item)));
}
function getPermissionSource(permissionId: string): PermissionSource {
if (sourceRoleList.value.some(role => getDirectPermissionIdSet(role).has(permissionId))) {
return "direct";
}
if (sourceRoleList.value.some(role => role.allPermissionList?.some(permission => permission.id === permissionId))) {
return "inherited";
}
return "unknown";
}
function getDirectPermissionIdSet(role: UserRole): Set<string> {
if (role.permissionList?.length) {
return new Set(role.permissionList.map(item => item.id));
}
return new Set(role.permissionIdList || []);
}
function formatPermissionCode(permission: Permission): string {
return `${permission.moduleCode}:${permission.code}`;
}
// ---------- 页面数据 ----------
async function refresh(): Promise<void> {
isRefreshing.value = true;
try {
await permissionStore.loadAll(true);
await loadSourceRoles();
} finally {
isRefreshing.value = false;
}
}
onMounted(async () => {
await permissionStore.loadAll();
await loadSourceRoles();
});
async function loadSourceRoles(): Promise<void> {
isSourceLoading.value = true;
try {
sourceRoleList.value = await RoleAPI.currentDetailList(moduleCode);
} finally {
isSourceLoading.value = false;
}
}
</script>
<style scoped lang="less">
.permission-list {
padding: calc(var(--app-nav-height) + 1rem) 0 1rem 0;
.list-wrapper {
.content {
gap: 1rem;
display: flex;
flex-direction: column;
.header {
.description {
gap: .5rem;
display: flex;
flex-direction: column;
}
}
.item {
&:last-child {
:deep(.t-cell:after) {
display: none;
}
}
}
}
}
}
</style>