update RolePermissionAssign style
This commit is contained in:
@@ -50,6 +50,7 @@ import type { DropdownOption, DropdownValue } from "tdesign-mobile-vue";
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import { type Permission, useUserStore } from "timi-web";
|
||||
import { type Role, usePermissionSettingsStore } from "@/store/permissionSettingsStore";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { corePermissionCodes, coreRoleCodes } from "@/utils/permission";
|
||||
|
||||
defineOptions({
|
||||
@@ -188,16 +189,6 @@ async function loadAuthorizationScope(): Promise<void> {
|
||||
candidateRoleList.value = roleList;
|
||||
}
|
||||
|
||||
function getErrorMessage(error: unknown, fallback: string): string {
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
}
|
||||
if (typeof error === "string" && error) {
|
||||
return error;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await permissionStore.loadAll();
|
||||
await loadAuthorizationScope();
|
||||
|
||||
@@ -112,6 +112,7 @@ import {
|
||||
type RoleDraft,
|
||||
usePermissionSettingsStore
|
||||
} from "@/store/permissionSettingsStore";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { corePermissionCodes, coreRoleCodes } from "@/utils/permission";
|
||||
import PermissionCell from "@/pages/permission/component/PermissionCell.vue";
|
||||
import PermissionLegend from "@/pages/permission/component/PermissionLegend.vue";
|
||||
@@ -453,16 +454,6 @@ async function getCurrentStoreId(): Promise<string> {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
function getErrorMessage(error: unknown, fallback: string): string {
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
}
|
||||
if (typeof error === "string" && error) {
|
||||
return error;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
onMounted(fillForm);
|
||||
|
||||
function updateNavBar(): void {
|
||||
|
||||
@@ -39,6 +39,7 @@ import { useUserStore } from "timi-web";
|
||||
import type { Role } from "@/store/permissionSettingsStore";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import { usePermissionSettingsStore } from "@/store/permissionSettingsStore";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { corePermissionCodes, coreRoleCodes } from "@/utils/permission";
|
||||
|
||||
defineOptions({
|
||||
@@ -161,15 +162,6 @@ async function refreshAuthorizationScope(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
function getErrorMessage(error: unknown, fallback: string): string {
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
}
|
||||
if (typeof error === "string" && error) {
|
||||
return error;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -198,4 +190,3 @@ function getErrorMessage(error: unknown, fallback: string): string {
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
@@ -13,21 +13,23 @@
|
||||
@change="handleRoleChange"
|
||||
/>
|
||||
</t-dropdown-menu>
|
||||
<div class="show-child-permission">
|
||||
<span>显示继承权限</span>
|
||||
<t-switch v-model="showChildRolePermissions" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="inherit">
|
||||
<span class="label">显示继承权限</span>
|
||||
<t-switch class="switch" v-model="showChildRolePermissions" />
|
||||
</div>
|
||||
<t-cell-group v-if="activeRole && grantablePermissionList.length" title="可配置的直接权限 P" theme="card">
|
||||
<t-cell-group
|
||||
v-if="activeRole && grantablePermissionList.length"
|
||||
class="list"
|
||||
theme="card"
|
||||
>
|
||||
<t-cell
|
||||
:class="{ inherited: isPermissionInherited(item.id) }"
|
||||
v-for="item in grantablePermissionList"
|
||||
:key="item.id"
|
||||
:title="item.name || item.code"
|
||||
:class="{ inherited: isPermissionInherited(item.id) }"
|
||||
:title="item.name"
|
||||
:description="item.code"
|
||||
>
|
||||
<template #description>
|
||||
<span class="code" v-text="item.code"></span>
|
||||
</template>
|
||||
<template #right-icon>
|
||||
<t-switch
|
||||
:disabled="!canUpdateRolePermission || !canEditActiveRole || isPermissionInherited(item.id)"
|
||||
@@ -38,15 +40,6 @@
|
||||
</t-cell>
|
||||
</t-cell-group>
|
||||
<t-empty v-else-if="!permissionStore.loading" description="暂无可配置的直接权限 P" />
|
||||
<t-button
|
||||
v-if="canEditActiveRole"
|
||||
v-can="rolePermissionWriteAccess"
|
||||
class="save"
|
||||
theme="primary"
|
||||
@click="savePermissionList"
|
||||
>
|
||||
保存 P
|
||||
</t-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -54,7 +47,9 @@
|
||||
import type { DropdownOption, DropdownValue } from "tdesign-mobile-vue";
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
import { type Permission, useUserStore } from "timi-web";
|
||||
import { useNavBarStore } from "@/store/navBarStore";
|
||||
import { type Role, usePermissionSettingsStore } from "@/store/permissionSettingsStore";
|
||||
import { getErrorMessage } from "@/utils/error";
|
||||
import { corePermissionCodes, coreRoleCodes } from "@/utils/permission";
|
||||
|
||||
defineOptions({
|
||||
@@ -62,16 +57,13 @@ defineOptions({
|
||||
});
|
||||
|
||||
const permissionStore = usePermissionSettingsStore();
|
||||
const navBarStore = useNavBarStore();
|
||||
const userStore = useUserStore();
|
||||
const route = useRoute();
|
||||
|
||||
// ---------- 角色选择 ----------
|
||||
|
||||
const activeRoleId = ref(String(route.query.roleId || route.params.id || ""));
|
||||
const checkedPermissionIds = ref<string[]>([]);
|
||||
const unmanagedPermissionIds = ref<string[]>([]);
|
||||
const inheritedPermissionIds = ref<string[]>([]);
|
||||
const grantablePermissionList = ref<Permission[]>([]);
|
||||
const candidateRoleList = ref<Role[]>([]);
|
||||
const showChildRolePermissions = ref(false);
|
||||
let permissionSyncSeq = 0;
|
||||
@@ -94,16 +86,12 @@ const roleOptions = computed<DropdownOption[]>(() => candidateRoleList.value
|
||||
disabled: false
|
||||
})));
|
||||
|
||||
const rolePermissionWriteAccess = {
|
||||
value: [
|
||||
corePermissionCodes.rolePermission.create,
|
||||
corePermissionCodes.rolePermission.delete
|
||||
],
|
||||
mode: "and"
|
||||
} as const;
|
||||
|
||||
// ---------- 权限状态 ----------
|
||||
|
||||
const checkedPermissionIds = ref<string[]>([]);
|
||||
const unmanagedPermissionIds = ref<string[]>([]);
|
||||
const inheritedPermissionIds = ref<string[]>([]);
|
||||
const grantablePermissionList = ref<Permission[]>([]);
|
||||
const checkedPermissionIdSet = computed(() => new Set(checkedPermissionIds.value));
|
||||
const inheritedPermissionIdSet = computed(() => new Set(inheritedPermissionIds.value));
|
||||
|
||||
@@ -152,7 +140,7 @@ async function savePermissionList(): Promise<void> {
|
||||
...checkedPermissionIds.value,
|
||||
...unmanagedPermissionIds.value
|
||||
])));
|
||||
Toast.success("P 已保存");
|
||||
Toast.success("已保存");
|
||||
await loadActiveRolePermissions();
|
||||
} catch (error) {
|
||||
clearPermissionState();
|
||||
@@ -160,11 +148,25 @@ async function savePermissionList(): Promise<void> {
|
||||
await loadAuthorizationScope();
|
||||
await loadActiveRolePermissions();
|
||||
} finally {
|
||||
Toast.error(getErrorMessage(error, "P 保存失败"));
|
||||
Toast.error(getErrorMessage(error, "保存失败"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateNavBar(): void {
|
||||
navBarStore.clearRight();
|
||||
if (canEditActiveRole.value && canUpdateRolePermission.value) {
|
||||
navBarStore.setRightText("保存", "var(--td-brand-color)", savePermissionList);
|
||||
}
|
||||
}
|
||||
|
||||
watch([canEditActiveRole, canUpdateRolePermission], updateNavBar, { immediate: true });
|
||||
|
||||
onMounted(updateNavBar);
|
||||
onUnmounted(() => {
|
||||
navBarStore.clearRight();
|
||||
});
|
||||
|
||||
// ---------- 权限勾选 ----------
|
||||
|
||||
function isPermissionChecked(permissionId: string): boolean {
|
||||
@@ -204,18 +206,7 @@ function clearPermissionState(): void {
|
||||
// ---------- 授权范围 ----------
|
||||
|
||||
async function loadAuthorizationScope(): Promise<void> {
|
||||
const roleList = isSystemAdmin.value ? permissionStore.roleList : await permissionStore.loadManageableRoles();
|
||||
candidateRoleList.value = roleList;
|
||||
}
|
||||
|
||||
function getErrorMessage(error: unknown, fallback: string): string {
|
||||
if (error instanceof Error && error.message) {
|
||||
return error.message;
|
||||
}
|
||||
if (typeof error === "string" && error) {
|
||||
return error;
|
||||
}
|
||||
return fallback;
|
||||
candidateRoleList.value = isSystemAdmin.value ? permissionStore.roleList : await permissionStore.loadManageableRoles();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -232,7 +223,7 @@ onMounted(async () => {
|
||||
.role-permission-assign {
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
padding: calc(var(--app-nav-height) + 4.5rem) 0 6rem 0;
|
||||
padding: calc(var(--app-nav-height) + 4rem) 0 1rem 0;
|
||||
flex-direction: column;
|
||||
|
||||
.header {
|
||||
@@ -241,81 +232,42 @@ onMounted(async () => {
|
||||
right: 0;
|
||||
z-index: 20;
|
||||
display: flex;
|
||||
padding: 0 1rem;
|
||||
position: fixed;
|
||||
background: #fff;
|
||||
box-shadow: var(--td-shadow-1);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.role-selector::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.inherit {
|
||||
gap: .75rem;
|
||||
display: flex;
|
||||
margin: 0 1rem;
|
||||
padding: .75rem 1rem;
|
||||
background: #fff;
|
||||
align-items: center;
|
||||
border-radius: .75rem;
|
||||
justify-content: space-between;
|
||||
|
||||
.label {
|
||||
color: #334155;
|
||||
font-size: .875rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
|
||||
.switch {
|
||||
.show-child-permission {
|
||||
--td-switch-checked-color: #14b8a6;
|
||||
|
||||
gap: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.t-cell__title) {
|
||||
min-width: 0;
|
||||
}
|
||||
.list {
|
||||
|
||||
:deep(.t-cell__title-text) {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
:deep(.t-cell) {
|
||||
|
||||
:deep(.t-cell__description) {
|
||||
min-width: 0;
|
||||
}
|
||||
&.inherited {
|
||||
|
||||
:deep(.t-cell__right) {
|
||||
flex: 0 0 auto;
|
||||
margin-left: .75rem;
|
||||
}
|
||||
.t-cell__title-text {
|
||||
color: #0f766e;
|
||||
}
|
||||
|
||||
.code {
|
||||
width: 100%;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.inherited {
|
||||
:deep(.t-cell__title) {
|
||||
color: #0f766e;
|
||||
.t-switch--checked.t-switch--disabled {
|
||||
background: #14b8a6;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.t-switch--checked.t-switch--disabled) {
|
||||
background: #14b8a6;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.save {
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
bottom: calc(.75rem + env(safe-area-inset-bottom, 0));
|
||||
position: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user