feat: Folder authorization frontend
parent
89749a3006
commit
94560b8394
|
|
@ -12,12 +12,11 @@ const getResourceAuthorization: (
|
|||
workspace_id: string,
|
||||
user_id: string,
|
||||
resource: string,
|
||||
page: pageRequest,
|
||||
params?: any,
|
||||
loading?: Ref<boolean>,
|
||||
) => Promise<Result<any>> = (workspace_id, user_id, resource, page, params, loading) => {
|
||||
) => Promise<Result<any>> = (workspace_id, user_id, resource, params, loading) => {
|
||||
return get(
|
||||
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}/${page.current_page}/${page.page_size}`,
|
||||
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}`,
|
||||
params,
|
||||
loading,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
v-if="canOperation"
|
||||
v-if="canOperation && permissionPrecise.folderManage(data.id)"
|
||||
@click.stop
|
||||
v-show="hoverNodeId === data.id"
|
||||
@mouseenter.stop="handleMouseEnter(data)"
|
||||
|
|
@ -56,30 +56,37 @@
|
|||
class="mr-16"
|
||||
>
|
||||
<el-dropdown trigger="click" :teleported="false">
|
||||
<el-button text class="w-full" v-if="MoreFilledPermission(node)">
|
||||
<el-button text class="w-full" v-if="permissionPrecise.folderManage(data.id)">
|
||||
<AppIcon iconName="app-more"></AppIcon>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
@click.stop="openCreateFolder(data)"
|
||||
v-if="node.level !== 3 && permissionPrecise.folderCreate()"
|
||||
v-if="node.level !== 3 && permissionPrecise.folderManage(data.id)"
|
||||
>
|
||||
<AppIcon iconName="app-add-folder" class="color-secondary"></AppIcon>
|
||||
{{ $t('components.folder.addChildFolder') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.stop="openEditFolder(data)"
|
||||
v-if="permissionPrecise.folderEdit()"
|
||||
v-if="permissionPrecise.folderManage(data.id)"
|
||||
>
|
||||
<AppIcon iconName="app-edit" class="color-secondary"></AppIcon>
|
||||
{{ $t('common.edit') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.stop="openAuthorization(data)"
|
||||
v-if="permissionPrecise.folderManage(data.id)"
|
||||
>
|
||||
<AppIcon iconName="app-resource-authorization" class="color-secondary"></AppIcon>
|
||||
{{ $t('views.system.resourceAuthorization.title') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
divided
|
||||
@click.stop="deleteFolder(data)"
|
||||
:disabled="!data.parent_id"
|
||||
v-if="permissionPrecise.folderDelete()"
|
||||
v-if="permissionPrecise.folderManage(data.id)"
|
||||
>
|
||||
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
|
||||
{{ $t('common.delete') }}
|
||||
|
|
@ -94,6 +101,12 @@
|
|||
</el-scrollbar>
|
||||
</div>
|
||||
<CreateFolderDialog ref="CreateFolderDialogRef" @refresh="refreshFolder" :title="title" />
|
||||
<ResourceAuthorizationDrawer
|
||||
:type="props.source"
|
||||
:is-folder="true"
|
||||
:is-root-folder="!currentNode?.parent_id"
|
||||
ref="ResourceAuthorizationDrawerRef"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -102,6 +115,7 @@ import { computed, onUnmounted, ref, watch } from 'vue'
|
|||
import { onBeforeRouteLeave } from 'vue-router'
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
|
||||
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
|
||||
import { t } from '@/locales'
|
||||
import { i18n_name } from '@/utils/common'
|
||||
import folderApi from '@/api/folder'
|
||||
|
|
@ -255,6 +269,13 @@ function openEditFolder(row: Tree) {
|
|||
CreateFolderDialogRef.value.open(props.source, row.id, row)
|
||||
}
|
||||
|
||||
const currentNode = ref<Tree | null>(null)
|
||||
const ResourceAuthorizationDrawerRef = ref()
|
||||
function openAuthorization(data: any) {
|
||||
currentNode.value = data
|
||||
ResourceAuthorizationDrawerRef.value.open(data.id)
|
||||
}
|
||||
|
||||
function refreshFolder() {
|
||||
emit('refreshTree')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@
|
|||
v-model="row.permission"
|
||||
@change="(val: any) => permissionsHandle(val, row)"
|
||||
>
|
||||
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||
<template v-for="(item, index) in getFolderPermissionOptions()" :key="index">
|
||||
<el-radio :value="item.value" class="mr-16">{{ item.label }}</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
|
|
@ -157,6 +157,8 @@ import useStore from '@/stores'
|
|||
const { user } = useStore()
|
||||
const props = defineProps<{
|
||||
type: string
|
||||
isFolder?: boolean
|
||||
isRootFolder?: boolean
|
||||
}>()
|
||||
|
||||
const apiType = computed(() => {
|
||||
|
|
@ -166,6 +168,24 @@ const apiType = computed(() => {
|
|||
return 'workspace'
|
||||
}
|
||||
})
|
||||
|
||||
const permissionOptionMap = computed(() => {
|
||||
return {
|
||||
rootFolder: getPermissionOptions(true, true),
|
||||
folder: getPermissionOptions(true, false),
|
||||
}
|
||||
})
|
||||
|
||||
const getFolderPermissionOptions = () => {
|
||||
if (props.isRootFolder) {
|
||||
return permissionOptionMap.value.rootFolder
|
||||
}
|
||||
if (props.isFolder) {
|
||||
return permissionOptionMap.value.folder
|
||||
}
|
||||
return getPermissionOptions(false, false)
|
||||
}
|
||||
|
||||
const permissionOptions = computed(() => {
|
||||
return getPermissionOptions()
|
||||
})
|
||||
|
|
@ -281,7 +301,12 @@ const getPermissionList = () => {
|
|||
loading,
|
||||
)
|
||||
.then((res: any) => {
|
||||
permissionData.value = res.data.records || []
|
||||
permissionData.value = res.data.records.map((item: any) => {
|
||||
if (props.isRootFolder && item.permission === 'NOT_AUTH') {
|
||||
return {...item, permission: 'VIEW'}
|
||||
}
|
||||
return item
|
||||
}) || []
|
||||
paginationConfig.total = res.data.total || 0
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ const systemManage = {
|
|||
'OR'
|
||||
),
|
||||
folderEdit: () => false,
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
export: () =>
|
||||
hasPermission(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -23,6 +23,26 @@ const workspace = {
|
|||
],
|
||||
'OR'
|
||||
),
|
||||
folderRead: (folder_id: string) =>
|
||||
hasPermission(
|
||||
[
|
||||
new ComplexPermission([RoleConst.USER],[PermissionConst.APPLICATION.getApplicationWorkspaceResourcePermission(folder_id)],[],'AND'),
|
||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||
PermissionConst.APPLICATION_FOLDER_READ.getApplicationWorkspaceResourcePermission(folder_id),
|
||||
PermissionConst.APPLICATION_FOLDER_READ.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
'OR'
|
||||
),
|
||||
folderManage: (folder_id: string) =>
|
||||
hasPermission(
|
||||
[
|
||||
new ComplexPermission([RoleConst.USER],[PermissionConst.APPLICATION.getApplicationWorkspaceResourcePermission(folder_id)],[],'AND'),
|
||||
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
|
||||
PermissionConst.APPLICATION_FOLDER_EDIT.getApplicationWorkspaceResourcePermission(folder_id),
|
||||
PermissionConst.APPLICATION_EDIT.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
'OR'
|
||||
),
|
||||
edit: (source_id:string) =>
|
||||
hasPermission(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ const systemManage = {
|
|||
PermissionConst.RESOURCE_KNOWLEDGE_AUTH
|
||||
],'OR'
|
||||
),
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -185,6 +185,8 @@ const share = {
|
|||
chat_user_edit: () =>false,
|
||||
|
||||
auth: () => false,
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ const workspaceShare = {
|
|||
problem_edit: () => false,
|
||||
chat_user_edit: () =>false,
|
||||
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ const workspace = {
|
|||
],
|
||||
'OR',
|
||||
),
|
||||
folderRead: () => true,
|
||||
folderManage: () => true,
|
||||
folderCreate: () =>
|
||||
hasPermission(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@ const systemManage = {
|
|||
hasPermission([RoleConst.ADMIN, PermissionConst.RESOURCE_MODEL_DELETE], 'OR'),
|
||||
|
||||
auth: () =>
|
||||
hasPermission([RoleConst.ADMIN, PermissionConst.RESOURCE_MODEL_AUTH], 'OR'),
|
||||
hasPermission([RoleConst.ADMIN, PermissionConst.RESOURCE_MODEL_AUTH], 'OR'),
|
||||
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ const share = {
|
|||
'OR',
|
||||
),
|
||||
auth: () => false,
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ const workspace = {
|
|||
],
|
||||
'OR'
|
||||
),
|
||||
folderRead: () => true,
|
||||
folderManage: () => true,
|
||||
folderCreate: () =>
|
||||
hasPermission(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ const systemManage = {
|
|||
],
|
||||
'OR',
|
||||
),
|
||||
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ const share = {
|
|||
),
|
||||
|
||||
auth: () => false,
|
||||
|
||||
folderRead: () => false,
|
||||
folderManage: () => false,
|
||||
folderCreate: () => false,
|
||||
folderEdit: () => false,
|
||||
folderDelete: () => false,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ const workspace = {
|
|||
],
|
||||
'OR'
|
||||
),
|
||||
folderRead: () => true,
|
||||
folderManage: () => true,
|
||||
folderCreate: () =>
|
||||
hasPermission(
|
||||
[
|
||||
|
|
|
|||
|
|
@ -94,6 +94,13 @@ const PermissionConst = {
|
|||
ROLE_ADD_MEMBER: new Permission('ROLE:READ+ADD_MEMBER'),
|
||||
ROLE_REMOVE_MEMBER: new Permission('ROLE:READ+REMOVE_MEMBER'),
|
||||
|
||||
APPLICATION_FOLDER_READ: new Permission('APPLICATION_FOLDER:READ'),
|
||||
APPLICATION_FOLDER_EDIT: new Permission('APPLICATION_FOLDER:READ+EDIT'),
|
||||
KNOWLEDGE_FOLDER_READ: new Permission('APPLICATION_FOLDER:READ'),
|
||||
KNOWLEDGE_FOLDER_EDIT: new Permission('APPLICATION_FOLDER:READ+EDIT'),
|
||||
TOOL_FOLDER_READ: new Permission('APPLICATION_FOLDER:READ'),
|
||||
TOOL_FOLDER_EDIT: new Permission('APPLICATION_FOLDER:READ+EDIT'),
|
||||
|
||||
KNOWLEDGE_READ: new Permission('KNOWLEDGE:READ'),
|
||||
KNOWLEDGE_CREATE: new Permission('KNOWLEDGE:READ+CREATE'),
|
||||
KNOWLEDGE_SYNC: new Permission('KNOWLEDGE:READ+SYNC'),
|
||||
|
|
|
|||
|
|
@ -67,8 +67,10 @@
|
|||
<el-table-column prop="name" :label="$t('common.name')">
|
||||
<template #default="{ row }">
|
||||
<el-space :size="8">
|
||||
<!-- 文件夹 icon -->
|
||||
<AppIcon v-if="row.resource_type === 'folder'" iconName="app-folder" style="font-size: 20px"></AppIcon>
|
||||
<!-- 知识库 icon -->
|
||||
<KnowledgeIcon :size="20" v-if="isKnowledge" :type="row.icon" />
|
||||
<KnowledgeIcon :size="20" v-else-if="isKnowledge" :type="row.icon" />
|
||||
<!-- 应用/工具 自定义 icon -->
|
||||
<el-avatar
|
||||
v-else-if="isAppIcon(row?.icon) && !isModel"
|
||||
|
|
@ -100,7 +102,7 @@
|
|||
v-model="row.permission"
|
||||
@change="(val: any) => submitPermissions(val, row)"
|
||||
>
|
||||
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||
<template v-for="(item, index) in getRowPermissionOptions(row)" :key="index">
|
||||
<el-radio :value="item.value" class="mr-16">{{ item.label }}</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
|
|
@ -154,6 +156,28 @@ const props = defineProps<{
|
|||
}>()
|
||||
const emit = defineEmits(['submitPermissions'])
|
||||
|
||||
const permissionOptionMap = computed(() => {
|
||||
return {
|
||||
rootFolder: getPermissionOptions(true, true),
|
||||
folder: getPermissionOptions(true, false),
|
||||
resource: getPermissionOptions(false, false),
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const getRowPermissionOptions = (row: any) => {
|
||||
const isFolder = row.resource_type === 'folder'
|
||||
const isRoot = isFolder && row.folder_id === null
|
||||
if (isRoot) {
|
||||
return permissionOptionMap.value.rootFolder
|
||||
}
|
||||
if (isFolder) {
|
||||
return permissionOptionMap.value.folder
|
||||
}
|
||||
return permissionOptionMap.value.resource
|
||||
|
||||
}
|
||||
|
||||
const permissionOptions = computed(() => {
|
||||
return getPermissionOptions()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -23,7 +23,15 @@ const permissionOptions = [
|
|||
]
|
||||
|
||||
|
||||
const getPermissionOptions=()=>{
|
||||
const getPermissionOptions = (isFodler = false, isRootFolder = false) => {
|
||||
if (isFodler && isRootFolder) {
|
||||
return permissionOptions.filter(
|
||||
item => item.value === AuthorizationEnum.VIEW || item.value === AuthorizationEnum.MANAGE
|
||||
)
|
||||
}
|
||||
if (isFodler) {
|
||||
return permissionOptions
|
||||
}
|
||||
if (hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')) {
|
||||
return [...permissionOptions,{
|
||||
label: t('views.system.resourceAuthorization.setting.role'),
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<PermissionTable
|
||||
:data="permissionData"
|
||||
:data="treeData"
|
||||
:type="activeData.type"
|
||||
ref="PermissionTableRef"
|
||||
:getData="getPermissionList"
|
||||
|
|
@ -164,15 +164,59 @@ const getPermissionList = () => {
|
|||
workspaceId,
|
||||
currentUser.value,
|
||||
(route.meta?.resource as string) || 'APPLICATION',
|
||||
PermissionTableRef.value.paginationConfig,
|
||||
params,
|
||||
rLoading,
|
||||
).then((res) => {
|
||||
permissionData.value = res.data.records || []
|
||||
PermissionTableRef.value.paginationConfig.total = res.data.total || 0
|
||||
const resourceType = (route.meta?.resource as string) || 'APPLICATION'
|
||||
|
||||
if (resourceType === 'MODEL') {
|
||||
permissionData.value = res.data || []
|
||||
} else {
|
||||
permissionData.value = res.data.map((item: any) => {
|
||||
if (!item.folder_id && item.permission === 'NOT_AUTH') {
|
||||
return {...item, permission: 'VIEW'}
|
||||
}
|
||||
return item}) || []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const toTree = (nodeList: any, pField: any) => {
|
||||
if (!nodeList || nodeList.length === 0) return []
|
||||
|
||||
const list = JSON.parse(JSON.stringify(nodeList))
|
||||
|
||||
if (!pField) {
|
||||
pField = 'parentId'
|
||||
}
|
||||
const nodeMap = Object.fromEntries(list.map((item: any) => [item.id, item]))
|
||||
|
||||
for (let index = 0; index < nodeList.length; index++) {
|
||||
const element = list[index];
|
||||
if (!element.children) {
|
||||
element.children = []
|
||||
}
|
||||
if (element[pField]) {
|
||||
const pNode = nodeMap[element[pField]]
|
||||
if (pNode) {
|
||||
if (!pNode.children) {
|
||||
pNode.children = []
|
||||
}
|
||||
pNode.children.push(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
return list.filter((item: any) => !item[pField])
|
||||
}
|
||||
|
||||
const treeData = computed(() => {
|
||||
const resourceType = (route.meta?.resource as string) || 'APPLICATION'
|
||||
if (resourceType === 'MODEL') {
|
||||
return permissionData.value
|
||||
}
|
||||
return toTree(permissionData.value, 'folder_id')
|
||||
})
|
||||
|
||||
function clickMemberHandle(item: any) {
|
||||
currentUser.value = item.id
|
||||
currentType.value = item.type
|
||||
|
|
|
|||
Loading…
Reference in New Issue