feat: tool

This commit is contained in:
wangdan-fit2cloud 2025-06-24 16:53:58 +08:00
parent 77295d2c13
commit bb0ad0a27b
30 changed files with 229 additions and 1016 deletions

View File

@ -39,20 +39,34 @@
</template>
<script setup lang="ts">
import {ref, computed, watch} from 'vue'
import {Codemirror} from 'vue-codemirror'
import {python} from '@codemirror/lang-python'
import {oneDark} from '@codemirror/theme-one-dark'
import {linter, type Diagnostic} from '@codemirror/lint'
import ToolApi from '@/api/system-shared/tool'
import { ref, computed, watch } from 'vue'
import { useRoute } from 'vue-router'
import { Codemirror } from 'vue-codemirror'
import { python } from '@codemirror/lang-python'
import { oneDark } from '@codemirror/theme-one-dark'
import { linter, type Diagnostic } from '@codemirror/lint'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
defineOptions({name: 'CodemirrorEditor'})
defineOptions({ name: 'CodemirrorEditor' })
const props = defineProps<{
title: string
modelValue: any
}>()
const emit = defineEmits(['update:modelValue', 'submitDialog'])
const route = useRoute()
const type = computed(() => {
if (route.path.includes('shared')) {
return 'systemShare'
} else if (route.path.includes('resource-management')) {
return 'systemManage'
} else {
return 'workspace'
}
})
const data = computed({
set: (value) => {
emit('update:modelValue', value)
@ -74,23 +88,25 @@ function getRangeFromLineAndColumn(state: any, line: number, column: number, end
const regexpLinter = linter(async (view) => {
const diagnostics: Diagnostic[] = []
await ToolApi.postPylint(view.state.doc.toString()).then((ok) => {
ok.data.forEach((element: any) => {
const range = getRangeFromLineAndColumn(
view.state,
element.line,
element.column,
element.endColumn,
)
await loadSharedApi({ type: 'tool', systemType: type.value })
.postPylint(view.state.doc.toString())
.then((ok: any) => {
ok.data.forEach((element: any) => {
const range = getRangeFromLineAndColumn(
view.state,
element.line,
element.column,
element.endColumn,
)
diagnostics.push({
from: range.form,
to: range.to,
severity: element.type,
message: element.message,
diagnostics.push({
from: range.form,
to: range.to,
severity: element.type,
message: element.message,
})
})
})
})
return diagnostics
})
const extensions = [python(), regexpLinter, oneDark]

View File

@ -33,7 +33,7 @@
<div class="flex-between w-full" @mouseenter.stop="handleMouseEnter(data)">
<div class="flex align-center">
<AppIcon iconName="app-folder" style="font-size: 16px"></AppIcon>
<span class="ml-8">{{ node.label }}</span>
<span class="ml-8 ellipsis" style="max-width:110px" :label="node.label">{{ node.label }}</span>
</div>
<div
@ -109,7 +109,7 @@ const props = defineProps({
},
shareTitle: {
type: String,
default: 'views.system.shared.shared_knowledge',
default: '',
},
canOperation: {
type: Boolean,

View File

@ -11,11 +11,12 @@
<slot name="search"> </slot>
</div>
</div>
<el-scrollbar>
<div class="content-container__main p-16">
<div class="content-container__main">
<el-scrollbar class="p-16" style="padding-right: 0;">
<slot></slot>
</div>
</el-scrollbar>
</el-scrollbar>
</div>
</div>
</template>

View File

@ -21,7 +21,7 @@
/>
</div>
<TopMenu></TopMenu>
<TopAbout></TopAbout>
<TopAbout class="mt-4 mr-12"></TopAbout>
</div>
<Avatar></Avatar>
</div>

View File

@ -115,7 +115,7 @@ export default {
shared_resources: '共享资源',
shared_tool: '共享工具',
shared_model: '共享模型',
shared_knowledge: '共享知识',
shared_knowledge: '共享知识',
authorized_workspace: '授权工作区',
},
resource_management: {

View File

@ -1,62 +0,0 @@
const DocumentRouter = {
path: '/knowledge/system/:id/',
name: 'KnowledgeDetailSharedSystem',
meta: { title: 'common.fileUpload.document', activeMenu: '/knowledge', breadcrumb: true },
component: () => import('@/layout/layout-template/MainLayout.vue'),
hidden: true,
children: [
{
path: 'documentShared',
name: 'DocumentSharedSystem',
meta: {
icon: 'app-document',
iconActive: 'app-document-active',
title: 'common.fileUpload.document',
active: 'documentShared',
parentPath: '/knowledge/system/:id/',
parentName: 'KnowledgeDetailSharedSystem',
},
component: () => import('@/views/shared/document-shared/index.vue'),
},
{
path: 'problemShared',
name: 'ProblemSharedSystem',
meta: {
icon: 'app-problems',
iconActive: 'QuestionFilled',
title: 'views.problem.title',
active: 'problemShared',
parentPath: '/knowledge/system/:id/',
parentName: 'KnowledgeDetailSharedSystem',
},
component: () => import('@/views/shared/problem-shared/index.vue'),
},
{
path: 'hit-test-shared',
name: 'KnowledgeHitTestSharedSystem',
meta: {
icon: 'app-hit-test',
title: 'views.application.hitTest.title',
active: 'hit-test-shared',
parentPath: '/knowledge/system/:id/',
parentName: 'KnowledgeDetailSharedSystem',
},
component: () => import('@/views/shared/hit-test-shared/index.vue'),
},
{
path: 'settingShared',
name: 'settingSharedSystem',
meta: {
icon: 'app-setting',
iconActive: 'app-setting-active',
title: 'common.setting',
active: 'settingShared',
parentPath: '/knowledge/system/:id/',
parentName: 'KnowledgeDetailSharedSystem',
},
component: () => import('@/views/shared/knowledge-shared/KnowledgeSetting.vue'),
}
],
}
export default DocumentRouter

View File

@ -1,26 +0,0 @@
const ModelRouter = {
path: '/knowledge/system',
name: 'knowledgeSharedSystem',
meta: { title: 'views.knowledge.title', permission: 'KNOWLEDGE:READ' },
hidden: true,
redirect: '/knowledge',
component: () => import('@/layout/layout-template/SimpleLayout.vue'),
children: [
{
path: '/knowledge/system/document/upload/shared',
name: 'UploadDocumentSharedSystem',
meta: { activeMenu: '/knowledge/system' },
component: () => import('@/views/shared/document-shared/UploadDocument.vue'),
hidden: true,
},
{
path: '/knowledge/system/import/shared',
name: 'ImportLarkDocumentShared',
meta: { activeMenu: '/knowledge' },
component: () => import('@/views/shared/document-shared/ImportLarkDocument.vue'),
hidden: true,
},
],
}
export default ModelRouter

View File

@ -1,17 +0,0 @@
const ParagraphRouter = {
path: '/paragraph/system/:id/:documentId/shared',
name: 'ParagraphSharedSystem',
meta: { title: 'common.fileUpload.document', activeMenu: '/knowledge', breadcrumb: true },
component: () => import('@/layout/layout-template/SimpleLayout.vue'),
hidden: true,
children: [
{
path: '/paragraph/system/:id/:documentId/shared',
name: 'ParagraphIndexSharedSystem',
meta: { activeMenu: '/knowledge' },
component: () => import('@/views/shared/paragraph-shared/index.vue'),
},
],
}
export default ParagraphRouter

View File

@ -157,7 +157,7 @@ const systemRouter = {
parentPath: '/system',
parentName: 'system',
},
component: () => import('@/views/shared/model-shared/index.vue'),
component: () => import('@/views/system-shared/ModelSharedIndex.vue'),
},
],
},

View File

@ -1,52 +0,0 @@
import { defineStore } from 'pinia'
import { DeviceType, ValidType } from '@/enums/common'
// import type { Ref } from 'vue'
// import userApi from '@/api/user/user'
export interface commonTypes {
breadcrumb: any
paginationConfig: any | null
search: any
device: string
}
const useCommonStore = defineStore('commo',{
state: (): commonTypes => ({
breadcrumb: null,
// 搜索和分页缓存
paginationConfig: {},
search: {},
device: DeviceType.Desktop
}),
actions: {
saveBreadcrumb(data: any) {
this.breadcrumb = data
},
savePage(val: string, data: any) {
this.paginationConfig[val] = data
},
saveCondition(val: string, data: any) {
this.search[val] = data
},
toggleDevice(value: DeviceType) {
this.device = value
},
isMobile() {
return this.device === DeviceType.Mobile
},
// async asyncGetValid(valid_type: ValidType, valid_count: number, loading?: Ref<boolean>) {
// return new Promise((resolve, reject) => {
// userApi
// .getValid(valid_type, valid_count, loading)
// .then((data) => {
// resolve(data)
// })
// .catch((error) => {
// reject(error)
// })
// })
// }
}
})
export default useCommonStore

View File

@ -1,35 +0,0 @@
import { defineStore } from 'pinia'
import documentApi from '@/api/system-shared/document'
import { type Ref } from 'vue'
const useDocumentStore = defineStore('documen', {
state: () => ({}),
actions: {
async asyncGetAllDocument(id: string, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
documentApi
.getAllDocument(id, loading)
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
async asyncPutDocument(knowledgeId: string, data: any, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
documentApi
.putMulDocument(knowledgeId, data, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useDocumentStore

View File

@ -1,23 +0,0 @@
import {defineStore} from 'pinia'
import {type Ref} from 'vue'
import folderApi from '@/api/folder'
const useFolderStore = defineStore('folde', {
state: () => ({}),
actions: {
async asyncGetFolder(source: string, data: any, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
folderApi
.getFolder(source, data, loading)
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useFolderStore

View File

@ -1,23 +0,0 @@
import useCommonStore from './common'
import useLoginStore from './login'
import useFolderStore from './folder'
import useKnowledgeStore from './knowledge'
import useModelStore from './model'
import usePromptStore from './prompt'
import useProblemStore from './problem'
import useParagraphStore from './paragraph'
import useDocumentStore from './document'
const useStore = () => ({
common: useCommonStore(),
login: useLoginStore(),
folder: useFolderStore(),
knowledge: useKnowledgeStore(),
model: useModelStore(),
prompt: usePromptStore(),
problem: useProblemStore(),
paragraph: useParagraphStore(),
document: useDocumentStore(),
})
export default useStore

View File

@ -1,64 +0,0 @@
import { defineStore } from 'pinia'
import type { knowledgeData } from '@/api/type/knowledge'
import type { UploadUserFile } from 'element-plus'
import knowledgeApi from '@/api/system-shared/knowledge'
import { type Ref } from 'vue'
export interface knowledgeStateTypes {
baseInfo: knowledgeData | null
webInfo: any
documentsType: string
documentsFiles: UploadUserFile[]
}
const useKnowledgeStore = defineStore('knowledg', {
state: (): knowledgeStateTypes => ({
baseInfo: null,
webInfo: null,
documentsType: '',
documentsFiles: [],
}),
actions: {
saveBaseInfo(info: knowledgeData | null) {
this.baseInfo = info
},
saveWebInfo(info: any) {
this.webInfo = info
},
saveDocumentsType(val: string) {
this.documentsType = val
},
saveDocumentsFile(file: UploadUserFile[]) {
this.documentsFiles = file
},
async asyncGetFolderKnowledge(loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
const params = {
folder_id: 'default',
}
knowledgeApi
.getKnowledgeList(params, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
async asyncGetKnowledgeDetail(knowledge_id: string, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
knowledgeApi
.getKnowledgeDetail(knowledge_id, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useKnowledgeStore

View File

@ -1,52 +0,0 @@
import {defineStore} from 'pinia'
import {type Ref} from 'vue'
import loginApi from '@/api/user/login'
import type { LoginRequest } from '@/api/type/login'
import useUserStore from '@/stores/modules/user'
const useLoginStore = defineStore('logi', {
state: () => ({
token: '',
userAccessToken: '',
}),
actions: {
getToken(): string | null {
if (this.token) {
return this.token
}
const user = useUserStore()
return user.userType === 1 ? localStorage.getItem('token') : this.getAccessToken()
},
getAccessToken() {
const token = sessionStorage.getItem(`${this.userAccessToken}-accessToken`)
if (token) {
return token
}
const local_token = localStorage.getItem(`${token}-accessToken`)
if (local_token) {
return local_token
}
return localStorage.getItem(`accessToken`)
},
async asyncLogin(data: LoginRequest, loading?: Ref<boolean>) {
return loginApi.login(data).then((ok) => {
this.token = ok?.data?.token
localStorage.setItem('token', ok?.data?.token)
const user = useUserStore()
return user.profile(loading)
})
},
async asyncLdapLogin(data: LoginRequest, loading?: Ref<boolean>) {
return loginApi.ldapLogin(data).then((ok) => {
this.token = ok?.data?.token
localStorage.setItem('token', ok?.data?.token)
const user = useUserStore()
return user.profile(loading)
})
},
},
})
export default useLoginStore

View File

@ -1,35 +0,0 @@
import {defineStore} from 'pinia'
import {type Ref} from 'vue'
import ModelApi from '@/api/system-shared/model'
import ProviderApi from '@/api/model/provider'
import type {ListModelRequest} from '@/api/type/model'
const useModelStore = defineStore('mode', {
state: () => ({}),
actions: {
async asyncGetModel(data?: ListModelRequest, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
ModelApi.getModel(data, loading)
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
async asyncGetProvider(loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
ProviderApi.getProvider(loading)
.then((res) => {
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useModelStore

View File

@ -1,91 +0,0 @@
import { defineStore } from 'pinia'
import paragraphApi from '@/api/system-shared/paragraph'
import type { Ref } from 'vue'
const useParagraphStore = defineStore('paragrap', {
state: () => ({}),
actions: {
async asyncPutParagraph(
knowledgeId: string,
documentId: string,
paragraphId: string,
data: any,
loading?: Ref<boolean>,
) {
return new Promise((resolve, reject) => {
paragraphApi
.putParagraph(knowledgeId, documentId, paragraphId, data, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
async asyncDelParagraph(
knowledgeId: string,
documentId: string,
paragraphId: string,
loading?: Ref<boolean>,
) {
return new Promise((resolve, reject) => {
paragraphApi
.delParagraph(knowledgeId, documentId, paragraphId, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
async asyncDisassociationProblem(
knowledgeId: string,
documentId: string,
paragraphId: string,
problemId: string,
loading?: Ref<boolean>,
) {
return new Promise((resolve, reject) => {
const obj = {
paragraphId,
problemId,
}
paragraphApi
.putDisassociationProblem(knowledgeId, documentId, obj, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
async asyncAssociationProblem(
knowledgeId: string,
documentId: string,
paragraphId: string,
problemId: string,
loading?: Ref<boolean>,
) {
return new Promise((resolve, reject) => {
const obj = {
paragraphId,
problemId,
}
paragraphApi
.putAssociationProblem(knowledgeId, documentId, obj, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useParagraphStore

View File

@ -1,41 +0,0 @@
import { defineStore } from 'pinia'
import { type Ref } from 'vue'
import problemApi from '@/api/system-shared/problem'
import type { pageRequest } from '@/api/type/common'
const useProblemStore = defineStore('proble', {
state: () => ({}),
actions: {
async asyncPostProblem(knowledgeId: string, data: any, loading?: Ref<boolean>) {
return new Promise((resolve, reject) => {
problemApi
.postProblems(knowledgeId, data, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
async asyncGetProblem(
knowledgeId: string,
page: pageRequest,
param: any,
loading?: Ref<boolean>,
) {
return new Promise((resolve, reject) => {
problemApi
.getProblemsPage(knowledgeId, page, param, loading)
.then((data) => {
resolve(data)
})
.catch((error) => {
reject(error)
})
})
},
},
})
export default useProblemStore

View File

@ -1,37 +0,0 @@
import { defineStore } from 'pinia'
import { t } from '@/locales'
export interface promptTypes {
user: string
formValue: { model_id: string; prompt: string }
}
const usePromptStore = defineStore('promp', {
state: (): promptTypes[] => JSON.parse(localStorage.getItem('PROMPT_CACHE') || '[]'),
actions: {
save(user: string, formValue: any) {
this.$state.forEach((item: any, index: number) => {
if (item.user === user) {
this.$state.splice(index, 1)
}
})
this.$state.push({ user, formValue })
localStorage.setItem('PROMPT_CACHE', JSON.stringify(this.$state))
},
get(user: string) {
for (let i = 0; i < this.$state.length; i++) {
if (this.$state[i].user === user) {
return this.$state[i].formValue
}
}
return {
model_id: '',
prompt:
t('views.document.generateQuestion.prompt1', { data: '{data}' }) +
'<question></question>' +
t('views.document.generateQuestion.prompt2'),
}
},
},
})
export default usePromptStore

View File

@ -4,12 +4,6 @@
--el-text-color-primary: #1f2329;
--el-border-radius-base: 6px;
--el-menu-item-height: 45px;
// --el-box-shadow-light: 0px 2px 4px 0px rgba(31, 35, 41, 0.12);
// --el-border-color: #dee0e3;
// --el-color-info: #8f959e !important;
// --el-disabled-bg-color: #eff0f1 !important;
// --el-font-line-height-primary: 22px;
}
.el-avatar {

View File

@ -8,7 +8,7 @@
:currentNodeKey="currentFolder?.id"
@handleNodeClick="folderClickHandel"
class="p-8"
:shareTitle="$t('views.system.share_knowledge')"
:shareTitle="$t('views.system.shared.shared_knowledge')"
:showShared="permissionPrecise['is_share']()"
@refreshTree="refreshFolder"
/>
@ -46,11 +46,7 @@
</el-select>
</div>
<el-dropdown trigger="click" v-if="!isShared">
<el-button
type="primary"
class="ml-8"
v-if="permissionPrecise.create()"
>
<el-button type="primary" class="ml-8" v-if="permissionPrecise.create()">
{{ $t('common.create') }}
<el-icon class="el-icon--right">
<arrow-down />
@ -156,7 +152,7 @@
@load="getList"
:loading="loading"
>
<el-row v-if="knowledgeList.length > 0" :gutter="15">
<el-row v-if="knowledgeList.length > 0" :gutter="15" class="w-full">
<template v-for="(item, index) in knowledgeList" :key="index">
<el-col
v-if="item.resource_type === 'folder'"
@ -239,16 +235,12 @@
<el-dropdown-item
icon="Refresh"
@click.stop="syncKnowledge(item)"
v-if="item.type === 1 &&
permissionPrecise.sync(item.id)
"
v-if="item.type === 1 && permissionPrecise.sync(item.id)"
>{{ $t('views.knowledge.setting.sync') }}
</el-dropdown-item>
<el-dropdown-item
@click.stop="reEmbeddingKnowledge(item)"
v-if="
permissionPrecise.vector(item.id)
"
v-if="permissionPrecise.vector(item.id)"
>
<AppIcon iconName="app-vectorization"></AppIcon>
{{ $t('views.knowledge.setting.vectorization') }}
@ -257,9 +249,7 @@
<el-dropdown-item
icon="Connection"
@click.stop="openGenerateDialog(item)"
v-if="
permissionPrecise.doc_generate(item.id)
"
v-if="permissionPrecise.doc_generate(item.id)"
>{{ $t('views.document.generateQuestion.title') }}
</el-dropdown-item>
<el-dropdown-item
@ -269,26 +259,20 @@
path: `/knowledge/${item.id}/${currentFolder.value}/setting`,
})
"
v-if="
permissionPrecise.setting(item.id)
"
v-if="permissionPrecise.setting(item.id)"
>
{{ $t('common.setting') }}
</el-dropdown-item>
<el-dropdown-item
@click.stop="exportKnowledge(item)"
v-if="
permissionPrecise.export(item.id)
"
v-if="permissionPrecise.export(item.id)"
>
<AppIcon iconName="app-export"></AppIcon
>{{ $t('views.document.setting.export') }} Excel
</el-dropdown-item>
<el-dropdown-item
@click.stop="exportZipKnowledge(item)"
v-if="
permissionPrecise.export(item.id)
"
v-if="permissionPrecise.export(item.id)"
>
<AppIcon iconName="app-export"></AppIcon
>{{ $t('views.document.setting.export') }} ZIP</el-dropdown-item
@ -297,9 +281,7 @@
icon="Delete"
type="danger"
@click.stop="deleteKnowledge(item)"
v-if="
permissionPrecise.delete(item.id)
"
v-if="permissionPrecise.delete(item.id)"
>
{{ $t('common.delete') }}</el-dropdown-item
>
@ -337,15 +319,14 @@ import { MsgSuccess, MsgConfirm } from '@/utils/message'
import useStore from '@/stores'
import { numberFormat } from '@/utils/common'
import { t } from '@/locales'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { FolderSource } from '@/enums/common'
import { PermissionConst, RoleConst } from '@/utils/permission/data'
import { hasPermission } from '@/utils/permission/index'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import { useRoute } from 'vue-router'
import permissionMap from '@/permission'
const router = useRouter()
const route = useRoute()
const { folder, user } = useStore()
@ -362,8 +343,6 @@ const permissionPrecise = computed(() => {
return permissionMap['knowledge'][type.value]
})
const router = useRouter()
const loading = ref(false)
const search_type = ref('name')

View File

@ -5,7 +5,7 @@
<div
@click="handleSharedNodeClick"
class="shared-model"
v-if="isShared && hasPermission(EditionConst.IS_EE, 'OR')"
v-if="showShared && hasPermission(EditionConst.IS_EE, 'OR')"
:class="active?.provider === 'share' && 'active'"
>
<AppIcon iconName="app-folder-share-active" style="font-size: 18px"></AppIcon>
@ -108,7 +108,7 @@ import { t } from '@/locales'
const props = defineProps<{
data: Array<Provider>
loading: boolean
isShared?: boolean
showShared?: boolean
active?: Provider
}>()
const emit = defineEmits(['click'])

View File

@ -6,12 +6,15 @@
:data="provider_list"
@click="clickListHandle"
:loading="loading"
shareTitle="views.system.shared.shared_tool"
:showShared="permissionPrecise['is_share']()"
:active="active_provider"
/>
</template>
<ContentContainer :header="active_provider?.name" v-loading="list_model_loading">
<ContentContainer
:header="active_provider?.name"
v-loading="list_model_loading"
style="padding: 0"
>
<template #search>
<div class="flex">
<div class="flex-between complex-search">
@ -55,9 +58,7 @@
</el-select>
</div>
<el-button
v-if="!isShared &&
permissionPrecise.addModel()
"
v-if="!isShared && permissionPrecise.addModel()"
class="ml-16"
type="primary"
@click="openCreateModel(active_provider)"
@ -68,32 +69,30 @@
</template>
<div class="model-list-height">
<el-scrollbar>
<el-row v-if="model_split_list.length > 0" :gutter="15" class="w-full">
<template v-for="(row, index) in model_split_list" :key="index">
<el-col
:xs="24"
:sm="12"
:md="12"
:lg="8"
:xl="6"
class="mb-16"
v-for="(model, i) in row"
:key="i"
<el-row v-if="model_split_list.length > 0" :gutter="15" class="w-full">
<template v-for="(row, index) in model_split_list" :key="index">
<el-col
:xs="24"
:sm="12"
:md="12"
:lg="8"
:xl="6"
class="mb-16"
v-for="(model, i) in row"
:key="i"
>
<ModelCard
@change="list_model"
:updateModelById="updateModelById"
:model="model"
:provider_list="provider_list"
:isShared="isShared"
>
<ModelCard
@change="list_model"
:updateModelById="updateModelById"
:model="model"
:provider_list="provider_list"
:isShared="isShared"
>
</ModelCard>
</el-col>
</template>
</el-row>
<el-empty :description="$t('common.noData')" v-else />
</el-scrollbar>
</ModelCard>
</el-col>
</template>
</el-row>
<el-empty :description="$t('common.noData')" v-else />
</div>
</ContentContainer>
@ -129,7 +128,6 @@ import { useRoute } from 'vue-router'
import useStore from '@/stores'
import permissionMap from '@/permission'
const route = useRoute()
const { folder, user } = useStore()
@ -231,6 +229,7 @@ onMounted(() => {
.model-manage {
.model-list-height {
height: calc(var(--app-main-height));
padding-right: 0 !important;
}
}
</style>

View File

@ -1,239 +1,25 @@
<template>
<ContentContainer>
<template #header>
<div class="shared-header">
<span class="title">{{ t('views.system.shared.shared_resources') }}</span>
<el-icon size="12">
<rightOutlined></rightOutlined>
</el-icon>
<span class="sub-title">{{ t('views.model.title') }}</span>
</div>
<el-breadcrumb separator-icon="ArrowRight">
<el-breadcrumb-item>{{ t('views.system.shared.shared_resources') }}</el-breadcrumb-item>
<el-breadcrumb-item>
<h5 class="ml-4 color-text-primary">{{ t('views.model.title') }}</h5>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<el-card style="--el-card-padding: 0">
<LayoutContainer class="model-manage">
<template #left>
<h4 class="p-16 mb-8 pb-0">{{ $t('views.model.provider') }}</h4>
<ProviderComponent
:data="provider_list"
@click="clickListHandle"
:loading="loading"
:shareTitle="$t('views.system.shared.shared_tool')"
isShared
:active="active_provider"
/>
</template>
<ContentContainer :header="active_provider?.name" v-loading="list_model_loading">
<template #search>
<div class="flex">
<div class="flex-between complex-search">
<el-select
class="complex-search__left"
v-model="search_type"
style="width: 120px"
@change="search_type_change"
>
<el-option :label="$t('common.creator')" value="create_user" />
<el-option
:label="$t('views.model.modelForm.model_type.label')"
value="model_type"
/>
<el-option :label="$t('views.model.modelForm.modeName.label')" value="name" />
</el-select>
<el-input
v-if="search_type === 'name'"
v-model="model_search_form.name"
@change="list_model"
:placeholder="$t('common.searchBar.placeholder')"
style="width: 220px"
clearable
/>
<el-select
v-else-if="search_type === 'create_user'"
v-model="model_search_form.create_user"
@change="list_model"
clearable
style="width: 220px"
>
<el-option
v-for="u in user_options"
:key="u.id"
:value="u.id"
:label="u.username"
/>
</el-select>
<el-select
v-else-if="search_type === 'model_type'"
v-model="model_search_form.model_type"
clearable
@change="list_model"
style="width: 220px"
>
<template v-for="item in modelTypeList" :key="item.value">
<el-option :label="item.text" :value="item.value" />
</template>
</el-select>
</div>
<el-button
v-if="!isShared"
class="ml-16"
type="primary"
@click="openCreateModel(active_provider)"
v-hasPermission="[
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
RoleConst.USER.getWorkspaceRole,
PermissionConst.MODEL_CREATE.getWorkspacePermission,
]"
>
{{ $t('views.model.addModel') }}
</el-button>
</div>
</template>
<div class="model-list-height">
<el-scrollbar>
<el-row v-if="model_split_list.length > 0" :gutter="15" class="w-full">
<template v-for="(row, index) in model_split_list" :key="index">
<el-col
:xs="24"
:sm="12"
:md="12"
:lg="12"
:xl="8"
class="mb-16"
v-for="(model, i) in row"
:key="i"
>
<ModelCard
@change="list_model"
:updateModelById="updateModelById"
:model="model"
:provider_list="provider_list"
:isShared="isShared"
>
</ModelCard>
</el-col>
</template>
</el-row>
<el-empty :description="$t('common.noData')" v-else />
</el-scrollbar>
</div>
</ContentContainer>
<CreateModelDialog
ref="createModelRef"
@submit="list_model"
@change="openCreateModel($event)"
v-if="!isShared"
></CreateModelDialog>
<SelectProviderDialog
ref="selectProviderRef"
@change="(provider, modelType) => openCreateModel(provider, modelType)"
v-if="!isShared"
></SelectProviderDialog>
</LayoutContainer>
<modelListContainer />
</el-card>
</ContentContainer>
</template>
<script lang="ts" setup>
import { onMounted, ref, computed } from 'vue'
import ProviderApi from '@/api/model/provider'
import ModelApi from '@/api/system-shared/model'
import type { Provider, Model } from '@/api/type/model'
import ModelCard from '@/views/model/component/ModelCard.vue'
import ProviderComponent from '@/views/model/component/Provider.vue'
import { splitArray } from '@/utils/common'
import { modelTypeList, allObj } from '@/views/model/component/data'
import CreateModelDialog from '@/views/model/component/CreateModelDialog.vue'
import SelectProviderDialog from '@/views/model/component/SelectProviderDialog.vue'
import { t } from '@/locales'
import { PermissionConst, RoleConst } from '@/utils/permission/data'
const commonList1 = ref()
const commonList2 = ref()
const loading = ref<boolean>(false)
import modelListContainer from '@/views/model/index.vue'
const active_provider = ref<Provider>()
const search_type = ref('name')
const model_search_form = ref<{
name: string
create_user: string
model_type: string
}>({
name: '',
create_user: '',
model_type: '',
})
const user_options = ref<any[]>([])
const list_model_loading = ref<boolean>(false)
const provider_list = ref<Array<Provider>>([])
const model_list = ref<Array<Model>>([])
const isShared = computed(() => {
return active_provider.value && active_provider.value.provider === 'share'
})
const updateModelById = (model_id: string, model: Model) => {
model_list.value
.filter((m) => m.id == model_id)
.forEach((m) => {
m.status = model.status
})
}
const model_split_list = computed(() => {
return splitArray(model_list.value, 2)
})
const createModelRef = ref<InstanceType<typeof CreateModelDialog>>()
const selectProviderRef = ref<InstanceType<typeof SelectProviderDialog>>()
const clickListHandle = (item: Provider) => {
active_provider.value = item
list_model()
if (active_provider.value.provider === '') {
commonList1.value.clearCurrent()
commonList2.value.clearCurrent()
}
}
const openCreateModel = (provider?: Provider, model_type?: string) => {
if (provider && provider.provider) {
createModelRef.value?.open(provider, model_type)
} else {
selectProviderRef.value?.open()
}
}
const list_model = () => {
const params = active_provider.value?.provider ? { provider: active_provider.value.provider } : {}
ModelApi.getModel({ ...model_search_form.value, ...params }, list_model_loading).then(
(ok: any) => {
model_list.value = ok.data
const v = model_list.value.map((m) => ({ id: m.user_id, username: m.username }))
if (user_options.value.length === 0) {
user_options.value = Array.from(new Map(v.map((item) => [item.id, item])).values())
}
},
)
}
const search_type_change = () => {
model_search_form.value = { name: '', create_user: '', model_type: '' }
}
onMounted(() => {
ProviderApi.getProvider(loading).then((ok) => {
active_provider.value = allObj
provider_list.value = [allObj, ...ok.data]
list_model()
})
})
onMounted(() => {})
</script>
<style lang="scss" scoped>
.model-manage {
.model-list-height {
height: calc(var(--app-main-height));
}
}
</style>
<style lang="scss" scoped></style>

View File

@ -5,7 +5,7 @@
<el-breadcrumb separator-icon="ArrowRight">
<el-breadcrumb-item>{{ t('views.system.shared.shared_resources') }}</el-breadcrumb-item>
<el-breadcrumb-item>
{{ t('views.tool.title') }}
<h5 class="ml-4 color-text-primary">{{ t('views.tool.title') }}</h5>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
@ -23,24 +23,4 @@ import { t } from '@/locales'
onMounted(() => {})
</script>
<style lang="scss" scoped>
.tool-shared {
padding-left: 8px;
.shared-header {
color: #646a73;
font-weight: 400;
font-size: 14px;
line-height: 22px;
display: flex;
align-items: center;
:deep(.el-icon i) {
height: 12px;
}
.sub-title {
color: #1f2329;
}
}
}
</style>
<style lang="scss" scoped></style>

View File

@ -109,11 +109,23 @@
</template>
<script setup lang="ts">
import { ref, reactive, watch } from 'vue'
import ToolApi from '@/api/tool/tool'
import { ref, reactive, watch, computed } from 'vue'
import type { FormInstance } from 'element-plus'
import { useRoute } from 'vue-router'
import DynamicsForm from '@/components/dynamics-form/index.vue'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
const route = useRoute()
const type = computed(() => {
if (route.path.includes('shared')) {
return 'systemShare'
} else if (route.path.includes('resource-management')) {
return 'systemManage'
} else {
return 'workspace'
}
})
const FormRef = ref()
const dynamicsFormRef = ref()
const loading = ref(false)
@ -148,17 +160,19 @@ watch(debugVisible, (bool) => {
const submit = async (formEl: FormInstance | undefined) => {
const validate = formEl ? formEl.validate() : Promise.resolve()
Promise.all([dynamicsFormRef.value?.validate(), validate]).then(() => {
ToolApi.postToolDebug(form.value, loading).then((res) => {
if (res.code === 500) {
showResult.value = true
isSuccess.value = false
result.value = res.message
} else {
showResult.value = true
isSuccess.value = true
result.value = res.data
}
})
loadSharedApi({ type: 'tool', systemType: type.value })
.postToolDebug(form.value, loading)
.then((res: any) => {
if (res.code === 500) {
showResult.value = true
isSuccess.value = false
result.value = res.message
} else {
showResult.value = true
isSuccess.value = true
result.value = res.data
}
})
})
}

View File

@ -24,7 +24,6 @@
@mouseenter="showEditIcon = true"
@mouseleave="showEditIcon = false"
>
<el-Avatar
v-if="isAppIcon(form.icon)"
:id="form.id"
@ -32,10 +31,10 @@
:size="32"
style="background: none"
>
<img :src="String(form.icon)" alt=""/>
<img :src="String(form.icon)" alt="" />
</el-Avatar>
<el-avatar v-else class="avatar-green" shape="square" :size="32">
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt=""/>
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
</el-avatar>
<el-Avatar
v-if="showEditIcon"
@ -46,12 +45,12 @@
@click="openEditAvatar"
>
<el-icon>
<EditPen/>
<EditPen />
</el-icon>
</el-Avatar>
</div>
<el-avatar v-else class="avatar-green" shape="square" :size="32">
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt=""/>
<img src="@/assets/node/icon_tool.svg" style="width: 58%" alt="" />
</el-avatar>
<el-input
v-model="form.name"
@ -81,7 +80,7 @@
</h4>
<el-button link type="danger" @click="openAddInitDialog()">
<el-icon class="mr-4">
<Plus/>
<Plus />
</el-icon>
{{ $t('common.add') }}
</el-button>
@ -94,44 +93,36 @@
</el-table-column>
<el-table-column :label="$t('dynamicsForm.paramForm.input_type.label')">
<template #default="{ row }">
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'">{{
$t('dynamicsForm.input_type_list.TextInput')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'TextInput'"
>{{ $t('dynamicsForm.input_type_list.TextInput') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'PasswordInput'">{{
$t('dynamicsForm.input_type_list.PasswordInput')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'PasswordInput'"
>{{ $t('dynamicsForm.input_type_list.PasswordInput') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'">{{
$t('dynamicsForm.input_type_list.Slider')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'Slider'"
>{{ $t('dynamicsForm.input_type_list.Slider') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'">{{
$t('dynamicsForm.input_type_list.SwitchInput')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SwitchInput'"
>{{ $t('dynamicsForm.input_type_list.SwitchInput') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'">{{
$t('dynamicsForm.input_type_list.SingleSelect')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'SingleSelect'"
>{{ $t('dynamicsForm.input_type_list.SingleSelect') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'MultiSelect'">{{
$t('dynamicsForm.input_type_list.MultiSelect')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'MultiSelect'"
>{{ $t('dynamicsForm.input_type_list.MultiSelect') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'RadioCard'">{{
$t('dynamicsForm.input_type_list.RadioCard')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'RadioCard'"
>{{ $t('dynamicsForm.input_type_list.RadioCard') }}
</el-tag>
<el-tag type="info" class="info-tag" v-if="row.input_type === 'DatePicker'">{{
$t('dynamicsForm.input_type_list.DatePicker')
}}
<el-tag type="info" class="info-tag" v-if="row.input_type === 'DatePicker'"
>{{ $t('dynamicsForm.input_type_list.DatePicker') }}
</el-tag>
</template>
</el-table-column>
<el-table-column :label="$t('common.required')">
<template #default="{ row }">
<div @click.stop>
<el-switch disabled size="small" v-model="row.required"/>
<el-switch disabled size="small" v-model="row.required" />
</div>
</template>
</el-table-column>
@ -140,14 +131,14 @@
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('common.modify')" placement="top">
<el-button type="primary" text @click.stop="openAddInitDialog(row, $index)">
<el-icon><EditPen/></el-icon>
<el-icon><EditPen /></el-icon>
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')" placement="top">
<el-button type="primary" text @click="deleteInitField($index)">
<el-icon>
<Delete/>
<Delete />
</el-icon>
</el-button>
</el-tooltip>
@ -163,14 +154,14 @@
</h4>
<el-button link type="primary" @click="openAddDialog()">
<el-icon class="mr-4">
<Plus/>
<Plus />
</el-icon>
{{ $t('common.add') }}
</el-button>
</div>
<el-table ref="inputFieldTableRef" :data="form.input_field_list" class="mb-16">
<el-table-column prop="name" :label="$t('views.tool.form.paramName.label')"/>
<el-table-column prop="name" :label="$t('views.tool.form.paramName.label')" />
<el-table-column :label="$t('views.tool.form.dataType.label')">
<template #default="{ row }">
<el-tag type="info" class="info-tag">{{ row.type }}</el-tag>
@ -179,7 +170,7 @@
<el-table-column :label="$t('common.required')">
<template #default="{ row }">
<div @click.stop>
<el-switch size="small" v-model="row.is_required"/>
<el-switch size="small" v-model="row.is_required" />
</div>
</template>
</el-table-column>
@ -197,14 +188,14 @@
<span class="mr-4">
<el-tooltip effect="dark" :content="$t('common.modify')" placement="top">
<el-button type="primary" text @click.stop="openAddDialog(row, $index)">
<el-icon><EditPen/></el-icon>
<el-icon><EditPen /></el-icon>
</el-button>
</el-tooltip>
</span>
<el-tooltip effect="dark" :content="$t('common.delete')" placement="top">
<el-button type="primary" text @click="deleteField($index)">
<el-icon>
<Delete/>
<Delete />
</el-icon>
</el-button>
</el-tooltip>
@ -240,44 +231,38 @@
<template #footer>
<div>
<el-button :loading="loading" @click="visible = false">{{ $t('common.cancel') }}</el-button>
<el-button :loading="loading" @click="openDebug"
v-if="permissionPrecise.debug()"
>{{ $t('common.debug') }}</el-button>
<el-button type="primary" @click="submit(FormRef)" :loading="loading"
>
<el-button :loading="loading" @click="openDebug" v-if="permissionPrecise.debug()">{{
$t('common.debug')
}}</el-button>
<el-button type="primary" @click="submit(FormRef)" :loading="loading">
{{ isEdit ? $t('common.save') : $t('common.create') }}
</el-button
>
</el-button>
</div>
</template>
<ToolDebugDrawer ref="ToolDebugDrawerRef"/>
<FieldFormDialog ref="FieldFormDialogRef" @refresh="refreshFieldList"/>
<UserFieldFormDialog ref="UserFieldFormDialogRef" @refresh="refreshInitFieldList"/>
<EditAvatarDialog ref="EditAvatarDialogRef" @refresh="refreshTool"/>
<ToolDebugDrawer ref="ToolDebugDrawerRef" />
<FieldFormDialog ref="FieldFormDialogRef" @refresh="refreshFieldList" />
<UserFieldFormDialog ref="UserFieldFormDialogRef" @refresh="refreshInitFieldList" />
<EditAvatarDialog ref="EditAvatarDialogRef" @refresh="refreshTool" />
</el-drawer>
</template>
<script setup lang="ts">
import {ref, reactive, watch, nextTick, computed} from 'vue'
import { ref, reactive, watch, nextTick, computed } from 'vue'
import FieldFormDialog from '@/views/tool/component/FieldFormDialog.vue'
import ToolDebugDrawer from './ToolDebugDrawer.vue'
import UserFieldFormDialog from '@/views/tool/component/UserFieldFormDialog.vue'
import EditAvatarDialog from '@/views/tool/component/EditAvatarDialog.vue'
import type {toolData} from '@/api/type/tool'
import ToolApi from '@/api/tool/tool'
import type {FormInstance} from 'element-plus'
import {MsgSuccess, MsgConfirm} from '@/utils/message'
import {cloneDeep} from 'lodash'
import {PermissionType, PermissionDesc} from '@/enums/model'
import {t} from '@/locales'
import {isAppIcon} from '@/utils/common'
import { PermissionConst, RoleConst } from '@/utils/permission/data'
import { hasPermission } from '@/utils/permission/index'
import type { toolData } from '@/api/type/tool'
import type { FormInstance } from 'element-plus'
import { MsgSuccess, MsgConfirm } from '@/utils/message'
import { cloneDeep } from 'lodash'
import { t } from '@/locales'
import { isAppIcon } from '@/utils/common'
import { useRoute } from 'vue-router'
import useStore from '@/stores'
import permissionMap from '@/permission'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
const route = useRoute()
const { folder, user } = useStore()
@ -367,8 +352,7 @@ function close() {
.then(() => {
visible.value = false
})
.catch(() => {
})
.catch(() => {})
}
}
@ -440,17 +424,25 @@ const submit = async (formEl: FormInstance | undefined) => {
await formEl.validate((valid: any) => {
if (valid) {
if (isEdit.value) {
ToolApi.putTool(form.value?.id as string, form.value, loading).then((res) => {
MsgSuccess(t('common.editSuccess'))
emit('refresh', res.data)
visible.value = false
})
loadSharedApi({ type: 'tool', systemType: type.value })
.putTool(form.value?.id as string, form.value, loading)
.then((res: any) => {
MsgSuccess(t('common.editSuccess'))
emit('refresh', res.data)
visible.value = false
})
} else {
ToolApi.postTool(form.value, loading).then((res) => {
MsgSuccess(t('common.createSuccess'))
emit('refresh')
visible.value = false
})
const obj = {
folder_id: folder.currentFolder?.id,
...form.value,
}
loadSharedApi({ type: 'tool', systemType: type.value })
.postTool(obj, loading)
.then((res: any) => {
MsgSuccess(t('common.createSuccess'))
emit('refresh')
visible.value = false
})
}
}
})

View File

@ -27,15 +27,28 @@
</template>
<script setup lang="ts">
import {ref, watch} from 'vue'
import ToolApi from '@/api/tool/tool'
import { ref, watch, computed } from 'vue'
import { useRoute } from 'vue-router'
import DynamicsForm from '@/components/dynamics-form/index.vue'
import {MsgSuccess} from '@/utils/message'
import {t} from '@/locales'
import {cloneDeep} from 'lodash'
import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
import { cloneDeep } from 'lodash'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
const emit = defineEmits(['refresh'])
const route = useRoute()
const type = computed(() => {
if (route.path.includes('shared')) {
return 'systemShare'
} else if (route.path.includes('resource-management')) {
return 'systemManage'
} else {
return 'workspace'
}
})
const dynamicsFormRef = ref()
const loading = ref(false)
const debugVisible = ref(false)
@ -55,11 +68,13 @@ watch(debugVisible, (bool) => {
const submit = async () => {
dynamicsFormRef.value.validate().then(() => {
ToolApi.putTool(form.value?.id as string, form.value, loading).then((res) => {
MsgSuccess(t('common.editSuccess'))
emit('refresh')
debugVisible.value = false
})
loadSharedApi({ type: 'tool', systemType: type.value })
.putTool(form.value?.id as string, form.value, loading)
.then((res: any) => {
MsgSuccess(t('common.editSuccess'))
emit('refresh')
debugVisible.value = false
})
})
}
@ -71,12 +86,12 @@ const open = (data: any, is_active: boolean) => {
const init_params = form.value.init_field_list
.map((item: any) => {
if (item.show_default_value === false) {
return {[item.field]: undefined}
return { [item.field]: undefined }
}
return {[item.field]: item.default_value}
return { [item.field]: item.default_value }
})
.reduce((x: any, y: any) => ({...x, ...y}), {})
form.value.init_params = {...init_params, ...form.value.init_params}
.reduce((x: any, y: any) => ({ ...x, ...y }), {})
form.value.init_params = { ...init_params, ...form.value.init_params }
debugVisible.value = true
}

View File

@ -115,7 +115,7 @@
@load="getList"
:loading="loading"
>
<el-row v-if="tool.toolList.length > 0" :gutter="15">
<el-row v-if="tool.toolList.length > 0" :gutter="15" class="w-full">
<template v-for="(item, index) in tool.toolList" :key="index">
<el-col
v-if="item.resource_type === 'folder'"
@ -304,7 +304,6 @@
<script lang="ts" setup>
import { onMounted, ref, reactive, computed, watch } from 'vue'
import { cloneDeep, get } from 'lodash'
import ToolApi from '@/api/tool/tool'
import { useRoute } from 'vue-router'
import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
@ -407,7 +406,8 @@ async function changeState(row: any) {
const obj = {
is_active: !row.is_active,
}
ToolApi.putTool(row.id, obj, changeStateloading)
loadSharedApi({ type: 'tool', systemType: type.value })
.putTool(row.id, obj, changeStateloading)
.then(() => {
const list = cloneDeep(tool.toolList)
const index = list.findIndex((v) => v.id === row.id)
@ -513,7 +513,7 @@ function deleteTool(row: any) {
function configInitParams(item: any) {
loadSharedApi({ type: 'tool', systemType: type.value })
.getToolById(item?.id, changeStateloading)
.then((res) => {
.then((res: any) => {
InitParamDrawerRef.value.open(res.data)
})
}
@ -532,7 +532,7 @@ function confirmAddInternalFunction(data?: any, isEdit?: boolean) {
if (isEdit) {
loadSharedApi({ type: 'tool', systemType: type.value })
.putTool(data?.id as string, { name: data.name }, loading)
.then((res) => {
.then((res: any) => {
MsgSuccess(t('common.saveSuccess'))
refresh()
})

View File

@ -24,12 +24,7 @@
<script lang="ts" setup>
import { onMounted, ref, reactive, computed } from 'vue'
import ToolListContainer from '@/views/tool/component/ToolListContainer.vue'
import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
import { FolderSource } from '@/enums/common'
import { ComplexPermission } from '@/utils/permission/type'
import ToolStoreDialog from './toolStore/ToolStoreDialog.vue'
import AddInternalFunctionDialog from './toolStore/AddInternalFunctionDialog.vue'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
import permissionMap from '@/permission'
import { useRoute } from 'vue-router'
import useStore from '@/stores'