Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 142 additions & 117 deletions apps/common/auth/constants/permission_constants.py

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion apps/common/auth/struct/permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ class PermissionMeta:
category: Optional[Category] = None
resource_permission_group_list: Optional[list] = None
scope: list[PermissionScopeConstants] = field(default_factory=list)
is_ee: bool = False
is_ee: bool = True
# 角色 -> 分类 覆盖表;未列出的角色默认归入 OTHER
role_category_map: Optional[dict] = None


@dataclass(frozen=True)
Expand Down
10 changes: 8 additions & 2 deletions ui/src/api/admin/system/role.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { del, get, post } from '../core/request'
import type { ParamsPage, ResponsePage } from '../core/types'
import type { CreateRoleMembersRequest, Dict, RoleItem, RoleMember, RolePermissionModule, RolePayload, SaveRolePermissionRequest } from '@/api/types'
import type { CreateRoleMembersRequest, Dict, RoleItem, RoleMember, RolePermissionModule, RolePayload, RoleType, SaveRolePermissionRequest } from '@/api/types'

const prefix = '/system/role'

/** 获取内置角色与自定义角色列表。 */
const getRoleList = () => {
return get<{ internal_role: RoleItem[]; custom_role: RoleItem[] }>(prefix)
return get<{ internal_role: RoleItem[]; custom_role: RoleItem[] } | Array<{ role_type: RoleType; role_list: RoleItem[] }>>(prefix).then((data) => {
if (Array.isArray(data)) {
// 后端按角色类型分组返回 { role_type, role_list },展平为扁平角色数组
return data.flatMap((group) => group.role_list ?? [])
}
return [...(data.internal_role ?? []), ...(data.custom_role ?? [])]
})
}

/** 创建或重命名自定义角色。 */
Expand Down
10 changes: 8 additions & 2 deletions ui/src/api/types/system-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@ export interface RolePermission {
export interface RolePermissionFeature {
id: string
name: string
enable: boolean
enable?: boolean
permission: RolePermission[]
}

export interface RolePermissionModule {
export interface RolePermissionModuleGroup {
id: string
name: string
children: RolePermissionFeature[]
}

export interface RolePermissionModule {
id: string
name: string
children: RolePermissionModuleGroup[]
}

export interface RolePayload {
role_id?: string
role_name: string
Expand Down
6 changes: 3 additions & 3 deletions ui/src/views/system/identity/roles/RoleListView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ const roleGroups = computed(() => {
function loadRoles(selectedRoleId?: string) {
loadingRoles.value = true
return RoleApi.getRoleList()
.then(({ internal_role, custom_role }) => {
AllRoles.value = [...internal_role, ...custom_role]
.then((roles) => {
AllRoles.value = roles
currentRole.value =
AllRoles.value.find(({ id }) => id === selectedRoleId) ?? AllRoles.value.find(({ id }) => id === currentRole.value?.id) ?? internal_role[0]
AllRoles.value.find(({ id }) => id === selectedRoleId) ?? AllRoles.value.find(({ id }) => id === currentRole.value?.id) ?? AllRoles.value[0]
})
.finally(() => {
loadingRoles.value = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { MsgSuccess } from '@/utils/message'

interface PermissionTableRow {
id: string
categoryId: string
category: string
moduleId: string
module: string
name: string
Expand All @@ -30,15 +32,35 @@ function loadPermissions() {
}

function transformPermissions(modules: RolePermissionModule[]) {
return modules.flatMap((module) =>
module.children.map((feature) => ({ id: `${module.id}:${feature.id}`, moduleId: module.id, module: module.name, name: feature.name, permissions: feature.permission })),
// 后端返回 分类(category) → 分组(group) → 叶子(feature) → 权限 的结构,
// 分类 → “分类”列,分组 → “模块名称”列,叶子 → “操作对象”列,向下展平为表格行
return modules.flatMap((category) =>
category.children.flatMap((group) =>
group.children.map((feature) => ({
id: `${category.id}:${group.id}:${feature.id}`,
categoryId: category.id,
category: category.name,
moduleId: `${category.id}:${group.id}`,
module: group.name,
name: feature.name,
permissions: feature.permission,
})),
),
)
}

function permissionTableSpan({ row, rowIndex, columnIndex }: { row: PermissionTableRow; rowIndex: number; columnIndex: number }) {
if (columnIndex !== 0) return [1, 1]
const firstRowIndex = permissionData.value.findIndex(({ moduleId }) => moduleId === row.moduleId)
return rowIndex === firstRowIndex ? [permissionData.value.filter(({ moduleId }) => moduleId === row.moduleId).length, 1] : [0, 0]
if (columnIndex === 0) {
// “分类”列按分类纵向合并
const firstRowIndex = permissionData.value.findIndex(({ categoryId }) => categoryId === row.categoryId)
return rowIndex === firstRowIndex ? [permissionData.value.filter(({ categoryId }) => categoryId === row.categoryId).length, 1] : [0, 0]
}
if (columnIndex === 1) {
// “模块名称”列按分组纵向合并
const firstRowIndex = permissionData.value.findIndex(({ moduleId }) => moduleId === row.moduleId)
return rowIndex === firstRowIndex ? [permissionData.value.filter(({ moduleId }) => moduleId === row.moduleId).length, 1] : [0, 0]
}
return [1, 1]
}

/* 单项权限与查看权限联动 */
Expand Down Expand Up @@ -96,6 +118,7 @@ watch(() => props.currentRole.id, loadPermissions, { immediate: true })
:data="permissionData"
v-loading="loading"
>
<el-table-column prop="category" label="分类" width="120" />
<el-table-column prop="module" label="模块名称" width="150" />
<el-table-column prop="name" label="操作对象" width="150" />
<el-table-column label="权限">
Expand Down
Loading