优化
This commit is contained in:
@@ -93,10 +93,12 @@ describe('RolesView', () => {
|
||||
vi.mocked(createPlatformRole).mockReset()
|
||||
})
|
||||
|
||||
it('keeps directory, menu, and action permissions independently checkable', () => {
|
||||
it('links menu groups and permissions so partial selections use the half-checked state', () => {
|
||||
const wrapper = mountView()
|
||||
|
||||
expect(wrapper.get('[data-testid="permission-tree"]').attributes('data-check-strictly')).toBe('true')
|
||||
expect(wrapper.get('[data-testid="permission-tree"]').attributes('data-check-strictly')).toBe('false')
|
||||
expect(rolesSource).not.toContain('check-strictly')
|
||||
expect(rolesSource).not.toContain("disabled: 'disabled'")
|
||||
})
|
||||
|
||||
it('shows the role code in the default list layout', () => {
|
||||
|
||||
@@ -24,8 +24,9 @@ import ListPageLayout from '@/shared/components/ListPageLayout.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import { useUnsavedWorkRegistration } from '@/core/unsaved-work/useUnsavedWorkRegistration'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { adminNavigation } from '@/core/navigation/adminNavigation'
|
||||
import type { Permission, Role } from '@/modules/iam/types'
|
||||
import { buildPermissionTree, summarizePermissionSelection } from '@/modules/iam/utils/permissionTree'
|
||||
import { buildNavigationPermissionTree, summarizePermissionSelection } from '@/modules/iam/utils/permissionTree'
|
||||
import { mapPlatformPermission } from '@/modules/iam/utils/platformPermission'
|
||||
|
||||
interface TreeController {
|
||||
@@ -88,7 +89,9 @@ const roleColumns: DataTableColumn[] = [
|
||||
{ key: 'status', label: '状态', width: 88, slotName: 'status' },
|
||||
]
|
||||
const availablePermissions = computed(() => serverPermissions.value)
|
||||
const permissionTree = computed(() => buildPermissionTree(availablePermissions.value))
|
||||
const permissionTree = computed(() => buildNavigationPermissionTree(availablePermissions.value, adminNavigation))
|
||||
const permissionGroupIds = computed(() => permissionTree.value.map((node) => node.id))
|
||||
const assignablePermissionIds = computed(() => new Set(availablePermissions.value.map((permission) => permission.id)))
|
||||
|
||||
function applyFilters() {
|
||||
appliedFilters.value = { ...filters.value }
|
||||
@@ -144,8 +147,8 @@ function openEdit(row: Role) {
|
||||
}
|
||||
|
||||
function selectedPermissionIds() {
|
||||
const checked = treeRef.value?.getCheckedKeys(false).map(String) || []
|
||||
const halfChecked = treeRef.value?.getHalfCheckedKeys().map(String) || []
|
||||
const checked = treeRef.value?.getCheckedKeys(false).map(String).filter((id) => assignablePermissionIds.value.has(id)) || []
|
||||
const halfChecked = treeRef.value?.getHalfCheckedKeys().map(String).filter((id) => assignablePermissionIds.value.has(id)) || []
|
||||
return [...new Set([...checked, ...halfChecked])]
|
||||
}
|
||||
|
||||
@@ -258,7 +261,7 @@ onMounted(loadRoles)
|
||||
<el-form-item label="角色编码" prop="code" required><el-input v-model="form.code" :disabled="Boolean(form.id)" placeholder="如:ORDER_OPERATOR" maxlength="64" /></el-form-item>
|
||||
<el-form-item label="角色说明"><el-input v-model="form.description" :disabled="Boolean(form.id) && !canEdit" type="textarea" :rows="3" placeholder="说明该角色的工作范围" maxlength="200" show-word-limit /></el-form-item>
|
||||
</FormSection>
|
||||
<FormSection v-if="canGrant" title="菜单与操作权限" :description="`保存时按后端契约全量替换当前角色权限;当前 ${form.permissionIds.length} 项授权。`" class="role-editor-permissions"><el-tree ref="treeRef" class="permission-tree" :data="permissionTree" node-key="id" show-checkbox check-strictly default-expand-all :props="{ label: 'name', children: 'children' }" @check="syncPermissionIds"><template #default="{ data }"><div class="permission-node"><span>{{ data.name }}</span><code>{{ data.code }}</code></div></template></el-tree></FormSection>
|
||||
<FormSection v-if="canGrant" title="菜单与操作权限" :description="`按当前后台菜单分组;勾选上级可全选下级,部分选中时显示半选,当前 ${form.permissionIds.length} 项授权。`" class="role-editor-permissions"><el-tree ref="treeRef" class="permission-tree" :data="permissionTree" node-key="id" show-checkbox :default-expanded-keys="permissionGroupIds" :props="{ label: 'name', children: 'children' }" @check="syncPermissionIds"><template #default="{ data }"><div class="permission-node" :class="{ 'is-navigation-group': !data.permissionId }"><span>{{ data.name }}</span><code v-if="data.code">{{ data.code }}</code></div></template></el-tree></FormSection>
|
||||
</div>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
@@ -268,7 +271,10 @@ onMounted(loadRoles)
|
||||
<style scoped>
|
||||
.role-editor-layout { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.3fr); gap: 20px; }
|
||||
.role-editor-permissions { min-width: 0; padding-left: 20px; border-left: 1px solid var(--cc-border); }
|
||||
.permission-tree { max-height: 380px; overflow-y: auto; }
|
||||
.permission-tree { max-height: 380px; overflow-x: hidden; overflow-y: auto; }
|
||||
.permission-node span { min-width: 0; }
|
||||
.permission-node code { max-width: 58%; white-space: normal; text-align: right; }
|
||||
.permission-node.is-navigation-group span { font-weight: 650; }
|
||||
:global(.role-editor-dialog) { max-height: min(760px, calc(100vh - 32px)); display: flex; flex-direction: column; }
|
||||
:global(.role-editor-dialog .el-dialog__body) { min-height: 0; overflow-y: auto; }
|
||||
:global(.role-editor-dialog .el-dialog__footer) { flex: 0 0 auto; }
|
||||
|
||||
Reference in New Issue
Block a user