mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-30 01:32:49 +00:00
feat: System resource authorization function (#3861)
Co-authored-by: wangdan-fit2cloud <dan.wang@fit2cloud.com>
This commit is contained in:
parent
f78e24105f
commit
c0b2aa3688
|
|
@ -1,8 +1,7 @@
|
|||
import { Permission } from '@/utils/permission/type'
|
||||
import { Result } from '@/request/Result'
|
||||
import { get, put, post, del } from '@/request/index'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
import type { Ref } from 'vue'
|
||||
import type { pageRequest } from '@/api/type/common'
|
||||
const prefix = '/workspace'
|
||||
|
||||
/**
|
||||
|
|
@ -13,11 +12,13 @@ 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, loading) => {
|
||||
) => Promise<Result<any>> = (workspace_id, user_id, resource, page, params, loading) => {
|
||||
return get(
|
||||
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}`,
|
||||
undefined,
|
||||
`${prefix}/${workspace_id}/user_resource_permission/user/${user_id}/resource/${resource}/${page.current_page}/${page.page_size}`,
|
||||
params,
|
||||
loading,
|
||||
)
|
||||
}
|
||||
|
|
@ -26,18 +27,12 @@ const getResourceAuthorization: (
|
|||
* 修改成员权限
|
||||
* @param 参数 member_id
|
||||
* @param 参数 {
|
||||
"team_resource_permission_list": [
|
||||
{
|
||||
"auth_target_type": "KNOWLEDGE",
|
||||
"target_id": "string",
|
||||
"auth_type": "ROLE",
|
||||
"permission": {
|
||||
"VIEW": true,
|
||||
"MANAGE": true,
|
||||
"ROLE": true
|
||||
}
|
||||
}
|
||||
]
|
||||
[
|
||||
{
|
||||
"target_id": "string",
|
||||
"permission": "NOT_AUTH"
|
||||
}
|
||||
]
|
||||
}
|
||||
*/
|
||||
const putResourceAuthorization: (
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@
|
|||
:type="type" :send-message="sendMessage" :chat-management="ChatManagement"
|
||||
:executionIsRightPanel="props.executionIsRightPanel"
|
||||
@open-execution-detail="emit('openExecutionDetail', chatList[index])"
|
||||
@openParagraph="emit('openParagraph', chatList[index])" @openParagraphDocument="
|
||||
@openParagraph="emit('openParagraph', chatList[index])"
|
||||
@openParagraphDocument="
|
||||
(val: any) => emit('openParagraphDocument', chatList[index], val)
|
||||
"></AnswerContent>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ export enum AuthorizationEnum {
|
|||
MANAGE = 'MANAGE',
|
||||
VIEW = 'VIEW',
|
||||
ROLE = 'ROLE',
|
||||
NOT_AUTH = 'NOT_AUTH',
|
||||
KNOWLEDGE = 'KNOWLEDGE',
|
||||
APPLICATION = 'APPLICATION',
|
||||
MODEL = 'MODEL',
|
||||
|
|
|
|||
|
|
@ -109,18 +109,20 @@ export default {
|
|||
enableSSL: 'Enable SSL (if the SMTP port is 465, you usually need to enable SSL)',
|
||||
enableTLS: 'Enable TLS (if the SMTP port is 587, you usually need to enable TLS)',
|
||||
},
|
||||
|
||||
resourceAuthorization: {
|
||||
title: 'Resource Authorization',
|
||||
member: 'Member',
|
||||
permissionSetting: 'Permission Setting',
|
||||
setting: {
|
||||
management: 'management',
|
||||
managementDesc: 'Can delete or modify this resource',
|
||||
check: 'check',
|
||||
authorization: 'authorization',
|
||||
},
|
||||
priority: {
|
||||
label: 'Resource permission priority',
|
||||
role: 'Role',
|
||||
checkDesc: 'Can only view the resource',
|
||||
role: 'User Role',
|
||||
roleDesc: 'Authorize users based on their roles to access this resource',
|
||||
notAuthorized: 'Not Authorized',
|
||||
configure: 'Configure Permission',
|
||||
},
|
||||
},
|
||||
resource_management: {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import role from './role'
|
||||
|
||||
export default {
|
||||
title: '系统管理',
|
||||
subTitle: '系统设置',
|
||||
|
|
@ -115,12 +117,13 @@ export default {
|
|||
permissionSetting: '资源权限配置',
|
||||
setting: {
|
||||
management: '管理',
|
||||
managementDesc: '可对该资源进行删改操作',
|
||||
check: '查看',
|
||||
authorization: '授权',
|
||||
},
|
||||
priority: {
|
||||
label: '资源权限优先级',
|
||||
role: '按角色',
|
||||
checkDesc: '仅能查看使用该资源',
|
||||
role: '按用户角色',
|
||||
roleDesc: '根据用户角色中的权限授权用户对该资源的操作权限',
|
||||
notAuthorized: '不授权',
|
||||
configure: '配置权限',
|
||||
},
|
||||
},
|
||||
resource_management: {
|
||||
|
|
|
|||
|
|
@ -109,18 +109,20 @@ export default {
|
|||
enableSSL: '啟用 SSL(如果 SMTP 端口是 465,通常需要啟用 SSL)',
|
||||
enableTLS: '啟用 TLS(如果 SMTP 端口是 587,通常需要啟用 TLS)',
|
||||
},
|
||||
|
||||
resourceAuthorization: {
|
||||
title: '資源授权',
|
||||
title: '資源授權',
|
||||
member: '成員',
|
||||
permissionSetting: '資源权限配置',
|
||||
permissionSetting: '資源權限配置',
|
||||
setting: {
|
||||
management: '管理',
|
||||
managementDesc: '可對該資源進行刪改操作',
|
||||
check: '查看',
|
||||
authorization: '授权',
|
||||
},
|
||||
priority: {
|
||||
label: '資源权限优先级',
|
||||
role: '按角色',
|
||||
checkDesc: '僅能查看使用該資源',
|
||||
role: '按用戶角色',
|
||||
roleDesc: '根據用戶角色中的權限授權用戶對該資源的操作權限',
|
||||
notAuthorized: '不授權',
|
||||
configure: '配置權限',
|
||||
},
|
||||
},
|
||||
resource_management: {
|
||||
|
|
|
|||
|
|
@ -359,12 +359,12 @@ const nextChatRecord = () => {
|
|||
}
|
||||
}
|
||||
const pre_disable = computed(() => {
|
||||
let index = tableIndexMap.value[currentChatId.value] - 1
|
||||
const index = tableIndexMap.value[currentChatId.value] - 1
|
||||
return index < 0 && paginationConfig.current_page <= 1
|
||||
})
|
||||
|
||||
const next_disable = computed(() => {
|
||||
let index = tableIndexMap.value[currentChatId.value] + 1
|
||||
const index = tableIndexMap.value[currentChatId.value] + 1
|
||||
return (
|
||||
index >= tableData.value.length &&
|
||||
index + (paginationConfig.current_page - 1) * paginationConfig.page_size >=
|
||||
|
|
|
|||
|
|
@ -51,10 +51,11 @@
|
|||
>{{ $t('views.document.generateQuestion.title') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="openknowledgeDialog()"
|
||||
@click="openBatchEditDocument"
|
||||
:disabled="multipleSelection.length === 0"
|
||||
v-if="permissionPrecise.doc_migrate(id)"
|
||||
>{{ $t('views.document.setting.migration') }}
|
||||
v-if="permissionPrecise.doc_edit(id)"
|
||||
>
|
||||
{{ $t('common.setting') }}
|
||||
</el-button>
|
||||
<el-dropdown v-if="MoreFilledPermission0(id)">
|
||||
<el-button class="ml-12 mr-12">
|
||||
|
|
@ -63,11 +64,11 @@
|
|||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
@click="openBatchEditDocument"
|
||||
@click="openknowledgeDialog()"
|
||||
:disabled="multipleSelection.length === 0"
|
||||
v-if="permissionPrecise.doc_edit(id)"
|
||||
v-if="permissionPrecise.doc_migrate(id)"
|
||||
>
|
||||
{{ $t('common.setting') }}
|
||||
{{ $t('views.document.setting.migration') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
divided
|
||||
|
|
@ -434,16 +435,12 @@
|
|||
"
|
||||
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-generate-question"
|
||||
class="color-secondary"
|
||||
></AppIcon>
|
||||
<el-icon class="color-secondary"><Close /></el-icon>
|
||||
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
@click="openGenerateDialog(row)"
|
||||
v-if="permissionPrecise.doc_generate(id)"
|
||||
v-else-if="permissionPrecise.doc_generate(id)"
|
||||
>
|
||||
<AppIcon
|
||||
iconName="app-generate-question"
|
||||
|
|
@ -494,18 +491,6 @@
|
|||
</span>
|
||||
</template>
|
||||
<template v-if="knowledgeDetail?.type === 1 || knowledgeDetail?.type === 2">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('views.knowledge.setting.sync')"
|
||||
placement="top"
|
||||
v-if="permissionPrecise.sync(id)"
|
||||
>
|
||||
<span class="mr-4">
|
||||
<el-button type="primary" text @click.stop="syncDocument(row)">
|
||||
<AppIcon iconName="app-sync"></AppIcon>
|
||||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('views.document.setting.cancelVectorization')"
|
||||
|
|
@ -538,6 +523,18 @@
|
|||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$t('common.setting')"
|
||||
placement="top"
|
||||
v-if="permissionPrecise.doc_edit(id)"
|
||||
>
|
||||
<span class="mr-4">
|
||||
<el-button type="primary" text @click.stop="settingDoc(row)">
|
||||
<AppIcon iconName="app-setting"></AppIcon>
|
||||
</el-button>
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<span @click.stop>
|
||||
<el-dropdown trigger="click" v-if="MoreFilledPermission2(id)">
|
||||
<el-button text type="primary">
|
||||
|
|
@ -546,11 +543,11 @@
|
|||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
@click="settingDoc(row)"
|
||||
v-if="permissionPrecise.doc_edit(id)"
|
||||
@click="syncDocument(row)"
|
||||
v-if="permissionPrecise.sync(id)"
|
||||
>
|
||||
<AppIcon iconName="app-setting"></AppIcon>
|
||||
{{ $t('common.setting') }}</el-dropdown-item
|
||||
<AppIcon iconName="app-sync" class="color-secondary"></AppIcon>
|
||||
{{ $t('views.knowledge.setting.sync') }}</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item
|
||||
v-if="
|
||||
|
|
@ -561,43 +558,45 @@
|
|||
"
|
||||
@click="cancelTask(row, TaskType.GENERATE_PROBLEM)"
|
||||
>
|
||||
<AppIcon iconName="app-generate-question"></AppIcon>
|
||||
<el-icon class="color-secondary"><Close /></el-icon>
|
||||
{{ $t('views.document.setting.cancelGenerateQuestion') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-else
|
||||
@click="openGenerateDialog(row)"
|
||||
v-if="permissionPrecise.doc_generate(id)"
|
||||
v-else-if="permissionPrecise.doc_generate(id)"
|
||||
>
|
||||
<AppIcon iconName="app-generate-question"></AppIcon>
|
||||
<AppIcon
|
||||
iconName="app-generate-question"
|
||||
class="color-secondary"
|
||||
></AppIcon>
|
||||
{{ $t('views.document.generateQuestion.title') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click="openknowledgeDialog(row)"
|
||||
v-if="permissionPrecise.doc_migrate(id)"
|
||||
>
|
||||
<AppIcon iconName="app-migrate"></AppIcon>
|
||||
<AppIcon iconName="app-migrate" class="color-secondary"></AppIcon>
|
||||
{{ $t('views.document.setting.migration') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click="exportDocument(row)"
|
||||
v-if="permissionPrecise.doc_export(id)"
|
||||
>
|
||||
<AppIcon iconName="app-export"></AppIcon>
|
||||
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||
{{ $t('views.document.setting.export') }} Excel
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click="exportDocumentZip(row)"
|
||||
v-if="permissionPrecise.doc_export(id)"
|
||||
>
|
||||
<AppIcon iconName="app-export"></AppIcon>
|
||||
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
|
||||
{{ $t('views.document.setting.export') }} Zip
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.stop="deleteDocument(row)"
|
||||
v-if="permissionPrecise.doc_delete(id)"
|
||||
>
|
||||
<AppIcon iconName="app-delete"></AppIcon>
|
||||
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
|
||||
{{ $t('common.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
|
|
@ -712,7 +711,7 @@ const permissionPrecise = computed(() => {
|
|||
|
||||
const MoreFilledPermission0 = (id: string) => {
|
||||
return (
|
||||
permissionPrecise.value.doc_edit(id) ||
|
||||
permissionPrecise.value.doc_migrate(id) ||
|
||||
(knowledgeDetail?.value.type === 1 && permissionPrecise.value.doc_sync(id)) ||
|
||||
(knowledgeDetail?.value.type === 2 && permissionPrecise.value.doc_sync(id)) ||
|
||||
permissionPrecise.value.doc_delete(id)
|
||||
|
|
@ -731,7 +730,7 @@ const MoreFilledPermission1 = (id: string) => {
|
|||
|
||||
const MoreFilledPermission2 = (id: string) => {
|
||||
return (
|
||||
permissionPrecise.value.doc_edit(id) ||
|
||||
permissionPrecise.value.sync(id) ||
|
||||
permissionPrecise.value.doc_generate(id) ||
|
||||
permissionPrecise.value.doc_migrate(id) ||
|
||||
permissionPrecise.value.doc_export(id) ||
|
||||
|
|
|
|||
|
|
@ -47,11 +47,10 @@ import { groupBy } from 'lodash'
|
|||
import type { knowledgeData } from '@/api/type/knowledge'
|
||||
import { t } from '@/locales'
|
||||
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
|
||||
import modelResourceApi from '@/api/system-resource-management/model'
|
||||
const props = defineProps<{
|
||||
data?: {
|
||||
type: Object
|
||||
default: () => {}
|
||||
type: object
|
||||
default: () => null
|
||||
}
|
||||
apiType: 'systemShare' | 'workspace' | 'systemManage'
|
||||
}>()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,308 @@
|
|||
<template>
|
||||
<div class="permission-setting p-24 flex">
|
||||
<div class="resource-authorization__table">
|
||||
<h4 class="mb-16">{{ $t('views.system.resourceAuthorization.permissionSetting') }}</h4>
|
||||
<div class="flex-between mb-16">
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="
|
||||
hasPermission(permissionObj[(route.meta?.resource as string) || 'APPLICATION'], 'OR')
|
||||
"
|
||||
:disabled="multipleSelection.length === 0"
|
||||
@click="openMulConfigureDialog"
|
||||
>{{ $t('views.system.resourceAuthorization.setting.configure') }}</el-button
|
||||
>
|
||||
|
||||
<div class="flex-between complex-search">
|
||||
<el-select
|
||||
class="complex-search__left"
|
||||
v-model="searchType"
|
||||
style="width: 80px"
|
||||
@change="search_type_change"
|
||||
>
|
||||
<el-option :label="$t('common.name')" value="name" />
|
||||
<el-option
|
||||
:label="$t('views.model.modelForm.permissionType.label')"
|
||||
value="publish_status"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-if="searchType === 'name'"
|
||||
v-model="searchForm.name"
|
||||
@change="searchHandle"
|
||||
:placeholder="$t('common.searchBar.placeholder')"
|
||||
style="width: 220px"
|
||||
clearable
|
||||
/>
|
||||
<el-select
|
||||
v-else-if="searchType === 'publish_status'"
|
||||
v-model="searchForm.publish_status"
|
||||
@change="searchHandle"
|
||||
filterable
|
||||
clearable
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
style="width: 220px"
|
||||
>
|
||||
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||
<el-option :label="item.label" :value="item.value" />
|
||||
</template>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-table
|
||||
ref="multipleTableRef"
|
||||
class="mt-16"
|
||||
:data="props.data"
|
||||
:pagination-config="paginationConfig"
|
||||
@sizeChange="handleSizeChange"
|
||||
@changePage="props.getData"
|
||||
@selection-change="handleSelectionChange"
|
||||
:maxTableHeight="320"
|
||||
:row-key="(row: any) => row.id"
|
||||
>
|
||||
<el-table-column type="selection" width="55" :reserve-selection="true" />
|
||||
<el-table-column prop="name" :label="$t('common.name')">
|
||||
<template #default="{ row }">
|
||||
<el-space :size="8">
|
||||
<!-- 知识库 icon -->
|
||||
<KnowledgeIcon :size="20" v-if="isKnowledge" :type="row.icon" />
|
||||
<!-- 应用/工具 自定义 icon -->
|
||||
<el-avatar
|
||||
v-else-if="isAppIcon(row?.icon) && !isModel"
|
||||
style="background: none"
|
||||
shape="square"
|
||||
:size="20"
|
||||
>
|
||||
<img :src="resetUrl(row?.icon)" alt="" />
|
||||
</el-avatar>
|
||||
<!-- 应用 icon -->
|
||||
<LogoIcon v-else-if="isApplication" height="20px" />
|
||||
<!-- 工具 icon -->
|
||||
<el-avatar v-else-if="isTool" class="avatar-green" shape="square" :size="20">
|
||||
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
|
||||
</el-avatar>
|
||||
<!-- 模型 icon -->
|
||||
<span
|
||||
v-else-if="isModel"
|
||||
style="width: 20px; height: 20px; display: inline-block"
|
||||
:innerHTML="getProviderIcon(row)"
|
||||
></span>
|
||||
<span :title="row?.name" class="ellipsis-1">
|
||||
{{ row?.name }}
|
||||
</span>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('common.operation')" align="left">
|
||||
<template #default="{ row }">
|
||||
<el-radio-group
|
||||
v-model="row.permission"
|
||||
@change="(val: any) => submitPermissions(val, row)"
|
||||
>
|
||||
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||
<el-radio :value="item.value" class="mr-16">{{ item.label }}</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</app-table>
|
||||
</div>
|
||||
|
||||
<!-- 批量配置 弹出层 -->
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="$t('views.system.resourceAuthorization.setting.configure')"
|
||||
destroy-on-close
|
||||
@close="closeDialog"
|
||||
>
|
||||
<el-radio-group v-model="radioPermission" class="radio-block">
|
||||
<template v-for="(item, index) in permissionOptions" :key="index">
|
||||
<el-radio :value="item.value" class="mr-16">
|
||||
<p class="color-text-primary lighter">{{ item.label }}</p>
|
||||
<el-text class="color-secondary lighter">{{ item.desc }}</el-text>
|
||||
</el-radio>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
<template #footer>
|
||||
<div class="dialog-footer mt-24">
|
||||
<el-button @click="closeDialog"> {{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submitDialog"> {{ $t('common.confirm') }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, computed, reactive } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { Provider } from '@/api/type/model'
|
||||
import { AuthorizationEnum } from '@/enums/system'
|
||||
import { isAppIcon, resetUrl } from '@/utils/common'
|
||||
import { RoleConst, PermissionConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
import { permissionOptions } from '@/views/system/resource-authorization/constant'
|
||||
import useStore from '@/stores'
|
||||
const { model, user } = useStore()
|
||||
const route = useRoute()
|
||||
const props = defineProps<{
|
||||
data: any[]
|
||||
type: string
|
||||
getData?: () => void
|
||||
}>()
|
||||
const emit = defineEmits(['submitPermissions'])
|
||||
const permissionObj = ref<any>({
|
||||
APPLICATION: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
KNOWLEDGE: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
TOOL: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
MODEL: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
})
|
||||
const isKnowledge = computed(() => props.type === AuthorizationEnum.KNOWLEDGE)
|
||||
const isApplication = computed(() => props.type === AuthorizationEnum.APPLICATION)
|
||||
const isTool = computed(() => props.type === AuthorizationEnum.TOOL)
|
||||
const isModel = computed(() => props.type === AuthorizationEnum.MODEL)
|
||||
|
||||
const multipleTableRef = ref()
|
||||
const searchType = ref('name')
|
||||
const searchForm = ref<any>({
|
||||
name: '',
|
||||
publish_status: undefined,
|
||||
})
|
||||
|
||||
const search_type_change = () => {
|
||||
searchForm.value = { name: '', create_user: '' }
|
||||
}
|
||||
|
||||
const paginationConfig = reactive({
|
||||
current_page: 1,
|
||||
page_size: 20,
|
||||
total: 0,
|
||||
})
|
||||
|
||||
function handleSizeChange() {
|
||||
paginationConfig.current_page = 1
|
||||
if (props.getData) {
|
||||
props.getData()
|
||||
}
|
||||
}
|
||||
function searchHandle() {
|
||||
paginationConfig.current_page = 1
|
||||
if (props.getData) {
|
||||
props.getData()
|
||||
}
|
||||
}
|
||||
|
||||
const multipleSelection = ref<any[]>([])
|
||||
|
||||
const handleSelectionChange = (val: any[]) => {
|
||||
multipleSelection.value = val
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const radioPermission = ref('')
|
||||
function openMulConfigureDialog() {
|
||||
if (multipleSelection.value.length === 0) {
|
||||
return
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
function submitDialog() {
|
||||
if (multipleSelection.value.length === 0 || !radioPermission.value) {
|
||||
return
|
||||
}
|
||||
const obj = multipleSelection.value.map((item) => ({
|
||||
target_id: item.id,
|
||||
permission: radioPermission.value,
|
||||
}))
|
||||
emit('submitPermissions', obj)
|
||||
closeDialog()
|
||||
}
|
||||
function closeDialog() {
|
||||
dialogVisible.value = false
|
||||
radioPermission.value = ''
|
||||
multipleSelection.value = []
|
||||
multipleTableRef.value?.clearSelection()
|
||||
}
|
||||
|
||||
function submitPermissions(value: string, row: any) {
|
||||
const obj = [
|
||||
{
|
||||
target_id: row.id,
|
||||
permission: value,
|
||||
},
|
||||
]
|
||||
emit('submitPermissions', obj)
|
||||
}
|
||||
const provider_list = ref<Array<Provider>>([])
|
||||
|
||||
function getProvider() {
|
||||
model.asyncGetProvider().then((res: any) => {
|
||||
provider_list.value = res?.data
|
||||
})
|
||||
}
|
||||
|
||||
const getProviderIcon = computed(() => {
|
||||
return (row: any) => {
|
||||
return provider_list.value.find((p) => p.provider === row.icon)?.icon
|
||||
}
|
||||
})
|
||||
onMounted(() => {
|
||||
if (isModel.value) {
|
||||
getProvider()
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
paginationConfig,
|
||||
searchForm,
|
||||
searchType,
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.permission-setting {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { AuthorizationEnum } from '@/enums/system'
|
||||
import { t } from '@/locales'
|
||||
|
||||
export const permissionOptions = [
|
||||
{
|
||||
label: t('views.system.resourceAuthorization.setting.notAuthorized'),
|
||||
value: AuthorizationEnum.NOT_AUTH,
|
||||
desc: '',
|
||||
},
|
||||
{
|
||||
label: t('views.system.resourceAuthorization.setting.check'),
|
||||
value: AuthorizationEnum.VIEW,
|
||||
desc: t('views.system.resourceAuthorization.setting.checkDesc'),
|
||||
},
|
||||
{
|
||||
label: t('views.system.resourceAuthorization.setting.management'),
|
||||
value: AuthorizationEnum.MANAGE,
|
||||
desc: t('views.system.resourceAuthorization.setting.managementDesc'),
|
||||
},
|
||||
{
|
||||
label: t('views.system.resourceAuthorization.setting.role'),
|
||||
value: AuthorizationEnum.ROLE,
|
||||
desc: t('views.system.resourceAuthorization.setting.roleDesc'),
|
||||
},
|
||||
]
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
/>
|
||||
</div>
|
||||
|
||||
<el-card style="--el-card-padding: 0">
|
||||
<div class="flex main-calc-height">
|
||||
<el-card style="--el-card-padding: 0; height: calc(100vh - 140px)">
|
||||
<div class="flex">
|
||||
<div class="resource-authorization__left border-r">
|
||||
<div class="p-24 pb-0">
|
||||
<h4 class="mb-12">{{ $t('views.system.resourceAuthorization.member') }}</h4>
|
||||
|
|
@ -45,11 +45,15 @@
|
|||
<template #default="{ row }">
|
||||
<div class="flex-between">
|
||||
<div class="flex">
|
||||
<span class="mr-8">{{ row.nick_name }}</span>
|
||||
<TagGroup
|
||||
:tags="row.roles"
|
||||
<span class="mr-8 ellipsis-1" :title="row.nick_name">{{
|
||||
row.nick_name
|
||||
}}</span>
|
||||
<el-text
|
||||
class="color-input-placeholder ellipsis-1"
|
||||
:title="row.roles.join(',')"
|
||||
v-if="hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')"
|
||||
/>
|
||||
>({{ row.roles?.join(',') }})</el-text
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -58,46 +62,13 @@
|
|||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="permission-setting p-24 flex" v-loading="rLoading">
|
||||
<div class="resource-authorization__table">
|
||||
<h4 class="mb-16">{{ $t('views.system.resourceAuthorization.permissionSetting') }}</h4>
|
||||
<!-- <el-tabs
|
||||
v-model="activeName"
|
||||
@tab-change="handleTabChange"
|
||||
class="resource-authorization__tabs"
|
||||
>
|
||||
<el-tab-pane
|
||||
v-for="(item, index) in settingTags"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:name="item.value"
|
||||
> -->
|
||||
<PermissionSetting
|
||||
:data="activeData.data"
|
||||
:type="activeData.type"
|
||||
:tableHeight="tableHeight"
|
||||
:manage="isManage(currentType)"
|
||||
@refreshData="refreshData"
|
||||
v-model:isRole="activeData.isRole"
|
||||
></PermissionSetting>
|
||||
<!-- </el-tab-pane> -->
|
||||
<!-- </el-tabs> -->
|
||||
</div>
|
||||
|
||||
<div class="submit-button">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitPermissions"
|
||||
v-if="
|
||||
hasPermission(
|
||||
permissionObj[(route.meta?.resource as string) || 'APPLICATION'],
|
||||
'OR',
|
||||
)
|
||||
"
|
||||
>{{ $t('common.save') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<PermissionTable
|
||||
:data="permissionData"
|
||||
:type="activeData.type"
|
||||
ref="PermissionTableRef"
|
||||
:getData="getPermissionList"
|
||||
@submitPermissions="submitPermissions"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
|
@ -107,18 +78,17 @@
|
|||
import { onMounted, ref, reactive, watch, computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import AuthorizationApi from '@/api/system/resource-authorization'
|
||||
import PermissionSetting from './component/PermissionSetting.vue'
|
||||
import PermissionTable from '@/views/system/resource-authorization/component/PermissionTable.vue'
|
||||
import { MsgSuccess, MsgConfirm } from '@/utils/message'
|
||||
import { AuthorizationEnum } from '@/enums/system'
|
||||
import { t } from '@/locales'
|
||||
import useStore from '@/stores'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { EditionConst, RoleConst, PermissionConst } from '@/utils/permission/data'
|
||||
import { EditionConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
import type { WorkspaceItem } from '@/api/type/workspace'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
|
||||
|
||||
import useStore from '@/stores'
|
||||
|
||||
const route = useRoute()
|
||||
const { user } = useStore()
|
||||
const loading = ref(false)
|
||||
|
|
@ -128,79 +98,27 @@ const filterMember = ref<any[]>([]) // 搜索过滤后列表
|
|||
const currentUser = ref<string>('')
|
||||
const currentType = ref<string>('')
|
||||
const filterText = ref('')
|
||||
const tableHeight = ref(0)
|
||||
const permissionData = ref<any[]>([])
|
||||
|
||||
const permissionObj = ref<any>({
|
||||
APPLICATION: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.APPLICATION_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
KNOWLEDGE: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.KNOWLEDGE_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
TOOL: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.TOOL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
MODEL: new ComplexPermission(
|
||||
[RoleConst.ADMIN, RoleConst.WORKSPACE_MANAGE],
|
||||
[
|
||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT,
|
||||
PermissionConst.MODEL_WORKSPACE_USER_RESOURCE_PERMISSION_EDIT
|
||||
.getWorkspacePermissionWorkspaceManageRole,
|
||||
],
|
||||
[],
|
||||
'OR',
|
||||
),
|
||||
})
|
||||
const settingTags = reactive([
|
||||
{
|
||||
label: t('views.knowledge.title'),
|
||||
type: AuthorizationEnum.KNOWLEDGE,
|
||||
data: [] as any,
|
||||
isRole: false,
|
||||
},
|
||||
{
|
||||
label: t('views.application.title'),
|
||||
type: AuthorizationEnum.APPLICATION,
|
||||
data: [] as any,
|
||||
isRole: false,
|
||||
},
|
||||
{
|
||||
label: t('views.tool.title'),
|
||||
type: AuthorizationEnum.TOOL,
|
||||
data: [] as any,
|
||||
isRole: false,
|
||||
},
|
||||
{
|
||||
label: t('views.model.title'),
|
||||
type: AuthorizationEnum.MODEL,
|
||||
data: [] as any,
|
||||
isRole: false,
|
||||
},
|
||||
])
|
||||
|
||||
// 当前激活的数据类型(应用/知识库/模型/工具)
|
||||
|
||||
const activeData = computed(() => {
|
||||
const lastIndex = route.path.lastIndexOf('/')
|
||||
const currentPathType = route.path.substring(lastIndex + 1).toUpperCase()
|
||||
|
|
@ -219,51 +137,46 @@ watch(filterText, (val: any) => {
|
|||
}
|
||||
})
|
||||
|
||||
function isManage(type: string) {
|
||||
return type === 'manage'
|
||||
}
|
||||
|
||||
const flotTree = (tree: Array<any>, result: Array<any>) => {
|
||||
tree.forEach((tItem) => {
|
||||
result.push(tItem)
|
||||
if (tItem.children) {
|
||||
flotTree(tItem.children, result)
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
function submitPermissions() {
|
||||
const user_resource_permission_list = settingTags
|
||||
.map((item: any, index: number) => {
|
||||
return flotTree(item.data, [])
|
||||
.filter((v: any) => !v.isFolder)
|
||||
.map((v: any) => {
|
||||
return {
|
||||
target_id: v.id,
|
||||
auth_target_type: item.value,
|
||||
permission: v.permission,
|
||||
auth_type: item.isRole ? 'ROLE' : 'RESOURCE_PERMISSION_GROUP',
|
||||
}
|
||||
})
|
||||
})
|
||||
.reduce((pre: any, next: any) => [...pre, ...next], [])
|
||||
function submitPermissions(obj: any) {
|
||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||
AuthorizationApi.putResourceAuthorization(
|
||||
workspaceId,
|
||||
currentUser.value,
|
||||
(route.meta?.resource as string) || 'APPLICATION',
|
||||
{ user_resource_permission_list: user_resource_permission_list },
|
||||
obj,
|
||||
rLoading,
|
||||
).then(() => {
|
||||
MsgSuccess(t('common.submitSuccess'))
|
||||
getWholeTree(currentUser.value)
|
||||
getPermissionList()
|
||||
})
|
||||
}
|
||||
|
||||
const PermissionTableRef = ref()
|
||||
|
||||
const getPermissionList = () => {
|
||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||
const params: any = {}
|
||||
if (PermissionTableRef.value.searchForm[PermissionTableRef.value.searchType]) {
|
||||
params[PermissionTableRef.value.searchType] =
|
||||
PermissionTableRef.value.searchForm[PermissionTableRef.value.searchType]
|
||||
}
|
||||
AuthorizationApi.getResourceAuthorization(
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
function clickMemberHandle(item: any) {
|
||||
currentUser.value = item.id
|
||||
currentType.value = item.type
|
||||
getWholeTree(item.id)
|
||||
getPermissionList()
|
||||
}
|
||||
|
||||
function getMember(id?: string) {
|
||||
|
|
@ -275,175 +188,13 @@ function getMember(id?: string) {
|
|||
const member = (id && memberList.value.find((p: any) => p.user_id === id)) || null
|
||||
currentUser.value = member ? member.id : memberList.value?.[0]?.id
|
||||
currentType.value = member ? member.type : memberList.value?.[0]?.type
|
||||
getWholeTree(currentUser.value)
|
||||
getPermissionList()
|
||||
} else {
|
||||
activeData.value.data = []
|
||||
permissionData.value = []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const dfsPermissionIndeterminateTrue = (arr: any = [], type: string) => {
|
||||
return arr.every((item: any) => {
|
||||
if (item.children?.length) {
|
||||
item.permission[type] = dfsPermissionIndeterminateTrue(item.children, type)
|
||||
}
|
||||
return item.permission[type]
|
||||
})
|
||||
}
|
||||
|
||||
const dfsPermissionIndeterminate = (
|
||||
arr: any = [],
|
||||
type: string,
|
||||
permissionHalf: any,
|
||||
permissionHalfMap: any,
|
||||
id: string,
|
||||
) => {
|
||||
arr.forEach((item: any) => {
|
||||
if (item.isFolder) {
|
||||
if (!permissionHalfMap[item.id]) {
|
||||
permissionHalfMap[item.id] = cloneDeep(permissionHalf)
|
||||
}
|
||||
}
|
||||
|
||||
if (item.children?.length) {
|
||||
dfsPermissionIndeterminate(item.children, type, permissionHalf, permissionHalfMap, item.id)
|
||||
}
|
||||
|
||||
if (!item.isFolder) {
|
||||
permissionHalfMap[id][type] = [...permissionHalfMap[id][type], item.permission[type]]
|
||||
}
|
||||
|
||||
if (item.isFolder) {
|
||||
// 判断是否存在子项且全部选中或全部未选中
|
||||
const hasPermissions = permissionHalfMap[item.id][type]
|
||||
const allTrue = hasPermissions.length && hasPermissions.every((p: boolean) => p)
|
||||
const allFalse = hasPermissions.length && hasPermissions.every((p: boolean) => !p)
|
||||
|
||||
// 只有在既有选中又有未选中的情况下才设置为半选状态
|
||||
item.permissionHalf[type] = hasPermissions.length && !allTrue && !allFalse
|
||||
|
||||
// 检查子文件夹是否有半选状态
|
||||
if (item.children.some((ele: any) => ele.isFolder && ele.permissionHalf[type])) {
|
||||
item.permissionHalf[type] = true
|
||||
}
|
||||
|
||||
// 如果所有子项都已选中,确保当前项也被选中而不是半选
|
||||
if (allTrue) {
|
||||
item.permission[type] = true
|
||||
item.permissionHalf[type] = false
|
||||
}
|
||||
|
||||
// 如果子项中有选中的也有未选中的,则设置为半选状态
|
||||
if (
|
||||
item.children.some((ele: any) => ele.permission[type]) &&
|
||||
item.children.some((ele: any) => !ele.permission[type])
|
||||
) {
|
||||
item.permissionHalf[type] = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const dfsFolder = (arr: any[] = [], folderIdMap: any) => {
|
||||
arr.forEach((ele) => {
|
||||
if (ele.permission) return
|
||||
if (ele.children?.length) {
|
||||
if (folderIdMap[ele.id]) {
|
||||
ele.children = [...ele.children, ...folderIdMap[ele.id]]
|
||||
}
|
||||
dfsFolder(ele.children, folderIdMap)
|
||||
} else {
|
||||
ele.children = folderIdMap[ele.id] || []
|
||||
}
|
||||
ele.isFolder = true
|
||||
ele.permission = {
|
||||
VIEW: false,
|
||||
MANAGE: false,
|
||||
ROLE: false,
|
||||
}
|
||||
|
||||
ele.permissionHalf = {
|
||||
VIEW: false,
|
||||
MANAGE: false,
|
||||
ROLE: false,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getFolder() {
|
||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||
return AuthorizationApi.getSystemFolder(workspaceId, activeData.value.type, {}, loading)
|
||||
}
|
||||
function getResourcePermissions(user_id: string) {
|
||||
const workspaceId = currentWorkspaceId.value || user.getWorkspaceId() || 'default'
|
||||
return AuthorizationApi.getResourceAuthorization(
|
||||
workspaceId,
|
||||
user_id,
|
||||
(route.meta?.resource as string) || 'APPLICATION',
|
||||
rLoading,
|
||||
)
|
||||
}
|
||||
const getWholeTree = async (user_id: string) => {
|
||||
const [parentRes, childrenRes] = await Promise.all([getFolder(), getResourcePermissions(user_id)])
|
||||
// if (!childrenRes.data || Object.keys(childrenRes.data).length > 0) {
|
||||
// settingTags.map((item: any) => {
|
||||
let folderIdMap = []
|
||||
const folderTree = cloneDeep((parentRes as unknown as any).data)
|
||||
if (Object.keys(childrenRes.data).indexOf(activeData.value.type) !== -1) {
|
||||
activeData.value.isRole =
|
||||
childrenRes.data[activeData.value.type].length > 0 &&
|
||||
hasPermission([EditionConst.IS_EE, EditionConst.IS_PE], 'OR')
|
||||
? childrenRes.data[activeData.value.type][0].auth_type == 'ROLE'
|
||||
: false
|
||||
folderIdMap = getFolderIdMap(childrenRes.data[activeData.value.type])
|
||||
dfsFolder(folderTree, folderIdMap)
|
||||
const permissionHalf = {
|
||||
VIEW: [],
|
||||
MANAGE: [],
|
||||
ROLE: [],
|
||||
}
|
||||
Object.keys(permissionHalf).forEach((ele) => {
|
||||
dfsPermissionIndeterminateTrue(folderTree, ele)
|
||||
dfsPermissionIndeterminate(folderTree, ele, cloneDeep(permissionHalf), {}, 'default')
|
||||
})
|
||||
if (activeData.value.type === AuthorizationEnum.MODEL) {
|
||||
activeData.value.data = folderTree[0].children
|
||||
} else {
|
||||
activeData.value.data = folderTree
|
||||
}
|
||||
} else {
|
||||
activeData.value.data = []
|
||||
}
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
const refreshData = () => {
|
||||
settingTags.map((item: any) => {
|
||||
if (activeData.value.type === item.type) {
|
||||
const permissionHalf = {
|
||||
VIEW: [],
|
||||
MANAGE: [],
|
||||
ROLE: [],
|
||||
}
|
||||
Object.keys(permissionHalf).forEach((ele) => {
|
||||
dfsPermissionIndeterminateTrue(item.data, ele)
|
||||
dfsPermissionIndeterminate(item.data, ele, cloneDeep(permissionHalf), {}, 'default')
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
const getFolderIdMap = (arr: any = []) => {
|
||||
return arr.reduce((pre: any, next: any) => {
|
||||
if (pre[next.folder_id]) {
|
||||
pre[next.folder_id].push(next)
|
||||
} else {
|
||||
pre[next.folder_id] = [next]
|
||||
}
|
||||
return pre
|
||||
}, {})
|
||||
}
|
||||
|
||||
const workspaceList = ref<WorkspaceItem[]>([])
|
||||
const currentWorkspaceId = ref<string | undefined>('')
|
||||
const currentWorkspace = computed(() => {
|
||||
|
|
@ -461,12 +212,6 @@ function changeWorkspace(item: WorkspaceItem) {
|
|||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableHeight.value = window.innerHeight - 300
|
||||
window.onresize = () => {
|
||||
return (() => {
|
||||
tableHeight.value = window.innerHeight - 300
|
||||
})()
|
||||
}
|
||||
if (user.isEE()) {
|
||||
getWorkspaceList()
|
||||
}
|
||||
|
|
@ -481,20 +226,6 @@ onMounted(() => {
|
|||
width: var(--setting-left-width);
|
||||
min-width: var(--setting-left-width);
|
||||
}
|
||||
|
||||
.permission-setting {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
.submit-button {
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
right: 24px;
|
||||
}
|
||||
}
|
||||
.list-height-left {
|
||||
height: calc(100vh - 240px);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue