feat: Resource management authorization

v3.2
wangdan-fit2cloud 2025-08-27 15:10:31 +08:00
parent 2434acf685
commit 7756d02b6a
18 changed files with 350 additions and 188 deletions

View File

@ -0,0 +1,55 @@
import { Result } from '@/request/Result'
import { get, put, post, del } from '@/request/index'
import type { Ref } from 'vue'
import type { pageRequest } from '@/api/type/common'
const prefix = 'system/workspace'
/**
*
* @query
*/
const getResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
page: pageRequest,
params?: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, page, params, loading) => {
return get(
`${prefix}/${workspace_id}/resource_management/resource/${target}/resource/${resource}/${page.current_page}/${page.page_size}`,
params,
loading,
)
}
/**
*
* @param member_id
* @param {
[
{
"target_id": "string",
"permission": "NOT_AUTH"
}
]
}
*/
const putResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
body: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, body, loading) => {
return put(
`${prefix}/${workspace_id}/resource_management/resource/${target}/resource/${resource}`,
body,
{},
loading,
)
}
export default {
getResourceAuthorization,
putResourceAuthorization,
}

View File

@ -4,52 +4,6 @@ import type { Ref } from 'vue'
import type { pageRequest } from '@/api/type/common' import type { pageRequest } from '@/api/type/common'
const prefix = '/workspace' const prefix = '/workspace'
/**
*
* @query
*/
const getWorkspaceResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
page: pageRequest,
params?: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, page, params, loading) => {
return get(
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}/${page.current_page}/${page.page_size}`,
params,
loading,
)
}
/**
*
* @param member_id
* @param {
[
{
"user_id": "string",
"permission": "NOT_AUTH"
}
]
}
*/
const putWorkspaceResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
body: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, body, loading) => {
return put(
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}`,
body,
{},
loading,
)
}
/** /**
* *
* @query * @query
@ -148,6 +102,5 @@ export default {
getUserList, getUserList,
getUserMember, getUserMember,
getSystemFolder, getSystemFolder,
getWorkspaceResourceAuthorization,
putWorkspaceResourceAuthorization
} }

View File

@ -0,0 +1,57 @@
import { Result } from '@/request/Result'
import { get, put, post, del } from '@/request/index'
import type { Ref } from 'vue'
import type { pageRequest } from '@/api/type/common'
const prefix = '/workspace'
/**
*
* @query
*/
const getResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
page: pageRequest,
params?: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, page, params, loading) => {
return get(
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}/${page.current_page}/${page.page_size}`,
params,
loading,
)
}
/**
*
* @param member_id
* @param {
[
{
"user_id": "string",
"permission": "NOT_AUTH"
}
]
}
*/
const putResourceAuthorization: (
workspace_id: string,
target: string,
resource: string,
body: any,
loading?: Ref<boolean>,
) => Promise<Result<any>> = (workspace_id, target, resource, body, loading) => {
return put(
`${prefix}/${workspace_id}/resource_user_permission/resource/${target}/resource/${resource}`,
body,
{},
loading,
)
}
export default {
getResourceAuthorization,
putResourceAuthorization
}

View File

@ -427,11 +427,10 @@ const uploadFile = async (file: any, fileList: any) => {
fileList.splice(0, fileList.length, ...fileList.slice(0, maxFiles)) fileList.splice(0, fileList.length, ...fileList.slice(0, maxFiles))
return return
} }
console.log(fileList)
if (fileList.filter((f: any) => f.size == 0).length > 0) { if (fileList.filter((f: any) => f.size == 0).length > 0) {
// MB // MB
MsgWarning(t('chat.uploadFile.sizeLimit2') + fileLimit + 'MB') MsgWarning(t('chat.uploadFile.sizeLimit2'))
// //
fileList.splice(0, fileList.length, ...fileList.filter((f: any) => f.size > 0)) fileList.splice(0, fileList.length, ...fileList.filter((f: any) => f.size > 0))
return return
} }

View File

@ -77,7 +77,6 @@ import { groupBy } from 'lodash'
import { MsgSuccess } from '@/utils/message' import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales' import { t } from '@/locales'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import modelResourceApi from '@/api/system-resource-management/model'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api' import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
const props = defineProps<{ const props = defineProps<{

View File

@ -22,10 +22,7 @@
> >
<el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" /> <el-option :label="$t('views.userManage.userForm.nick_name.label')" value="nick_name" />
<el-option :label="$t('views.login.loginForm.username.label')" value="username" /> <el-option :label="$t('views.login.loginForm.username.label')" value="username" />
<el-option <el-option :label="$t('views.model.modelForm.permissionType.label')" value="permission" />
:label="$t('views.model.modelForm.permissionType.label')"
value="permission"
/>
</el-select> </el-select>
<el-input <el-input
v-if="searchType === 'nick_name'" v-if="searchType === 'nick_name'"
@ -149,15 +146,26 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch, computed, reactive } from 'vue' import { ref, onMounted, watch, computed, reactive } from 'vue'
import { useRoute } from 'vue-router'
import { getPermissionOptions } from '@/views/system/resource-authorization/constant' import { getPermissionOptions } from '@/views/system/resource-authorization/constant'
import AuthorizationApi from '@/api/system/resource-authorization' import AuthorizationApi from '@/api/system/resource-authorization'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { t } from '@/locales' import { t } from '@/locales'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
const route = useRoute()
import useStore from '@/stores' import useStore from '@/stores'
const { user } = useStore() const { user } = useStore()
const props = defineProps<{ const props = defineProps<{
type: string type: string
}>() }>()
const apiType = computed(() => {
if (route.path.includes('resource-management')) {
return 'systemManage'
} else {
return 'workspace'
}
})
const permissionOptions = computed(() => { const permissionOptions = computed(() => {
return getPermissionOptions() return getPermissionOptions()
}) })
@ -250,16 +258,12 @@ function permissionsHandle(val: any, row: any) {
function submitPermissions(obj: any) { function submitPermissions(obj: any) {
const workspaceId = user.getWorkspaceId() || 'default' const workspaceId = user.getWorkspaceId() || 'default'
AuthorizationApi.putWorkspaceResourceAuthorization( loadSharedApi({ type: 'resourceAuthorization', systemType: apiType.value })
workspaceId, .putResourceAuthorization(workspaceId, targetId.value, props.type, obj, loading)
targetId.value, .then(() => {
props.type, MsgSuccess(t('common.submitSuccess'))
obj, getPermissionList()
loading, })
).then(() => {
MsgSuccess(t('common.submitSuccess'))
getPermissionList()
})
} }
const getPermissionList = () => { const getPermissionList = () => {
const workspaceId = user.getWorkspaceId() || 'default' const workspaceId = user.getWorkspaceId() || 'default'
@ -267,17 +271,19 @@ const getPermissionList = () => {
if (searchForm.value[searchType.value]) { if (searchForm.value[searchType.value]) {
params[searchType.value] = searchForm.value[searchType.value] params[searchType.value] = searchForm.value[searchType.value]
} }
AuthorizationApi.getWorkspaceResourceAuthorization( loadSharedApi({ type: 'resourceAuthorization', systemType: apiType.value })
workspaceId, .getResourceAuthorization(
targetId.value, workspaceId,
props.type, targetId.value,
paginationConfig, props.type,
params, paginationConfig,
loading, params,
).then((res) => { loading,
permissionData.value = res.data.records || [] )
paginationConfig.total = res.data.total || 0 .then((res: any) => {
}) permissionData.value = res.data.records || []
paginationConfig.total = res.data.total || 0
})
} }
const open = (id: string) => { const open = (id: string) => {

View File

@ -9,6 +9,7 @@ import applicationWorkspaceApi from '@/api/application/application'
import applicationKeyWorkspaceApi from '@/api/application/application-key' import applicationKeyWorkspaceApi from '@/api/application/application-key'
import workflowVersionWorkspaceApi from '@/api/application/workflow-version' import workflowVersionWorkspaceApi from '@/api/application/workflow-version'
import chatLogWorkspaceApi from '@/api/application/chat-log' import chatLogWorkspaceApi from '@/api/application/chat-log'
import resourceAuthorizationWorkspaceApi from '@/api/workspace/resource-authorization'
import sharedWorkspaceApi from '@/api/shared-workspace' import sharedWorkspaceApi from '@/api/shared-workspace'
import toolSystemShareApi from '@/api/system-shared/tool' import toolSystemShareApi from '@/api/system-shared/tool'
import modelSystemShareApi from '@/api/system-shared/model' import modelSystemShareApi from '@/api/system-shared/model'
@ -29,7 +30,8 @@ import chatUserResourceApi from '@/api/system-resource-management/chat-user'
import applicationResourceApi from '@/api/system-resource-management/application' import applicationResourceApi from '@/api/system-resource-management/application'
import applicationKeyResourceApi from '@/api/system-resource-management/application-key' import applicationKeyResourceApi from '@/api/system-resource-management/application-key'
import workflowVersionResourceApi from '@/api/system-resource-management/workflow-version' import workflowVersionResourceApi from '@/api/system-resource-management/workflow-version'
import chatLogWResourceApi from '@/api/system-resource-management/chat-log' import chatLogResourceApi from '@/api/system-resource-management/chat-log'
import resourceAuthorizationResourceApi from '@/api/system-resource-management/resource-authorization'
// 普通 API // 普通 API
const workspaceApiMap = { const workspaceApiMap = {
@ -45,6 +47,7 @@ const workspaceApiMap = {
applicationKey: applicationKeyWorkspaceApi, applicationKey: applicationKeyWorkspaceApi,
workflowVersion: workflowVersionWorkspaceApi, workflowVersion: workflowVersionWorkspaceApi,
chatLog: chatLogWorkspaceApi, chatLog: chatLogWorkspaceApi,
resourceAuthorization: resourceAuthorizationWorkspaceApi,
} as any } as any
// 系统分享 API // 系统分享 API
@ -71,7 +74,8 @@ const systemManageApiMap = {
application: applicationResourceApi, application: applicationResourceApi,
applicationKey: applicationKeyResourceApi, applicationKey: applicationKeyResourceApi,
workflowVersion: workflowVersionResourceApi, workflowVersion: workflowVersionResourceApi,
chatLog: chatLogWResourceApi, chatLog: chatLogResourceApi,
resourceAuthorization: resourceAuthorizationResourceApi,
} as any } as any
const data = { const data = {

View File

@ -544,7 +544,7 @@ const xpackForm = ref<any>({
language: '', language: '',
icon: '', icon: '',
icon_url: '', icon_url: '',
show_history: false, show_history: true,
draggable: false, draggable: false,
show_guide: false, show_guide: false,
chat_background: '', chat_background: '',

View File

@ -3,49 +3,52 @@
<h2 class="mb-16">{{ $t('views.chatLog.title') }}</h2> <h2 class="mb-16">{{ $t('views.chatLog.title') }}</h2>
<el-card style="--el-card-padding: 24px"> <el-card style="--el-card-padding: 24px">
<div class="mb-16"> <div class="mb-16 flex-between">
<el-select <div class="flex align-center">
v-model="query_option" <div class="flex-between complex-search">
class="mr-12" <el-select
@change="search_type_change" v-model="search_type"
style="width: 75px" class="complex-search__left"
> @change="search_type_change"
<el-option :label="$t('views.chatLog.table.abstract')" value="abstract" /> style="width: 75px"
<el-option :label="$t('views.chatLog.table.username')" value="username" /> >
</el-select> <el-option :label="$t('views.chatLog.table.abstract')" value="abstract" />
<el-input <el-option :label="$t('views.chatLog.table.username')" value="username" />
v-model="search" </el-select>
@change="getList" <el-input
:placeholder="$t('common.search')" v-model="search_form[search_type]"
prefix-icon="Search" @change="getList"
class="w-240 mr-12" :placeholder="$t('common.search')"
clearable class="w-240"
/> clearable
<el-select />
v-model="history_day" </div>
class="mr-12" <el-select
@change="changeDayHandle" v-model="history_day"
style="width: 180px" class="ml-12"
> @change="changeDayHandle"
<el-option style="width: 180px"
v-for="item in dayOptions" >
:key="item.value" <el-option
:label="item.label" v-for="item in dayOptions"
:value="item.value" :key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-date-picker
v-if="history_day === 'other'"
v-model="daterangeValue"
type="daterange"
:start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="changeDayRangeHandle"
style="width: 240px"
class="mr-12"
/> />
</el-select> </div>
<el-date-picker
v-if="history_day === 'other'"
v-model="daterangeValue"
type="daterange"
:start-placeholder="$t('views.applicationOverview.monitor.startDatePlaceholder')"
:end-placeholder="$t('views.applicationOverview.monitor.endDatePlaceholder')"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="changeDayRangeHandle"
style="width: 240px"
class="mr-12"
/>
<div style="display: flex; align-items: center" class="float-right"> <div style="display: flex; align-items: center" class="float-right">
<el-button @click="dialogVisible = true" v-if="permissionPrecise.chat_log_clear(id)"> <el-button @click="dialogVisible = true" v-if="permissionPrecise.chat_log_clear(id)">
{{ $t('views.chatLog.buttons.clearStrategy') }} {{ $t('views.chatLog.buttons.clearStrategy') }}
@ -218,7 +221,11 @@
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
> >
<SelectKnowledgeDocument ref="SelectKnowledgeDocumentRef" :apiType="apiType" :workspace-id="detail.workspace_id"/> <SelectKnowledgeDocument
ref="SelectKnowledgeDocumentRef"
:apiType="apiType"
:workspace-id="detail.workspace_id"
/>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click.prevent="documentDialogVisible = false"> <el-button @click.prevent="documentDialogVisible = false">
@ -263,15 +270,15 @@ const {
} = route as any } = route as any
const emit = defineEmits(['refresh']) const emit = defineEmits(['refresh'])
const formRef = ref()
const search_type = ref('abstract')
const search_form = ref<any>({ const search_form = ref<any>({
abstract: '', abstract: '',
username: '', username: '',
}) })
const search_type_change = () => { const search_type_change = () => {
search_form.value = {abstract: '', username: ''} search_form.value = { abstract: '', username: '' }
} }
const dayOptions = [ const dayOptions = [
@ -326,9 +333,7 @@ const tableIndexMap = computed<Dict<number>>(() => {
.reduce((pre, next) => ({ ...pre, ...next }), {}) .reduce((pre, next) => ({ ...pre, ...next }), {})
}) })
const history_day = ref<number | string>(7) const history_day = ref<number | string>(7)
const query_option = ref<string>('abstract')
const search = ref('')
const detail = ref<any>(null) const detail = ref<any>(null)
const currentChatId = ref<string>('') const currentChatId = ref<string>('')
@ -429,14 +434,13 @@ const handleSelectionChange = (val: any[]) => {
} }
function getList() { function getList() {
let obj: any = { const obj: any = {
start_time: daterange.value.start_time, start_time: daterange.value.start_time,
end_time: daterange.value.end_time, end_time: daterange.value.end_time,
...filter.value, ...filter.value,
} }
if (search.value) { if (search_form.value[search_type.value]) {
if (query_option.value === 'abstract'){obj = { ...obj, abstract: search.value }} obj[search_type.value] = search_form.value[search_type.value]
else if (query_option.value === 'username'){obj = { ...obj, username: search.value }}
} }
return loadSharedApi({ type: 'chatLog', systemType: apiType.value }) return loadSharedApi({ type: 'chatLog', systemType: apiType.value })
.getChatLog(id as string, paginationConfig, obj, loading) .getChatLog(id as string, paginationConfig, obj, loading)
@ -466,15 +470,14 @@ const exportLog = () => {
} }
}) })
if (detail.value) { if (detail.value) {
let obj: any = { const obj: any = {
start_time: daterange.value.start_time, start_time: daterange.value.start_time,
end_time: daterange.value.end_time, end_time: daterange.value.end_time,
...filter.value, ...filter.value,
} }
if (search.value) { if (search_form.value[search_type.value]) {
obj = { ...obj, abstract: search.value } obj[search_type.value] = search_form.value[search_type.value]
} }
loadSharedApi({ type: 'chatLog', systemType: apiType.value }).postExportChatLog( loadSharedApi({ type: 'chatLog', systemType: apiType.value }).postExportChatLog(
detail.value.id, detail.value.id,
detail.value.name, detail.value.name,

View File

@ -40,7 +40,7 @@
<div <div
v-show="!isPcCollapse" v-show="!isPcCollapse"
class="flex-between p-8 pb-0 color-secondary mt-8" class="flex-between p-8 pb-0 color-secondary mt-8"
v-if="applicationDetail.show_history || hasPermission(EditionConst.IS_CE, 'OR')" v-if="applicationDetail.show_history || user.isCE()"
> >
<span>{{ $t('chat.history') }}</span> <span>{{ $t('chat.history') }}</span>
<el-tooltip effect="dark" :content="$t('chat.clearChat')" placement="right"> <el-tooltip effect="dark" :content="$t('chat.clearChat')" placement="right">
@ -53,7 +53,7 @@
<div <div
v-show="!isPcCollapse" v-show="!isPcCollapse"
class="left-height" class="left-height"
v-if="applicationDetail.show_history || hasPermission(EditionConst.IS_CE, 'OR')" v-if="applicationDetail.show_history || user.isCE()"
> >
<el-scrollbar> <el-scrollbar>
<div class="p-16 pt-0"> <div class="p-16 pt-0">
@ -111,7 +111,7 @@
<template #title>{{ $t('chat.createChat') }}</template> <template #title>{{ $t('chat.createChat') }}</template>
</el-menu-item> </el-menu-item>
<el-sub-menu v-show="isPcCollapse" index="2" v-if="applicationDetail.show_history || hasPermission(EditionConst.IS_CE, 'OR')"> <el-sub-menu v-show="isPcCollapse" index="2" v-if="applicationDetail.show_history || user.isCE()">
<template #title> <template #title>
<AppIcon iconName="app-history-outlined" /> <AppIcon iconName="app-history-outlined" />
</template> </template>
@ -171,8 +171,9 @@
import { ref } from 'vue' import { ref } from 'vue'
import { isAppIcon } from '@/utils/common' import { isAppIcon } from '@/utils/common'
import EditTitleDialog from './EditTitleDialog.vue' import EditTitleDialog from './EditTitleDialog.vue'
import { EditionConst } from '@/utils/permission/data' import useStore from "@/stores";
import { hasPermission } from '@/utils/permission/index'
const {user} = useStore()
const props = defineProps<{ const props = defineProps<{
applicationDetail: any applicationDetail: any
chatLogData: any[] chatLogData: any[]

View File

@ -184,7 +184,6 @@ function back() {
if (documentsFiles.value?.length > 0) { if (documentsFiles.value?.length > 0) {
MsgConfirm(t('common.tip'), t('views.document.tip.saveMessage'), { MsgConfirm(t('common.tip'), t('views.document.tip.saveMessage'), {
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
type: 'warning',
}) })
.then(() => { .then(() => {
router.go(-1) router.go(-1)

View File

@ -260,6 +260,16 @@
</el-button> </el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item
@click.stop="openAuthorization(row)"
v-if="permissionPrecise.auth()"
>
<AppIcon
iconName="app-resource-authorization"
class="color-secondary"
></AppIcon>
{{ $t('views.system.resourceAuthorization.title') }}
</el-dropdown-item>
<el-dropdown-item <el-dropdown-item
@click.stop="exportApplication(row)" @click.stop="exportApplication(row)"
v-if="permissionPrecise.export()" v-if="permissionPrecise.export()"
@ -281,6 +291,10 @@
</el-table-column> </el-table-column>
</app-table> </app-table>
</el-card> </el-card>
<ResourceAuthorizationDrawer
:type="SourceTypeEnum.APPLICATION"
ref="ResourceAuthorizationDrawerRef"
/>
</div> </div>
</template> </template>
@ -288,6 +302,7 @@
import { onMounted, ref, reactive, computed, watch } from 'vue' import { onMounted, ref, reactive, computed, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import ApplicationResourceApi from '@/api/system-resource-management/application' import ApplicationResourceApi from '@/api/system-resource-management/application'
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
import { t } from '@/locales' import { t } from '@/locales'
import { isAppIcon, resetUrl } from '@/utils/common' import { isAppIcon, resetUrl } from '@/utils/common'
import useStore from '@/stores' import useStore from '@/stores'
@ -297,7 +312,7 @@ import { isWorkFlow } from '@/utils/application.ts'
import UserApi from '@/api/user/user.ts' import UserApi from '@/api/user/user.ts'
import permissionMap from '@/permission' import permissionMap from '@/permission'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message' import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import { SourceTypeEnum } from '@/enums/common'
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const { user, application } = useStore() const { user, application } = useStore()
@ -317,7 +332,16 @@ const managePermission = () => {
} }
const MoreFilledPermission = () => { const MoreFilledPermission = () => {
return permissionPrecise.value.export() || permissionPrecise.value.delete() return (
permissionPrecise.value.export() ||
permissionPrecise.value.delete() ||
permissionPrecise.value.auth()
)
}
const ResourceAuthorizationDrawerRef = ref()
function openAuthorization(item: any) {
ResourceAuthorizationDrawerRef.value.open(item.id)
} }
const apiInputParams = ref([]) const apiInputParams = ref([])

View File

@ -217,6 +217,16 @@
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon> <AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
{{ $t('common.setting') }} {{ $t('common.setting') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item
@click.stop="openAuthorization(row)"
v-if="permissionPrecise.auth()"
>
<AppIcon
iconName="app-resource-authorization"
class="color-secondary"
></AppIcon>
{{ $t('views.system.resourceAuthorization.title') }}
</el-dropdown-item>
<el-dropdown-item <el-dropdown-item
@click.stop="exportKnowledge(row)" @click.stop="exportKnowledge(row)"
v-if="permissionPrecise.export()" v-if="permissionPrecise.export()"
@ -248,6 +258,10 @@
</el-card> </el-card>
<SyncWebDialog ref="SyncWebDialogRef" /> <SyncWebDialog ref="SyncWebDialogRef" />
<GenerateRelatedDialog ref="GenerateRelatedDialogRef" apiType="systemManage" /> <GenerateRelatedDialog ref="GenerateRelatedDialogRef" apiType="systemManage" />
<ResourceAuthorizationDrawer
:type="SourceTypeEnum.KNOWLEDGE"
ref="ResourceAuthorizationDrawerRef"
/>
</div> </div>
</template> </template>
@ -258,10 +272,12 @@ import KnowledgeResourceApi from '@/api/system-resource-management/knowledge'
import UserApi from '@/api/user/user' import UserApi from '@/api/user/user'
import SyncWebDialog from '@/views/knowledge/component/SyncWebDialog.vue' import SyncWebDialog from '@/views/knowledge/component/SyncWebDialog.vue'
import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vue' import GenerateRelatedDialog from '@/components/generate-related-dialog/index.vue'
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
import { datetimeFormat } from '@/utils/time' import { datetimeFormat } from '@/utils/time'
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts' import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import permissionMap from '@/permission' import permissionMap from '@/permission'
import { MsgSuccess, MsgConfirm } from '@/utils/message' import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { SourceTypeEnum } from '@/enums/common'
import { t } from '@/locales' import { t } from '@/locales'
import useStore from '@/stores' import useStore from '@/stores'
const router = useRouter() const router = useRouter()
@ -287,7 +303,8 @@ const MoreFilledPermission = () => {
permissionPrecise.value.generate() || permissionPrecise.value.generate() ||
permissionPrecise.value.edit() || permissionPrecise.value.edit() ||
permissionPrecise.value.export() || permissionPrecise.value.export() ||
permissionPrecise.value.delete() permissionPrecise.value.delete() ||
permissionPrecise.value.auth()
) )
} }
@ -306,6 +323,11 @@ const paginationConfig = reactive({
total: 0, total: 0,
}) })
const ResourceAuthorizationDrawerRef = ref()
function openAuthorization(item: any) {
ResourceAuthorizationDrawerRef.value.open(item.id)
}
const exportKnowledge = (item: any) => { const exportKnowledge = (item: any) => {
KnowledgeResourceApi.exportKnowledge(item.name, item.id, loading).then(() => { KnowledgeResourceApi.exportKnowledge(item.name, item.id, loading).then(() => {
MsgSuccess(t('common.exportSuccess')) MsgSuccess(t('common.exportSuccess'))

View File

@ -196,50 +196,61 @@
</el-tooltip> </el-tooltip>
<el-tooltip <el-tooltip
effect="dark" effect="dark"
:content="$t('views.model.modelForm.title.paramSetting')" :content="$t('views.system.resourceAuthorization.title')"
placement="top" placement="top"
v-if=" v-if="permissionPrecise.auth()"
(row.model_type === 'TTS' ||
row.model_type === 'LLM' ||
row.model_type === 'IMAGE' ||
row.model_type === 'TTI') &&
permissionPrecise.paramSetting()
"
> >
<span class="mr-8"> <span class="mr-8">
<el-button <el-button
type="primary" type="primary"
text text
:title="$t('views.model.modelForm.title.paramSetting')" :title="$t('views.system.resourceAuthorization.title')"
@click.stop="openParamSetting(row)" @click.stop="openAuthorization(row)"
> >
<AppIcon iconName="app-setting"></AppIcon> <AppIcon iconName="app-resource-authorization"></AppIcon>
</el-button>
</span>
</el-tooltip>
<el-tooltip
effect="dark"
:content="$t('common.delete')"
placement="top"
v-if="permissionPrecise.delete()"
>
<span class="mr-8">
<el-button
type="primary"
text
:title="$t('common.delete')"
@click.stop="deleteModel(row)"
>
<AppIcon iconName="app-delete"></AppIcon>
</el-button> </el-button>
</span> </span>
</el-tooltip> </el-tooltip>
<el-dropdown trigger="click" v-if="MoreFilledPermission()">
<el-button text @click.stop type="primary">
<AppIcon iconName="app-more"></AppIcon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
@click.stop="openAuthorization(row)"
v-if="
(row.model_type === 'TTS' ||
row.model_type === 'LLM' ||
row.model_type === 'IMAGE' ||
row.model_type === 'TTI') &&
permissionPrecise.paramSetting()
"
>
<AppIcon iconName="app-setting" class="color-secondary"></AppIcon>
{{ $t('views.model.modelForm.title.paramSetting') }}
</el-dropdown-item>
<el-dropdown-item
@click.stop="deleteModel(row)"
v-if="permissionPrecise.delete()"
>
<AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
{{ $t('common.delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template> </template>
</el-table-column> </el-table-column>
</app-table> </app-table>
</el-card> </el-card>
<EditModel ref="editModelRef" @submit="getList"></EditModel> <EditModel ref="editModelRef" @submit="getList"></EditModel>
<ParamSettingDialog ref="paramSettingRef" /> <ParamSettingDialog ref="paramSettingRef" />
<ResourceAuthorizationDrawer
:type="SourceTypeEnum.MODEL"
ref="ResourceAuthorizationDrawerRef"
/>
</div> </div>
</template> </template>
@ -249,6 +260,8 @@ import type { Provider, Model } from '@/api/type/model'
import EditModel from '@/views/model/component/EditModel.vue' import EditModel from '@/views/model/component/EditModel.vue'
import ParamSettingDialog from '@/views/model/component/ParamSettingDialog.vue' import ParamSettingDialog from '@/views/model/component/ParamSettingDialog.vue'
import ModelResourceApi from '@/api/system-resource-management/model' import ModelResourceApi from '@/api/system-resource-management/model'
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
import { SourceTypeEnum } from '@/enums/common'
import { modelTypeList } from '@/views/model/component/data' import { modelTypeList } from '@/views/model/component/data'
import { modelType } from '@/enums/model' import { modelType } from '@/enums/model'
import { t } from '@/locales' import { t } from '@/locales'
@ -283,6 +296,16 @@ const paginationConfig = reactive({
total: 0, total: 0,
}) })
// sync generete edit export delete
const MoreFilledPermission = () => {
return permissionPrecise.value.delete() || permissionPrecise.value.auth()
}
const ResourceAuthorizationDrawerRef = ref()
function openAuthorization(item: any) {
ResourceAuthorizationDrawerRef.value.open(item.id)
}
const deleteModel = (row: any) => { const deleteModel = (row: any) => {
MsgConfirm( MsgConfirm(
`${t('views.model.delete.confirmTitle')}${row.name} ?`, `${t('views.model.delete.confirmTitle')}${row.name} ?`,

View File

@ -270,16 +270,26 @@
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item
v-if="!row.template_id && row.tool_type === 'CUSTOM' && permissionPrecise.export()" @click.stop="openAuthorization(row)"
v-if="permissionPrecise.auth()"
>
<AppIcon
iconName="app-resource-authorization"
class="color-secondary"
></AppIcon>
{{ $t('views.system.resourceAuthorization.title') }}
</el-dropdown-item>
<el-dropdown-item
v-if="
!row.template_id && row.tool_type === 'CUSTOM' && permissionPrecise.export()
"
@click.stop="exportTool(row)" @click.stop="exportTool(row)"
> >
<AppIcon iconName="app-export" class="color-secondary"></AppIcon> <AppIcon iconName="app-export" class="color-secondary"></AppIcon>
{{ $t('common.export') }} {{ $t('common.export') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item v-if="row.tool_type === 'MCP'" @click.stop="showMcpConfig(row)">
v-if="row.tool_type === 'MCP'"
@click.stop="showMcpConfig(row)"
>
<AppIcon iconName="app-operate-log" class="color-secondary"></AppIcon> <AppIcon iconName="app-operate-log" class="color-secondary"></AppIcon>
{{ $t('views.tool.mcpConfig') }} {{ $t('views.tool.mcpConfig') }}
</el-dropdown-item> </el-dropdown-item>
@ -304,6 +314,7 @@
<McpToolFormDrawer ref="McpToolFormDrawerRef" @refresh="refresh" :title="McpToolDrawertitle" /> <McpToolFormDrawer ref="McpToolFormDrawerRef" @refresh="refresh" :title="McpToolDrawertitle" />
<AddInternalToolDialog ref="AddInternalToolDialogRef" @refresh="confirmAddInternalTool" /> <AddInternalToolDialog ref="AddInternalToolDialogRef" @refresh="confirmAddInternalTool" />
<McpToolConfigDialog ref="McpToolConfigDialogRef" @refresh="refresh" /> <McpToolConfigDialog ref="McpToolConfigDialogRef" @refresh="refresh" />
<ResourceAuthorizationDrawer :type="SourceTypeEnum.TOOL" ref="ResourceAuthorizationDrawerRef" />
</div> </div>
</template> </template>
@ -314,8 +325,10 @@ import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
import ToolResourceApi from '@/api/system-resource-management/tool' import ToolResourceApi from '@/api/system-resource-management/tool'
import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue' import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue'
import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue' import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
import McpToolFormDrawer from "@/views/tool/McpToolFormDrawer.vue"; import McpToolFormDrawer from '@/views/tool/McpToolFormDrawer.vue'
import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
import { t } from '@/locales' import { t } from '@/locales'
import { SourceTypeEnum } from '@/enums/common'
import { resetUrl } from '@/utils/common' import { resetUrl } from '@/utils/common'
import { ToolType } from '@/enums/tool' import { ToolType } from '@/enums/tool'
import useStore from '@/stores' import useStore from '@/stores'
@ -324,7 +337,7 @@ import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import UserApi from '@/api/user/user.ts' import UserApi from '@/api/user/user.ts'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message' import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import permissionMap from '@/permission' import permissionMap from '@/permission'
import McpToolConfigDialog from "@/views/tool/component/McpToolConfigDialog.vue"; import McpToolConfigDialog from '@/views/tool/component/McpToolConfigDialog.vue'
const { user } = useStore() const { user } = useStore()
@ -355,10 +368,16 @@ const MoreFilledPermission = (row: any) => {
return ( return (
permissionPrecise.value.export() || permissionPrecise.value.export() ||
permissionPrecise.value.delete() || permissionPrecise.value.delete() ||
permissionPrecise.value.auth() ||
(row.init_field_list?.length > 0 && permissionPrecise.value.edit()) (row.init_field_list?.length > 0 && permissionPrecise.value.edit())
) )
} }
const ResourceAuthorizationDrawerRef = ref()
function openAuthorization(item: any) {
ResourceAuthorizationDrawerRef.value.open(item.id)
}
function exportTool(row: any) { function exportTool(row: any) {
ToolResourceApi.exportTool(row.id, row.name, loading).catch((e: any) => { ToolResourceApi.exportTool(row.id, row.name, loading).catch((e: any) => {
if (e.response.status !== 403) { if (e.response.status !== 403) {
@ -371,11 +390,9 @@ function exportTool(row: any) {
const McpToolConfigDialogRef = ref() const McpToolConfigDialogRef = ref()
function showMcpConfig(item: any) { function showMcpConfig(item: any) {
ToolResourceApi ToolResourceApi.getToolById(item?.id, loading).then((res: any) => {
.getToolById(item?.id, loading) McpToolConfigDialogRef.value.open(res.data)
.then((res: any) => { })
McpToolConfigDialogRef.value.open(res.data)
})
} }
function deleteTool(row: any) { function deleteTool(row: any) {
@ -433,7 +450,6 @@ function openCreateDialog(data?: any) {
} }
} }
function openCreateMcpDialog(data?: any) { function openCreateMcpDialog(data?: any) {
// template_id // template_id
if (data?.template_id) { if (data?.template_id) {

View File

@ -216,7 +216,6 @@ function close() {
} else { } else {
MsgConfirm(t('common.tip'), t('views.tool.tip.saveMessage'), { MsgConfirm(t('common.tip'), t('views.tool.tip.saveMessage'), {
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
type: 'warning',
}) })
.then(() => { .then(() => {
visible.value = false visible.value = false

View File

@ -344,7 +344,6 @@ function close() {
} else { } else {
MsgConfirm(t('common.tip'), t('views.tool.tip.saveMessage'), { MsgConfirm(t('common.tip'), t('views.tool.tip.saveMessage'), {
confirmButtonText: t('common.confirm'), confirmButtonText: t('common.confirm'),
type: 'warning',
}) })
.then(() => { .then(() => {
visible.value = false visible.value = false

View File

@ -124,6 +124,7 @@
link link
@click="openMcpServersDialog" @click="openMcpServersDialog"
@refreshForm="refreshParam" @refreshForm="refreshParam"
v-if="chat_data.mcp_enable"
> >
<AppIcon iconName="app-setting"></AppIcon> <AppIcon iconName="app-setting"></AppIcon>
</el-button> </el-button>
@ -165,6 +166,7 @@
link link
@click="openToolDialog" @click="openToolDialog"
@refreshForm="refreshParam" @refreshForm="refreshParam"
v-if="chat_data.tool_enable"
> >
<AppIcon iconName="app-setting"></AppIcon> <AppIcon iconName="app-setting"></AppIcon>
</el-button> </el-button>
@ -201,6 +203,7 @@
@click="openReasoningParamSettingDialog" @click="openReasoningParamSettingDialog"
@refreshForm="refreshParam" @refreshForm="refreshParam"
class="mr-4" class="mr-4"
v-if="chat_data.model_setting.reasoning_content_enable"
> >
<AppIcon iconName="app-setting"></AppIcon> <AppIcon iconName="app-setting"></AppIcon>
</el-button> </el-button>