feat: Tool reaource

This commit is contained in:
wangdan-fit2cloud 2025-07-25 18:08:38 +08:00
parent f744e8b109
commit bf7d5c2e61
7 changed files with 289 additions and 31 deletions

View File

@ -37,6 +37,20 @@ const getToolListPage: (
return get(`${prefix}/${page.current_page}/${page.page_size}`, param, loading)
}
/**
*
* @param tool_id id
* @param loading
* @returns
*/
const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
tool_id,
loading,
) => {
return get(`${prefix}/${tool_id}`, undefined, loading)
}
/**
*
* @param
@ -50,18 +64,6 @@ const putTool: (tool_id: string, data: toolData, loading?: Ref<boolean>) => Prom
return put(`${prefix}/${tool_id}`, data, undefined, loading)
}
/**
*
* @param tool_id id
* @param loading
* @returns
*/
const getToolById: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
tool_id,
loading,
) => {
return get(`${prefix}/${tool_id}`, undefined, loading)
}
/**
*

View File

@ -27,7 +27,7 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router'
import { isAppIcon, resetUrl } from '@/utils/common'
import { resetUrl } from '@/utils/common'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import useStore from '@/stores'
const { common, application } = useStore()

View File

@ -15,7 +15,7 @@ import problemSystemShareApi from '@/api/system-shared/problem'
import chatUserSystemShareApi from '@/api/system-shared/chat-user'
import workspaceApi from '@/api/workspace/workspace'
import systemUserApi from '@/api/user/user'
import workspaceShare from '@/permission/knowledge/workspace-share'
import ToolResourceApi from '@/api/system-resource-management/tool'
// 普通 API
const workspaceApiMap = {
@ -45,7 +45,7 @@ const systemShareApiMap = {
const systemManageApiMap = {
// knowledge: knowledgeWorkspaceApi,
// model: modelWorkspaceApi,
// tool: toolSystemShareApi,
tool: ToolResourceApi,
} as any
const data = {

View File

@ -210,7 +210,7 @@ import applicationApi from '@/api/application/application'
import { nowDate, beforeDay } from '@/utils/time'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { copyClick } from '@/utils/clipboard'
import { isAppIcon, resetUrl } from '@/utils/common'
import { resetUrl } from '@/utils/common'
import { mapToUrlParams } from '@/utils/application'
import useStore from '@/stores'
import { t } from '@/locales'

View File

@ -307,7 +307,7 @@ import useStore from '@/stores'
import { t } from '@/locales'
import { useRouter, useRoute } from 'vue-router'
import { isWorkFlow } from '@/utils/application'
import { isAppIcon, resetUrl } from '@/utils/common'
import { resetUrl } from '@/utils/common'
import { dateFormat } from '@/utils/time'
import { SourceTypeEnum, ValidType, ValidCount } from '@/enums/common'
import permissionMap from '@/permission'

View File

@ -49,23 +49,23 @@
>
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column width="220" :label="$t('common.name')" show-overflow-tooltip>
<template #default="scope">
<template #default="{ row }">
<div class="table-name flex align-center">
<el-icon size="24" class="mr-8">
<el-avatar
v-if="isAppIcon(scope.row?.icon)"
v-if="row?.icon"
shape="square"
:size="24"
style="background: none"
class="mr-8"
>
<img :src="resetUrl(scope.row?.icon)" alt="" />
<img :src="resetUrl(row?.icon)" alt="" />
</el-avatar>
<el-avatar v-else class="avatar-green" shape="square" :size="24">
<img src="@/assets/workflow/icon_tool.svg" style="width: 58%" alt="" />
</el-avatar>
</el-icon>
{{ scope.row.name }}
{{ row.name }}
</div>
</template>
</el-table-column>
@ -158,21 +158,136 @@
{{ datetimeFormat(row.create_time) }}
</template>
</el-table-column>
<el-table-column :label="$t('common.operation')" align="left" width="160" fixed="right">
<template #default="{ row }">
<span @click.stop>
<el-switch
v-model="row.is_active"
:before-change="() => changeState(row)"
size="small"
class="mr-4"
v-if="permissionPrecise.switch(row.id)"
/>
</span>
<el-divider direction="vertical" />
<el-tooltip
effect="dark"
:content="$t('common.edit')"
placement="top"
v-if="row.template_id && permissionPrecise.edit(row.id)"
>
<span class="mr-8">
<el-button
type="primary"
text
@click.stop="addInternalTool(row, true)"
:title="$t('common.edit')"
>
<el-icon>
<EditPen />
</el-icon>
</el-button>
</span>
</el-tooltip>
<el-tooltip
effect="dark"
:content="$t('common.edit')"
placement="top"
v-if="!row.template_id && permissionPrecise.edit(row.id)"
>
<span class="mr-8">
<el-button
type="primary"
text
@click.stop="openCreateDialog(row)"
:title="$t('common.edit')"
>
<el-icon>
<EditPen />
</el-icon>
</el-button>
</span>
</el-tooltip>
<el-tooltip
effect="dark"
:content="$t('common.copy')"
placement="top"
v-if="!row.template_id && permissionPrecise.copy(row.id)"
>
<span class="mr-8">
<el-button
type="primary"
text
@click.stop="copyTool(row)"
:title="$t('common.copy')"
>
<AppIcon iconName="app-copy"></AppIcon>
</el-button>
</span>
</el-tooltip>
<el-dropdown trigger="click">
<el-button text @click.stop>
<el-icon>
<MoreFilled />
</el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-if="row.init_field_list?.length > 0 && permissionPrecise.edit(row.id)"
@click.stop="configInitParams(row)"
>
<AppIcon iconName="app-operation" class="mr-4"></AppIcon>
{{ $t('common.param.initParam') }}
</el-dropdown-item>
<el-dropdown-item
v-if="!row.template_id && permissionPrecise.export(row.id)"
@click.stop="exportTool(row)"
>
<AppIcon iconName="app-export"></AppIcon>
{{ $t('common.export') }}
</el-dropdown-item>
<el-dropdown-item
v-if="permissionPrecise.delete(row.id)"
divided
@click.stop="deleteTool(row)"
>
<el-icon><Delete /></el-icon>
{{ $t('common.delete') }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</app-table>
</el-card>
<InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh" />
<ToolFormDrawer ref="ToolFormDrawerRef" @refresh="refresh" :title="ToolDrawertitle" />
<AddInternalToolDialog ref="AddInternalToolDialogRef" @refresh="confirmAddInternalTool" />
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref, reactive, computed } from 'vue'
import { cloneDeep } from 'lodash'
import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
import ToolResourceApi from '@/api/system-resource-management/tool'
import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue'
import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
import { t } from '@/locales'
import { isAppIcon, resetUrl } from '@/utils/common'
import { resetUrl } from '@/utils/common'
import { ToolType } from '@/enums/tool'
import useStore from '@/stores'
import { datetimeFormat } from '@/utils/time'
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
import UserApi from '@/api/user/user.ts'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import permissionMap from '@/permission'
const { user } = useStore()
@ -194,6 +309,137 @@ const paginationConfig = reactive({
const workspaceOptions = ref<any[]>([])
const workspaceVisible = ref(false)
const workspaceArr = ref<any[]>([])
const permissionPrecise = computed(() => {
return permissionMap['tool']['systemManage']
})
function exportTool(row: any) {
ToolResourceApi.exportTool(row.id, row.name, loading).catch((e: any) => {
if (e.response.status !== 403) {
e.response.data.text().then((res: string) => {
MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
})
}
})
}
function deleteTool(row: any) {
MsgConfirm(
`${t('views.tool.delete.confirmTitle')}${row.name} ?`,
t('views.tool.delete.confirmMessage'),
{
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
confirmButtonClass: 'danger',
},
)
.then(() => {
ToolResourceApi.delTool(row.id, loading).then(() => {
getList()
MsgSuccess(t('common.deleteSuccess'))
})
})
.catch(() => {})
}
function configInitParams(item: any) {
ToolResourceApi.getToolById(item?.id, changeStateloading).then((res: any) => {
InitParamDrawerRef.value.open(res.data)
})
}
async function copyTool(row: any) {
ToolDrawertitle.value = t('views.tool.copyTool')
const res = await ToolResourceApi.getToolById(row.id, changeStateloading)
const obj = cloneDeep(res.data)
delete obj['id']
obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
ToolFormDrawerRef.value.open(obj)
}
const ToolFormDrawerRef = ref()
const ToolDrawertitle = ref('')
function openCreateDialog(data?: any) {
// template_id
if (data?.template_id) {
return
}
ToolDrawertitle.value = t('views.tool.editTool')
if (data) {
ToolResourceApi.getToolById(data?.id, loading).then((res: any) => {
ToolFormDrawerRef.value.open(res.data)
})
} else {
ToolFormDrawerRef.value.open(data)
}
}
const AddInternalToolDialogRef = ref<InstanceType<typeof AddInternalToolDialog>>()
function addInternalTool(data?: any, isEdit?: boolean) {
AddInternalToolDialogRef.value?.open(data, isEdit)
}
function confirmAddInternalTool(data?: any, isEdit?: boolean) {
if (isEdit) {
ToolResourceApi.putTool(data?.id as string, { name: data.name }, loading).then((res: any) => {
MsgSuccess(t('common.saveSuccess'))
refresh()
})
}
}
const InitParamDrawerRef = ref()
async function changeState(row: any) {
if (row.is_active) {
MsgConfirm(
`${t('views.tool.disabled.confirmTitle')}${row.name} ?`,
t('views.tool.disabled.confirmMessage'),
{
confirmButtonText: t('common.status.disable'),
confirmButtonClass: 'danger',
},
).then(() => {
const obj = {
is_active: !row.is_active,
}
ToolResourceApi.putTool(row.id, obj, changeStateloading)
.then(() => {
getList()
return true
})
.catch(() => {
return false
})
})
} else {
const res = await ToolResourceApi.getToolById(row.id, changeStateloading)
if (
(!res.data.init_params || Object.keys(res.data.init_params).length === 0) &&
res.data.init_field_list &&
res.data.init_field_list.length > 0 &&
res.data.init_field_list.filter((item: any) => item.default_value && item.show_default_value)
.length !== res.data.init_field_list.length
) {
InitParamDrawerRef.value.open(res.data, !row.is_active)
return false
}
const obj = {
is_active: !row.is_active,
}
ToolResourceApi.putTool(row.id, obj, changeStateloading)
.then(() => {
getList()
return true
})
.catch(() => {
return false
})
}
}
function filterWorkspaceChange(val: string) {
if (val === 'clear') {
workspaceArr.value = []
@ -228,6 +474,16 @@ function getList() {
})
}
function refresh(data?: any) {
if (data) {
getList()
} else {
paginationConfig.total = 0
paginationConfig.current_page = 1
getList()
}
}
onMounted(() => {
getWorkspaceList()
getList()

View File

@ -65,7 +65,7 @@
:on-change="(file: any, fileList: any) => importTool(file)"
class="import-button"
>
<el-dropdown-item
<el-dropdown-item
v-if="permissionPrecise.import()"
>
<div class="flex align-center w-full">
@ -197,7 +197,7 @@
</div>
</template>
<template #mouseEnter>
<div @click.stop v-if="!isShared &&
<div @click.stop v-if="!isShared &&
MoreFieldPermission(item.id)">
<el-switch
v-model="item.is_active"
@ -309,18 +309,18 @@
<script lang="ts" setup>
import { onMounted, ref, reactive, computed, watch } from 'vue'
import { cloneDeep, get } from 'lodash'
import { cloneDeep } from 'lodash'
import { useRoute, onBeforeRouteLeave } from 'vue-router'
import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
import { isAppIcon, resetUrl } from '@/utils/common'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import { SourceTypeEnum } from '@/enums/common'
import ToolStoreDialog from '@/views/tool/toolStore/ToolStoreDialog.vue'
import AddInternalToolDialog from '@/views/tool/toolStore/AddInternalToolDialog.vue'
import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
import { resetUrl } from '@/utils/common'
import { MsgSuccess, MsgConfirm, MsgError } from '@/utils/message'
import { SourceTypeEnum } from '@/enums/common'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import permissionMap from '@/permission'
import useStore from '@/stores'
@ -354,8 +354,8 @@ const permissionPrecise = computed(() => {
})
const MoreFieldPermission = (id: any) => {
return (permissionPrecise.value.edit(id) ||
permissionPrecise.value.export(id) ||
return (permissionPrecise.value.edit(id) ||
permissionPrecise.value.export(id) ||
permissionPrecise.value.delete(id) || isSystemShare.value)
}