diff --git a/src/pages/permission/RoleDelegationPermissionAssign.vue b/src/pages/permission/RoleDelegationPermissionAssign.vue index b376830..62bd4db 100644 --- a/src/pages/permission/RoleDelegationPermissionAssign.vue +++ b/src/pages/permission/RoleDelegationPermissionAssign.vue @@ -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 { 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(); diff --git a/src/pages/permission/RoleEdit.vue b/src/pages/permission/RoleEdit.vue index 3397f23..93b9b61 100644 --- a/src/pages/permission/RoleEdit.vue +++ b/src/pages/permission/RoleEdit.vue @@ -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 { 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 { diff --git a/src/pages/permission/RoleList.vue b/src/pages/permission/RoleList.vue index d97b0a3..2ec480a 100644 --- a/src/pages/permission/RoleList.vue +++ b/src/pages/permission/RoleList.vue @@ -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 { } } -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; -} - diff --git a/src/pages/permission/RolePermissionAssign.vue b/src/pages/permission/RolePermissionAssign.vue index cbabaa1..69351e2 100644 --- a/src/pages/permission/RolePermissionAssign.vue +++ b/src/pages/permission/RolePermissionAssign.vue @@ -13,21 +13,23 @@ @change="handleRoleChange" /> +
+ 显示继承权限 + +
-
- 显示继承权限 - -
- + - @@ -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([]); -const unmanagedPermissionIds = ref([]); -const inheritedPermissionIds = ref([]); -const grantablePermissionList = ref([]); const candidateRoleList = ref([]); const showChildRolePermissions = ref(false); let permissionSyncSeq = 0; @@ -94,16 +86,12 @@ const roleOptions = computed(() => candidateRoleList.value disabled: false }))); -const rolePermissionWriteAccess = { - value: [ - corePermissionCodes.rolePermission.create, - corePermissionCodes.rolePermission.delete - ], - mode: "and" -} as const; - // ---------- 权限状态 ---------- +const checkedPermissionIds = ref([]); +const unmanagedPermissionIds = ref([]); +const inheritedPermissionIds = ref([]); +const grantablePermissionList = ref([]); const checkedPermissionIdSet = computed(() => new Set(checkedPermissionIds.value)); const inheritedPermissionIdSet = computed(() => new Set(inheritedPermissionIds.value)); @@ -152,7 +140,7 @@ async function savePermissionList(): Promise { ...checkedPermissionIds.value, ...unmanagedPermissionIds.value ]))); - Toast.success("P 已保存"); + Toast.success("已保存"); await loadActiveRolePermissions(); } catch (error) { clearPermissionState(); @@ -160,11 +148,25 @@ async function savePermissionList(): Promise { 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 { - 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; } } diff --git a/src/pages/user/UserRoleAssign.vue b/src/pages/user/UserRoleAssign.vue index f786240..26f9dd6 100644 --- a/src/pages/user/UserRoleAssign.vue +++ b/src/pages/user/UserRoleAssign.vue @@ -54,6 +54,7 @@ import ManagedUserAPI from "@/api/ManagedUserAPI"; import { useCurrentStoreStore } from "@/store/currentStoreStore"; import type { Role } from "@/store/permissionSettingsStore"; import type { ManagedUser } from "@/types/ManagedUser"; +import { getErrorMessage } from "@/utils/error"; import { corePermissionCodes, gaoRoleCodes } from "@/utils/permission"; defineOptions({ @@ -270,16 +271,6 @@ function getRoleId(role: UserRole | string): string { return fullRole?.id || ""; } -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; -} - function setRoleChecked(roleId: string, value: boolean): void { if (value && !checkedRoleIds.value.includes(roleId)) { checkedRoleIds.value.push(roleId); diff --git a/src/router/routes/permissionRoutes.ts b/src/router/routes/permissionRoutes.ts index 909eae1..b079d77 100644 --- a/src/router/routes/permissionRoutes.ts +++ b/src/router/routes/permissionRoutes.ts @@ -73,7 +73,7 @@ const permissionRoutes: RouteRecordRaw[] = [ depth: 6, navBarVisible: true, navBarCanBack: true, - navBarTitle: "角色直接权限 P", + navBarTitle: "角色直接授权权限 P", tabBarVisible: false, bodyBackground: "#F5F5F8", darkBodyBackground: "#10161f" @@ -147,7 +147,7 @@ const permissionRoutes: RouteRecordRaw[] = [ depth: 4, navBarVisible: true, navBarCanBack: true, - navBarTitle: "角色直接权限 P", + navBarTitle: "角色直接授权权限 P", tabBarVisible: false, bodyBackground: "#F5F5F8", darkBodyBackground: "#10161f" diff --git a/src/utils/error.ts b/src/utils/error.ts new file mode 100644 index 0000000..ebb924e --- /dev/null +++ b/src/utils/error.ts @@ -0,0 +1,15 @@ +/** + * 从未知错误值中提取可展示的错误文案。 + * + * @param error 未知错误值 + * @param fallback 无法提取错误文案时的备用文案 + */ +export 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; +}