| | |
| | | <div v-else class="space-y-3"> |
| | | <div class="flex items-center justify-between gap-3"> |
| | | <ElSpace wrap> |
| | | <ElButton @click="handleSelectAll(config.scopeType)">{{ t('pages.system.role.permission.selectAll') }}</ElButton> |
| | | <ElButton @click="handleClear(config.scopeType)">{{ t('pages.system.role.permission.clear') }}</ElButton> |
| | | <ElButton @click="handleSelectAll(config.scopeType)">{{ |
| | | t('pages.system.role.permission.selectAll') |
| | | }}</ElButton> |
| | | <ElButton @click="handleClear(config.scopeType)">{{ |
| | | t('pages.system.role.permission.clear') |
| | | }}</ElButton> |
| | | <ElButton @click="handleToggleExpand(config.scopeType)"> |
| | | {{ |
| | | scopeState[config.scopeType].expandAll |
| | | ? t('common.actions.collapse') |
| | | : t('common.actions.expand') |
| | | }} |
| | | </ElButton> |
| | | </ElSpace> |
| | | <ElButton type="primary" @click="handleSave(config.scopeType)">{{ t('pages.system.role.permission.saveCurrent') }}</ElButton> |
| | | <ElButton type="primary" @click="handleSave(config.scopeType)">{{ |
| | | t('pages.system.role.permission.saveCurrent') |
| | | }}</ElButton> |
| | | </div> |
| | | |
| | | <div class="flex items-center gap-3"> |
| | |
| | | @clear="handleSearch(config.scopeType)" |
| | | @keyup.enter="handleSearch(config.scopeType)" |
| | | /> |
| | | <ElButton @click="handleSearch(config.scopeType)">{{ t('common.actions.search') }}</ElButton> |
| | | <ElButton @click="handleSearch(config.scopeType)">{{ |
| | | t('common.actions.search') |
| | | }}</ElButton> |
| | | </div> |
| | | |
| | | <ElScrollbar height="56vh"> |
| | | <ElTree |
| | | :key="`${config.scopeType}-${scopeState[config.scopeType].treeVersion}`" |
| | | :ref="(el) => setTreeRef(config.scopeType, el)" |
| | | :data="scopeState[config.scopeType].treeData" |
| | | node-key="id" |
| | | show-checkbox |
| | | :default-expand-all="true" |
| | | :default-expand-all="scopeState[config.scopeType].expandAll" |
| | | :default-checked-keys="scopeState[config.scopeType].checkedKeys" |
| | | :props="treeProps" |
| | | @check="handleTreeCheck(config.scopeType)" |
| | |
| | | buildRoleScopeSubmitPayload, |
| | | getRoleScopeConfig, |
| | | normalizeScopeKeys, |
| | | normalizeScopeKey, |
| | | normalizeRoleScopeTreeData |
| | | } from '../rolePage.helpers' |
| | | import { fetchGetRoleScopeList, fetchGetRoleScopeTree, fetchUpdateRoleScope } from '@/api/system-manage' |
| | | import { |
| | | fetchGetRoleScopeList, |
| | | fetchGetRoleScopeTree, |
| | | fetchUpdateRoleScope |
| | | } from '@/api/system-manage' |
| | | import { resolveBackendMenuTitle } from '@/utils/backend-menu-title' |
| | | import { formatMenuTitle } from '@/utils/router' |
| | | import { guardRequestWithMessage } from '@/utils/sys/requestGuard' |
| | |
| | | const emit = defineEmits(['update:visible', 'success']) |
| | | const { t } = useI18n() |
| | | |
| | | const scopeConfigs = ['menu', 'pda', 'matnr', 'warehouse'].map((scopeType) => getRoleScopeConfig(scopeType)) |
| | | const scopeConfigs = ['menu', 'pda', 'matnr', 'warehouse'].map((scopeType) => |
| | | getRoleScopeConfig(scopeType) |
| | | ) |
| | | const activeScopeType = ref(props.scopeType || 'menu') |
| | | const treeRefs = reactive({}) |
| | | const treeProps = { |
| | | label: 'label', |
| | | children: 'children' |
| | | } |
| | | const scopeState = reactive(Object.fromEntries(scopeConfigs.map((config) => [config.scopeType, createScopeTabState()]))) |
| | | const scopeState = reactive( |
| | | Object.fromEntries(scopeConfigs.map((config) => [config.scopeType, createScopeTabState()])) |
| | | ) |
| | | |
| | | const visible = computed({ |
| | | get: () => props.visible, |
| | | set: (value) => emit('update:visible', value) |
| | | }) |
| | | |
| | | const roleLabel = computed(() => props.roleData?.name || props.roleData?.code || t('pages.system.role.permission.unselected')) |
| | | const roleLabel = computed( |
| | | () => |
| | | props.roleData?.name || props.roleData?.code || t('pages.system.role.permission.unselected') |
| | | ) |
| | | |
| | | function createScopeTabState() { |
| | | return { |
| | |
| | | treeData: [], |
| | | checkedKeys: [], |
| | | halfCheckedKeys: [], |
| | | condition: '' |
| | | condition: '', |
| | | expandAll: true, |
| | | treeVersion: 0 |
| | | } |
| | | } |
| | | |
| | |
| | | const selectionRequest = reloadSelection |
| | | ? fetchGetRoleScopeList(config.scopeType, props.roleData.id) |
| | | : Promise.resolve(state.checkedKeys) |
| | | const treeRequest = fetchGetRoleScopeTree(config.scopeType, { condition: state.condition || '' }) |
| | | const treeRequest = fetchGetRoleScopeTree(config.scopeType, { |
| | | condition: state.condition || '' |
| | | }) |
| | | |
| | | const guardedResult = await guardRequestWithMessage( |
| | | Promise.all([selectionRequest, treeRequest]), |
| | | null, |
| | | { |
| | | timeoutMessage: t('pages.system.role.permission.scopeLoadTimeout', { title: config.title }) |
| | | timeoutMessage: t('pages.system.role.permission.scopeLoadTimeout', { |
| | | title: config.title |
| | | }) |
| | | } |
| | | ) |
| | | if (!guardedResult) { |
| | |
| | | state.treeData = normalizeRoleScopeTreeData(config.scopeType, treeData) |
| | | state.checkedKeys = normalizeScopeKeys(checkedIds) |
| | | state.halfCheckedKeys = [] |
| | | state.treeVersion += 1 |
| | | state.loaded = true |
| | | } catch (error) { |
| | | ElMessage.error(error?.message || t('pages.system.role.permission.scopeLoadFailed', { title: config.title })) |
| | | ElMessage.error( |
| | | error?.message || t('pages.system.role.permission.scopeLoadFailed', { title: config.title }) |
| | | ) |
| | | } finally { |
| | | state.loading = false |
| | | nextTick(() => { |
| | |
| | | handleTreeCheck(scopeType) |
| | | } |
| | | |
| | | const handleToggleExpand = (scopeType) => { |
| | | const state = scopeState[scopeType] |
| | | state.expandAll = !state.expandAll |
| | | state.treeVersion += 1 |
| | | nextTick(() => { |
| | | treeRefs[scopeType]?.setCheckedKeys(state.checkedKeys) |
| | | handleTreeCheck(scopeType) |
| | | }) |
| | | } |
| | | |
| | | const handleSave = async (scopeType) => { |
| | | if (!props.roleData?.id) return |
| | | try { |
| | |
| | | } |
| | | if (activeScopeType.value === 'menu') { |
| | | const resolvedTitle = resolveBackendMenuTitle(rawLabel, data?.component || '') |
| | | return resolvedTitle ? formatMenuTitle(resolvedTitle) : '' |
| | | return resolvedTitle ? formatMenuTitle(resolvedTitle) : rawLabel |
| | | } |
| | | return rawLabel |
| | | } |
| | |
| | | } |
| | | ) |
| | | |
| | | watch( |
| | | activeScopeType, |
| | | async (scopeType) => { |
| | | if (props.visible && scopeType) { |
| | | await ensureScopeLoaded(scopeType) |
| | | } |
| | | watch(activeScopeType, async (scopeType) => { |
| | | if (props.visible && scopeType) { |
| | | await ensureScopeLoaded(scopeType) |
| | | } |
| | | ) |
| | | }) |
| | | </script> |