update permission and product

This commit is contained in:
Timi
2026-09-04 23:07:59 +08:00
parent 1df5748f54
commit fc9e6a5023
48 changed files with 1670 additions and 2475 deletions
+96 -85
View File
@@ -1,71 +1,70 @@
<template>
<div v-can="pageAccess" class="role-edit">
<t-form v-entrance-transition class="form" label-align="left">
<t-form-item label="名称">
<t-input v-model.trim="formModel.name" placeholder="角色名称" borderless :disabled="!canEditRoleInfo" />
</t-form-item>
<t-form-item label="代码" :help="isBuiltinRole ? '内建角色代码不可修改' : ''">
<t-input v-model.trim="formModel.code" placeholder="如 front-desk" borderless :disabled="!canEditRoleCode" />
</t-form-item>
<t-form-item label="模块">
<t-input v-model.trim="formModel.moduleCode" placeholder="模块代码" borderless disabled />
</t-form-item>
<t-form-item
label="上级"
:arrow="canEditParentRole"
@click.stop="openParentRolePicker"
>
<div class="picker-text" v-text="selectedParentRoleName" />
</t-form-item>
<t-form-item label="说明">
<t-textarea v-model.trim="formModel.description" class="textarea" placeholder="角色说明" autosize borderless :disabled="!canEditRoleInfo" />
</t-form-item>
<t-form-item
label="继承角色"
:arrow="canEditRoleRelation"
@click.stop="openChildRolePicker"
>
<div class="picker-text" v-text="selectedChildRoleName" />
</t-form-item>
</t-form>
<t-cell-group v-entrance-transition="70" v-if="!isCreateMode" title="权限授权" theme="card">
<t-cell
v-can="rolePermissionReadAccess"
title="直接授权权限 P"
arrow
@click="toRolePermissionPage"
>
<template #leftIcon>
<t-icon name="secured" size="1.5rem" />
</template>
</t-cell>
<t-cell
v-can="rolePermissionReadAccess"
title="可转授权限 D"
arrow
@click="toRoleDelegationPage"
>
<template #leftIcon>
<t-icon name="user-checked" size="1.5rem" />
</template>
</t-cell>
</t-cell-group>
<card-container v-entrance-transition="140" v-if="aggregatePermissionList.length" title="聚合权限 P">
<template #description>
<div>该角色拥有以下权限,可执行权限对应的功能,这些权限来自上级角色直接授权或子角色继承。</div>
<permission-legend />
<t-form v-entrance-transition class="form" label-align="left">
<t-form-item label="名称">
<t-input v-model.trim="formModel.name" placeholder="角色名称" borderless :disabled="!canEditRoleInfo" />
</t-form-item>
<t-form-item label="代码" :help="isBuiltinRole ? '内建角色代码不可修改' : ''">
<t-input v-model.trim="formModel.code" placeholder="如 ROLE_CODE" borderless :disabled="!canEditRoleCode" />
</t-form-item>
<t-form-item label="模块">
<t-input v-model.trim="formModel.moduleCode" placeholder="模块代码" borderless disabled />
</t-form-item>
<t-form-item
label="上级"
:arrow="canEditParentRole"
@click.stop="openParentRolePicker"
>
<div class="picker-text" v-text="selectedParentRoleName" />
</t-form-item>
<t-form-item label="说明">
<t-textarea v-model.trim="formModel.description" class="textarea" placeholder="角色说明" autosize borderless :disabled="!canEditRoleInfo" />
</t-form-item>
<t-form-item
label="继承角色"
:arrow="canEditRoleRelation"
@click.stop="openChildRolePicker"
>
<div class="picker-text" v-text="selectedChildRoleName" />
</t-form-item>
</t-form>
<t-cell-group v-entrance-transition="70" v-if="!isCreateMode && canManageRole" title="权限授权" theme="card">
<t-cell
v-can="rolePermissionReadAccess"
title="直接授权权限 P"
arrow
@click="toRolePermissionPage"
>
<template #leftIcon>
<t-icon name="secured" size="1.5rem" />
</template>
<t-cell-group class="permission-list" theme="card">
<permission-cell
v-for="item in aggregatePermissionList"
:key="item.id"
:permission="item"
:source="item.source"
/>
</t-cell-group>
</card-container>
</t-cell>
<t-cell
v-can="rolePermissionReadAccess"
title="可转授权限 D"
arrow
@click="toRoleDelegationPage"
>
<template #leftIcon>
<t-icon name="user-checked" size="1.5rem" />
</template>
</t-cell>
</t-cell-group>
<card-container v-entrance-transition="140" v-if="aggregatePermissionList.length" title="聚合权限 P">
<template #description>
<div>该角色拥有以下权限,可执行权限对应的功能,这些权限来自上级角色直接授权或子角色继承。</div>
<permission-legend />
</template>
<t-cell-group class="permission-list" theme="card">
<permission-cell
v-for="item in aggregatePermissionList"
:key="item.id"
:permission="item"
:source="item.source"
/>
</t-cell-group>
</card-container>
</div>
<t-popup v-model="parentRolePickerVisible" placement="bottom">
<t-picker
v-model="parentRolePickerDraft"
@@ -170,7 +169,12 @@ const isSystemAdmin = computed(() => userStore.hasRoles(coreRoleCodes.admin));
const isBuiltinRole = computed(() => currentRole.value?.builtin === true);
const isProtectedRole = computed(() => !isSystemAdmin.value && currentRole.value?.protectedRole === true);
const canManageRole = computed(() => isCreateMode.value || Boolean(currentRole.value && candidateRoleList.value.some(item => item.id === formModel.id)));
const canEditRoleInfo = computed(() => userStore.hasPermissions(savePermissionCode.value) && (isCreateMode.value || (
const isCurrentUserDirectRole = computed(() => {
const current = currentRole.value;
return Boolean(current?.moduleCode && current.code && userStore.hasRoles(`${current.moduleCode}:${current.code}`));
});
const hasSavePermission = computed(() => userStore.hasPermissions(savePermissionCode.value));
const canEditRoleInfo = computed(() => hasSavePermission.value && (isCreateMode.value || (
canManageRole.value
&& !isProtectedRole.value
)));
@@ -181,11 +185,10 @@ const canUpdateRoleRelation = computed(() => userStore.hasPermissions([
corePermissionCodes.rolePermissionInherit.delete
], "and"));
const canEditRoleRelation = computed(() => !isCreateMode.value && canUpdateRoleRelation.value && (
canManageRole.value
(canManageRole.value || isCurrentUserDirectRole.value)
&& !isProtectedRole.value
));
const canSaveBaseInfo = computed(() => canEditRoleInfo.value);
const canShowSaveAction = computed(() => canSaveBaseInfo.value && userStore.hasPermissions(savePermissionCode.value));
type PermissionSource = "direct" | "inherited";
type PermissionWithSource = Permission & {
source: PermissionSource;
@@ -308,14 +311,14 @@ function isManagementChildRole(roleId: string, parentRoleId: string, visitedRole
// ---------- 页面跳转 ----------
async function toRolePermissionPage(): Promise<void> {
if (!formModel.id) {
if (!formModel.id || !canManageRole.value) {
return;
}
await router.push(`/management/permissions/roles/${formModel.id}/assign/p`);
}
async function toRoleDelegationPage(): Promise<void> {
if (!formModel.id) {
if (!formModel.id || !canManageRole.value) {
return;
}
await router.push(`/management/permissions/roles/${formModel.id}/assign/d`);
@@ -327,7 +330,7 @@ async function fillForm(): Promise<void> {
await permissionStore.loadAll();
await loadAuthorizationScope();
if (isCreateMode.value) {
parentRoleOptions.value = candidateRoleList.value;
parentRoleOptions.value = await permissionStore.loadCreateParentGrantableRoles();
formModel.parentRoleId = parentRoleOptions.value[0]?.id || "";
return;
}
@@ -342,16 +345,6 @@ async function reloadCurrentRole(): Promise<void> {
.filter(item => item.id !== current.id && isManagementChildRole(item.id, current.id) && !hasChildRole(item.id, current.id))
.map(item => item.id));
const childRoleIdList = current.childRoleIdList.filter(id => childOptionIdSet.has(id));
parentRoleOptions.value = await permissionStore.loadParentGrantableRoles(current.id);
if (current.parentRole?.id && !parentRoleOptions.value.some(item => item.id === current.parentRoleId)) {
parentRoleOptions.value.unshift({
...current.parentRole,
id: current.parentRole.id,
permissionIdList: current.parentRole.permissionIdList || current.parentRole.permissionList?.map(item => item.id) || [],
childRoleIdList: current.parentRole.childRoleIdList || current.parentRole.childRoleList?.map(item => item.id).filter((id): id is string => Boolean(id)) || [],
delegationPermissionIdList: current.parentRole.delegationPermissionIdList || current.parentRole.delegationPermissionList?.map(item => item.id) || []
});
}
Object.assign(formModel, {
id: current.id,
moduleCode: current.moduleCode || moduleCode,
@@ -361,6 +354,18 @@ async function reloadCurrentRole(): Promise<void> {
parentRoleId: current.parentRoleId || "",
childRoleIdList
});
parentRoleOptions.value = canEditParentRole.value
? await permissionStore.loadParentGrantableRoles(current.id)
: [];
if (current.parentRole?.id && !parentRoleOptions.value.some(item => item.id === current.parentRoleId)) {
parentRoleOptions.value.unshift({
...current.parentRole,
id: current.parentRole.id,
permissionIdList: current.parentRole.permissionIdList || current.parentRole.permissionList?.map(item => item.id) || [],
childRoleIdList: current.parentRole.childRoleIdList || current.parentRole.childRoleList?.map(item => item.id).filter((id): id is string => Boolean(id)) || [],
delegationPermissionIdList: current.parentRole.delegationPermissionIdList || current.parentRole.delegationPermissionList?.map(item => item.id) || []
});
}
}
async function loadAuthorizationScope(): Promise<void> {
@@ -453,16 +458,22 @@ async function getCurrentStoreId(): Promise<string> {
return storeId;
}
onMounted(fillForm);
function updateNavBar(): void {
navBarStore.clearRight();
if (canShowSaveAction.value) {
navBarStore.setRightText("保存", "var(--td-brand-color)", saveBaseInfo);
if (!hasSavePermission.value) {
return;
}
navBarStore.setRightText("保存", "var(--td-brand-color)", saveBaseInfo);
navBarStore.setRightDisabled(!canSaveBaseInfo.value);
}
watch(canShowSaveAction, updateNavBar, { immediate: true });
watch([hasSavePermission, canSaveBaseInfo], updateNavBar, { immediate: true });
onMounted(async () => {
await fillForm();
updateNavBar();
});
onUnmounted(() => navBarStore.clearRight());
</script>