ToolListContainer.vue 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. <template>
  2. <ContentContainer>
  3. <template #header>
  4. <slot name="header"></slot>
  5. </template>
  6. <template #search>
  7. <div class="flex">
  8. <div class="flex-between complex-search">
  9. <el-select
  10. class="complex-search__left"
  11. v-model="search_type"
  12. style="width: 90px"
  13. @change="search_type_change"
  14. >
  15. <el-option :label="$t('common.creator')" value="create_user"/>
  16. <el-option :label="$t('common.name')" value="name"/>
  17. </el-select>
  18. <el-input
  19. v-if="search_type === 'name'"
  20. v-model="search_form.name"
  21. @change="searchHandle"
  22. :placeholder="$t('common.searchBar.placeholder')"
  23. style="width: 190px"
  24. clearable
  25. />
  26. <el-select
  27. v-else-if="search_type === 'create_user'"
  28. v-model="search_form.create_user"
  29. @change="searchHandle"
  30. filterable
  31. clearable
  32. style="width: 190px"
  33. >
  34. <el-option v-for="u in user_options" :key="u.id" :value="u.id" :label="u.nick_name"/>
  35. </el-select>
  36. </div>
  37. <span
  38. class="ml-8"
  39. v-if="!isShared && (permissionPrecise.batchMove() || permissionPrecise.batchDelete())"
  40. >
  41. <el-button @click="batchSelectedHandle(true)" v-if="isBatch === false">
  42. <AppIcon iconName="app-batch-delete" class="mr-4"/>
  43. {{ $t('views.paragraph.setting.batchSelected') }}
  44. </el-button>
  45. <el-button @click="batchSelectedHandle(false)" v-if="isBatch === true">
  46. <AppIcon iconName="app-batch-delete" class="mr-4"/>
  47. {{ $t('views.paragraph.setting.cancelSelected') }}
  48. </el-button>
  49. </span>
  50. <div v-if="isBatch === false">
  51. <span class="ml-8" v-show="false" v-if="!isShared && permissionPrecise.create()">
  52. <el-button @click="openToolStoreDialog()">
  53. <AppIcon iconName="app-tool-store" class="mr-4"/>
  54. {{ $t('views.tool.toolStore.title') }}
  55. </el-button>
  56. </span>
  57. <el-dropdown trigger="click">
  58. <el-button type="primary" class="ml-8" v-if="!isShared && permissionPrecise.create()">
  59. {{ $t('common.create') }}
  60. <el-icon class="el-icon--right">
  61. <arrow-down/>
  62. </el-icon>
  63. </el-button>
  64. <template #dropdown>
  65. <el-dropdown-menu class="create-dropdown">
  66. <el-dropdown-item @click="openCreateDialog()">
  67. <div class="flex align-center">
  68. <el-avatar class="avatar-green" shape="square" :size="32">
  69. <img src="@/assets/tool/icon_tool.svg" style="width: 58%" alt=""/>
  70. </el-avatar>
  71. <div class="pre-wrap ml-8">
  72. <div class="lighter">{{ $t('views.tool.title') }}</div>
  73. </div>
  74. </div>
  75. </el-dropdown-item>
  76. <el-dropdown-item @click="openCreateWorkflowDialog()">
  77. <div class="flex align-center">
  78. <el-avatar class="avatar-green mt-4" shape="square" :size="32">
  79. <img src="@/assets/workflow/logo_workflow.svg" style="width: 60%" alt=""/>
  80. </el-avatar>
  81. <div class="pre-wrap ml-8">
  82. <div class="lighter">{{ $t('workflow.workflow') }}</div>
  83. </div>
  84. </div>
  85. </el-dropdown-item>
  86. <el-dropdown-item @click="openCreateSkillDialog()">
  87. <div class="flex align-center">
  88. <el-avatar shape="square" :size="32">
  89. <img src="@/assets/tool/icon_skill.svg" style="width: 58%" alt=""/>
  90. </el-avatar>
  91. <div class="pre-wrap ml-8">
  92. <div class="lighter">Skills</div>
  93. </div>
  94. </div>
  95. </el-dropdown-item>
  96. <el-dropdown-item @click="openCreateMcpDialog()">
  97. <div class="flex align-center">
  98. <el-avatar shape="square" :size="32">
  99. <img src="@/assets/tool/icon_mcp.svg" style="width: 75%" alt=""/>
  100. </el-avatar>
  101. <div class="pre-wrap ml-8">
  102. <div class="lighter">MCP</div>
  103. </div>
  104. </div>
  105. </el-dropdown-item>
  106. <el-dropdown-item @click="openCreateDataSourceDialog()">
  107. <div class="flex align-center">
  108. <el-avatar class="avatar-purple" shape="square" :size="32">
  109. <img src="@/assets/tool/icon_datasource.svg" style="width: 58%" alt=""/>
  110. </el-avatar>
  111. <div class="pre-wrap ml-8">
  112. <div class="lighter">{{ $t('views.tool.dataSource.title') }}</div>
  113. </div>
  114. </div>
  115. </el-dropdown-item>
  116. <el-upload
  117. ref="elUploadRef"
  118. :file-list="[]"
  119. action="#"
  120. multiple
  121. :auto-upload="false"
  122. :show-file-list="false"
  123. :limit="1"
  124. :on-change="(file: any, fileList: any) => importTool(file)"
  125. class="import-button"
  126. >
  127. <el-dropdown-item v-if="permissionPrecise.import()">
  128. <div class="flex align-center w-full">
  129. <el-avatar shape="square" :size="32" style="background: none">
  130. <img src="@/assets/icon_import.svg" alt=""/>
  131. </el-avatar>
  132. <div class="pre-wrap ml-8">
  133. <div class="lighter">{{ $t('common.importCreate') }}</div>
  134. </div>
  135. </div>
  136. </el-dropdown-item>
  137. </el-upload>
  138. <el-dropdown-item @click="openCreateFolder" divided v-if="apiType === 'workspace'">
  139. <div class="flex align-center">
  140. <AppIcon iconName="app-folder" style="font-size: 32px"></AppIcon>
  141. <div class="pre-wrap ml-4">
  142. <div class="lighter">
  143. {{ $t('components.folder.addFolder') }}
  144. </div>
  145. </div>
  146. </div>
  147. </el-dropdown-item>
  148. </el-dropdown-menu>
  149. </template>
  150. </el-dropdown>
  151. </div>
  152. </div>
  153. </template>
  154. <div
  155. v-loading.fullscreen.lock="paginationConfig.current_page === 1 && loading"
  156. style="max-height: calc(100vh - 120px)"
  157. >
  158. <InfiniteScroll
  159. :size="tool.toolList.length"
  160. :total="paginationConfig.total"
  161. :page_size="paginationConfig.page_size"
  162. v-model:current_page="paginationConfig.current_page"
  163. @load="getList"
  164. :loading="loading"
  165. >
  166. <el-checkbox-group v-model="multipleSelection" @change="handleCheckedChatChange">
  167. <el-row v-if="tool.toolList.length > 0" :gutter="15" class="w-full">
  168. <template v-for="(item, index) in tool.toolList" :key="index">
  169. <el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="6" class="mb-16">
  170. <CardBox
  171. :title="item.name"
  172. :description="item.desc"
  173. class="cursor"
  174. :class="[multipleSelection.includes(item.id) ? 'border-active' : '']"
  175. @click.stop="openEditDialog(item)"
  176. :disabled="!permissionPrecise.edit(item.id) || isBatch"
  177. >
  178. <template #icon>
  179. <el-avatar v-if="item?.icon" shape="square" :size="32" style="background: none">
  180. <img :src="resetUrl(item?.icon)" alt=""/>
  181. </el-avatar>
  182. <ToolIcon v-else :size="32" :type="item?.tool_type"/>
  183. </template>
  184. <template #title>
  185. <div class="flex align-center">
  186. <span class="ellipsis-1" :title="item.name">
  187. {{ item.name }}
  188. </span>
  189. <el-tag
  190. v-if="item.version"
  191. class="ml-4"
  192. size="small"
  193. type="info"
  194. effect="plain"
  195. >
  196. {{ item.version }}
  197. </el-tag>
  198. </div>
  199. </template>
  200. <template #subTitle>
  201. <el-text class="color-secondary lighter flex align-center" size="small">
  202. <span
  203. :title="i18n_name(item.nick_name)"
  204. class="ellipsis"
  205. style="max-width: 90px"
  206. >
  207. {{ i18n_name(item.nick_name) }}
  208. </span>
  209. <span class="ml-4 mr-4"> {{ $t('common.createdIn') }}</span>
  210. <span> {{ dateFormat(item.create_time) }}</span>
  211. </el-text>
  212. </template>
  213. <template #tag="{ hoverShow }">
  214. <el-checkbox :value="item.id" v-if="isBatch" @change="checkboxChange(item)"/>
  215. <div v-else>
  216. <el-tag v-if="isShared" size="small" type="info" class="info-tag">
  217. {{ t('views.shared.title') }}
  218. </el-tag>
  219. <el-tooltip
  220. effect="dark"
  221. :content="$t('views.tool.updatedVersion')"
  222. v-if="
  223. showUpdateStoreTool(item) && !isShared && permissionPrecise.edit(item.id)
  224. "
  225. >
  226. <el-button text @click.stop="updateStoreTool(item)">
  227. <el-icon v-if="hoverShow">
  228. <Refresh/>
  229. </el-icon>
  230. <div v-else class="dot-success"></div>
  231. </el-button>
  232. </el-tooltip>
  233. </div>
  234. </template>
  235. <template #footer>
  236. <div v-if="item.is_active" class="flex align-center">
  237. <el-icon class="color-success mr-8" style="font-size: 16px">
  238. <SuccessFilled/>
  239. </el-icon>
  240. <span class="color-secondary">
  241. {{ $t('common.status.enabled') }}
  242. </span>
  243. </div>
  244. <div v-else class="flex align-center">
  245. <AppIcon iconName="app-disabled" class="color-secondary mr-8"></AppIcon>
  246. <span class="color-secondary">
  247. {{ $t('common.status.disabled') }}
  248. </span>
  249. </div>
  250. </template>
  251. <template #mouseEnter>
  252. <div @click.stop v-if="!isShared && MoreFieldPermission(item.id)">
  253. <el-switch
  254. v-model="item.is_active"
  255. :before-change="() => changeState(item)"
  256. size="small"
  257. class="mr-4"
  258. v-if="permissionPrecise.switch(item.id)"
  259. />
  260. <el-divider direction="vertical"/>
  261. <el-dropdown trigger="click">
  262. <el-button text @click.stop>
  263. <AppIcon iconName="app-more" class="color-secondary"></AppIcon>
  264. </el-button>
  265. <template #dropdown>
  266. <el-dropdown-menu>
  267. <el-dropdown-item
  268. v-if="item.tool_type === 'MCP'"
  269. @click.stop="showMcpConfig(item)"
  270. >
  271. <AppIcon iconName="app-operate-log" class="color-secondary"></AppIcon>
  272. {{ $t('views.tool.mcp.mcpConfig') }}
  273. </el-dropdown-item>
  274. <el-dropdown-item
  275. v-if="item.template_id && permissionPrecise.edit(item.id)"
  276. @click.stop="addInternalTool(item, true)"
  277. >
  278. <AppIcon iconName="app-edit" class="color-secondary"></AppIcon>
  279. {{ $t('common.edit') }}
  280. </el-dropdown-item>
  281. <el-dropdown-item
  282. v-else-if="
  283. item.tool_type === 'WORKFLOW' && permissionPrecise.edit(item.id)
  284. "
  285. @click.stop="openCreateWorkflowDialog(item)"
  286. >
  287. <AppIcon iconName="app-edit" class="color-secondary"></AppIcon>
  288. {{ $t('common.edit') }}
  289. </el-dropdown-item>
  290. <el-dropdown-item
  291. v-else-if="permissionPrecise.edit(item.id)"
  292. @click.stop="openEditDialog(item)"
  293. >
  294. <AppIcon iconName="app-edit" class="color-secondary"></AppIcon>
  295. {{ $t('common.edit') }}
  296. </el-dropdown-item>
  297. <el-dropdown-item
  298. v-if="item.tool_type === 'WORKFLOW'"
  299. @click.stop="toWorkflow(item)"
  300. >
  301. <AppIcon iconName="app-workflow" class="color-secondary"></AppIcon>
  302. {{ $t('workflow.workflow') }}
  303. </el-dropdown-item>
  304. <el-dropdown-item
  305. v-if="!item.template_id && permissionPrecise.copy(item.id)"
  306. @click.stop="copyTool(item)"
  307. >
  308. <AppIcon iconName="app-copy" class="color-secondary"></AppIcon>
  309. {{ $t('common.copy') }}
  310. </el-dropdown-item>
  311. <el-dropdown-item
  312. v-if="
  313. item.init_field_list?.length > 0 && permissionPrecise.edit(item.id)
  314. "
  315. @click.stop="configInitParams(item)"
  316. >
  317. <AppIcon iconName="app-operation" class="color-secondary"></AppIcon>
  318. {{ $t('common.param.initParam') }}
  319. </el-dropdown-item>
  320. <el-dropdown-item
  321. @click.stop="openAuthorization(item)"
  322. v-if="apiType === 'workspace' && permissionPrecise.auth(item.id)"
  323. >
  324. <AppIcon
  325. iconName="app-resource-authorization"
  326. class="color-secondary"
  327. ></AppIcon>
  328. {{ $t('views.system.resourceAuthorization.title') }}
  329. </el-dropdown-item>
  330. <el-dropdown-item
  331. @click.stop="openTriggerDrawer(item)"
  332. v-if="
  333. ['workspace', 'systemManage'].includes(apiType) &&
  334. (item.tool_type === 'CUSTOM' || item.tool_type === 'WORKFLOW') &&
  335. permissionPrecise.trigger_read(item.id)
  336. "
  337. >
  338. <AppIcon iconName="app-trigger" class="color-secondary"></AppIcon>
  339. {{ $t('views.trigger.title') }}
  340. </el-dropdown-item>
  341. <el-dropdown-item
  342. text
  343. @click.stop="openResourceMappingDrawer(item)"
  344. v-if="permissionPrecise.relate_map(item.id)"
  345. >
  346. <AppIcon
  347. iconName="app-resource-mapping"
  348. class="color-secondary"
  349. ></AppIcon>
  350. {{ $t('views.system.resourceMapping.title') }}
  351. </el-dropdown-item>
  352. <el-dropdown-item
  353. text
  354. @click.stop="openToolRecordDrawer(item)"
  355. v-if="
  356. (item.tool_type === 'CUSTOM' || item.tool_type === 'WORKFLOW') &&
  357. permissionPrecise.record(item.id)
  358. "
  359. >
  360. <AppIcon
  361. iconName="app-schedule-report"
  362. class="color-secondary"
  363. ></AppIcon>
  364. {{ $t('common.ExecutionRecord.subTitle') }}
  365. </el-dropdown-item>
  366. <el-dropdown-item
  367. @click.stop="openMoveToDialog(item)"
  368. v-if="permissionPrecise.copy(item.id) && apiType === 'workspace'"
  369. >
  370. <AppIcon iconName="app-migrate" class="color-secondary"></AppIcon>
  371. {{ $t('common.moveTo') }}
  372. </el-dropdown-item>
  373. <el-dropdown-item
  374. v-if="isSystemShare"
  375. @click.stop="openAuthorizedWorkspaceDialog(item)"
  376. >
  377. <AppIcon iconName="app-lock" class="color-secondary"></AppIcon>
  378. {{ $t('views.shared.authorized_workspace') }}
  379. </el-dropdown-item>
  380. <el-dropdown-item
  381. v-if="!item.template_id && permissionPrecise.export(item.id)"
  382. @click.stop="exportTool(item)"
  383. >
  384. <AppIcon iconName="app-export" class="color-secondary"></AppIcon>
  385. {{ $t('common.export') }}
  386. </el-dropdown-item>
  387. <el-dropdown-item
  388. v-if="permissionPrecise.delete(item.id)"
  389. divided
  390. @click.stop="deleteTool(item)"
  391. >
  392. <AppIcon iconName="app-delete" class="color-secondary"></AppIcon>
  393. {{ $t('common.delete') }}
  394. </el-dropdown-item>
  395. </el-dropdown-menu>
  396. </template>
  397. </el-dropdown>
  398. </div>
  399. </template>
  400. </CardBox>
  401. </el-col>
  402. </template>
  403. </el-row>
  404. <el-empty :description="$t('common.noData')" v-else/>
  405. </el-checkbox-group>
  406. </InfiniteScroll>
  407. </div>
  408. <!-- 批量操作拦 -->
  409. <div class="mul-operation border-t w-full flex align-center" v-if="isBatch">
  410. <el-checkbox
  411. v-model="checkAll"
  412. :indeterminate="isIndeterminate"
  413. @change="handleCheckAllChange"
  414. >
  415. {{ $t('common.allCheck') }}
  416. </el-checkbox>
  417. <el-button
  418. class="ml-16"
  419. :disabled="multipleSelection.length === 0"
  420. @click="openMoveToDialog()"
  421. v-if="permissionPrecise.batchMove()"
  422. >
  423. {{ $t('common.moveTo') }}
  424. </el-button>
  425. <el-button
  426. :disabled="multipleSelection.length === 0"
  427. @click="deleteMulTool"
  428. v-if="permissionPrecise.batchDelete()"
  429. >
  430. {{ $t('common.delete') }}
  431. </el-button>
  432. <span class="color-secondary ml-24 mr-16">
  433. {{ $t('common.selected') }} {{ multipleSelection.length }}/{{ paginationConfig.total }}
  434. {{ $t('views.document.items') }}
  435. </span>
  436. <el-button link type="primary" @click="batchSelectedHandle(false)">
  437. {{ $t('views.paragraph.setting.cancelSelected') }}
  438. </el-button>
  439. </div>
  440. <InitParamDrawer ref="InitParamDrawerRef" @refresh="refresh"/>
  441. <ToolFormDrawer ref="ToolFormDrawerRef" @refresh="refresh" :title="ToolDrawertitle"/>
  442. <McpToolFormDrawer ref="McpToolFormDrawerRef" @refresh="refresh" :title="McpToolDrawertitle"/>
  443. <SkillToolFormDrawer
  444. ref="SkillToolFormDrawerRef"
  445. @refresh="refresh"
  446. :title="SkillToolDrawertitle"
  447. />
  448. <DataSourceToolFormDrawer
  449. ref="DataSourceToolFormDrawerRef"
  450. @refresh="refresh"
  451. :title="DataSourceToolDrawertitle"
  452. />
  453. <CreateFolderDialog ref="CreateFolderDialogRef" v-if="!isShared" @refresh="refreshFolder"/>
  454. <ToolStoreDialog ref="toolStoreDialogRef" :api-type="apiType" @refresh="refresh"/>
  455. <AddInternalToolDialog ref="AddInternalToolDialogRef" @refresh="confirmAddInternalTool"/>
  456. <McpToolConfigDialog ref="McpToolConfigDialogRef" @refresh="refresh"/>
  457. <AuthorizedWorkspace
  458. ref="AuthorizedWorkspaceDialogRef"
  459. v-if="isSystemShare"
  460. ></AuthorizedWorkspace>
  461. <MoveToDialog
  462. ref="MoveToDialogRef"
  463. :source="SourceTypeEnum.TOOL"
  464. @refresh="refreshToolList"
  465. v-if="apiType === 'workspace'"
  466. />
  467. <ResourceAuthorizationDrawer
  468. :type="SourceTypeEnum.TOOL"
  469. ref="ResourceAuthorizationDrawerRef"
  470. v-if="apiType === 'workspace'"
  471. />
  472. <ToolStoreDescDrawer ref="toolStoreDescDrawerRef"/>
  473. <ResourceMappingDrawer ref="resourceMappingDrawerRef"></ResourceMappingDrawer>
  474. <ResourceTriggerDrawer
  475. ref="resourceTriggerDrawerRef"
  476. :source="SourceTypeEnum.TOOL"
  477. ></ResourceTriggerDrawer>
  478. <ExecutionRecordDrawer ref="toolRecordDrawerRef"/>
  479. <WorkflowFormDialog
  480. ref="workflowFormDialogRef"
  481. @refresh="refresh"
  482. :title="workflowFormDialogTitle"
  483. ></WorkflowFormDialog>
  484. </ContentContainer>
  485. </template>
  486. <script lang="ts" setup>
  487. import {onMounted, ref, reactive, computed, watch} from 'vue'
  488. import {cloneDeep} from 'lodash'
  489. import {useRoute, onBeforeRouteLeave, useRouter} from 'vue-router'
  490. import type {CheckboxValueType} from 'element-plus'
  491. import InitParamDrawer from '@/views/tool/component/InitParamDrawer.vue'
  492. import ToolFormDrawer from '@/views/tool/ToolFormDrawer.vue'
  493. import McpToolFormDrawer from '@/views/tool/McpToolFormDrawer.vue'
  494. import SkillToolFormDrawer from '@/views/tool/SkillToolFormDrawer.vue'
  495. import DataSourceToolFormDrawer from '@/views/tool/DataSourceToolFormDrawer.vue'
  496. import CreateFolderDialog from '@/components/folder-tree/CreateFolderDialog.vue'
  497. import AuthorizedWorkspace from '@/views/system-shared/AuthorizedWorkspaceDialog.vue'
  498. import ToolStoreDialog from '@/views/tool/tool-store/ToolStoreDialog.vue'
  499. import AddInternalToolDialog from '@/views/tool/tool-store/AddInternalToolDialog.vue'
  500. import MoveToDialog from '@/components/folder-tree/MoveToDialog.vue'
  501. import ResourceAuthorizationDrawer from '@/components/resource-authorization-drawer/index.vue'
  502. import McpToolConfigDialog from '@/views/tool/component/McpToolConfigDialog.vue'
  503. import ResourceTriggerDrawer from '@/views/trigger/ResourceTriggerDrawer.vue'
  504. import ToolStoreDescDrawer from '@/views/tool/component/ToolStoreDescDrawer.vue'
  505. import ResourceMappingDrawer from '@/components/resource_mapping/index.vue'
  506. import WorkflowFormDialog from '../WorkflowFormDialog.vue'
  507. import ExecutionRecordDrawer from '@/views/tool-workflow/execution-record/ExecutionRecordDrawer.vue'
  508. import ToolStoreApi from '@/api/tool/store.ts'
  509. import {resetUrl, i18n_name} from '@/utils/common'
  510. import {MsgSuccess, MsgConfirm, MsgError} from '@/utils/message'
  511. import {SourceTypeEnum} from '@/enums/common'
  512. import {dateFormat} from '@/utils/time'
  513. import {loadSharedApi} from '@/utils/dynamics-api/shared-api'
  514. import permissionMap from '@/permission'
  515. import useStore from '@/stores'
  516. import {t} from '@/locales'
  517. import bus from '@/bus'
  518. const router = useRouter()
  519. const route = useRoute()
  520. const {folder, user, tool} = useStore()
  521. onBeforeRouteLeave((to, from) => {
  522. tool.setToolList([])
  523. })
  524. const emit = defineEmits(['refreshFolder'])
  525. const apiType = computed(() => {
  526. if (route.path.includes('shared')) {
  527. return 'systemShare'
  528. } else if (route.path.includes('resource-management')) {
  529. return 'systemManage'
  530. } else {
  531. return 'workspace'
  532. }
  533. })
  534. const isShared = computed(() => {
  535. return folder.currentFolder.id === 'share'
  536. })
  537. const isSystemShare = computed(() => {
  538. return apiType.value === 'systemShare'
  539. })
  540. const permissionPrecise = computed(() => {
  541. return permissionMap['tool'][apiType.value]
  542. })
  543. const MoreFieldPermission = (id: any) => {
  544. return (
  545. permissionPrecise.value.edit(id) ||
  546. permissionPrecise.value.export(id) ||
  547. permissionPrecise.value.delete(id) ||
  548. permissionPrecise.value.auth(id) ||
  549. permissionPrecise.value.relate_map(id) ||
  550. permissionPrecise.value.trigger_read(id) ||
  551. permissionPrecise.value.record(id) ||
  552. isSystemShare.value
  553. )
  554. }
  555. const resourceTriggerDrawerRef = ref<InstanceType<typeof ResourceTriggerDrawer>>()
  556. const openTriggerDrawer = (data: any) => {
  557. resourceTriggerDrawerRef.value?.open(data)
  558. }
  559. const resourceMappingDrawerRef = ref<InstanceType<typeof ResourceMappingDrawer>>()
  560. const openResourceMappingDrawer = (tool: any) => {
  561. resourceMappingDrawerRef.value?.open('TOOL', tool)
  562. }
  563. const ResourceAuthorizationDrawerRef = ref()
  564. function openAuthorization(item: any) {
  565. ResourceAuthorizationDrawerRef.value.open(item.id)
  566. }
  567. const toolRecordDrawerRef = ref<InstanceType<typeof ExecutionRecordDrawer>>()
  568. const openToolRecordDrawer = (data: any) => {
  569. toolRecordDrawerRef.value?.open(data)
  570. }
  571. const InitParamDrawerRef = ref()
  572. const search_type = ref('name')
  573. const search_form = ref<any>({
  574. name: '',
  575. create_user: '',
  576. })
  577. const user_options = ref<any[]>([])
  578. const loading = ref(false)
  579. const changeStateloading = ref(false)
  580. const paginationConfig = reactive({
  581. current_page: 1,
  582. page_size: 30,
  583. total: 0,
  584. })
  585. const search_type_change = () => {
  586. search_form.value = {name: '', create_user: ''}
  587. }
  588. const ToolFormDrawerRef = ref()
  589. const McpToolFormDrawerRef = ref()
  590. const SkillToolFormDrawerRef = ref()
  591. const DataSourceToolFormDrawerRef = ref()
  592. const ToolDrawertitle = ref('')
  593. const McpToolDrawertitle = ref('')
  594. const SkillToolDrawertitle = ref('')
  595. const DataSourceToolDrawertitle = ref('')
  596. // 批量操作
  597. const isBatch = ref(false)
  598. const multipleSelection = ref<any[]>([])
  599. const checkAll = ref(false)
  600. const isIndeterminate = computed(() => {
  601. return multipleSelection.value.length > 0 && multipleSelection.value.length < tool.toolList.length
  602. })
  603. function batchSelectedHandle(bool: boolean) {
  604. isBatch.value = bool
  605. multipleSelection.value = []
  606. checkAll.value = false
  607. }
  608. const handleCheckAllChange = (val: CheckboxValueType) => {
  609. let bool
  610. if (isIndeterminate.value) {
  611. bool = true
  612. } else {
  613. bool = val as boolean
  614. }
  615. multipleSelection.value = bool ? tool.toolList.map((v) => v.id) : []
  616. checkAll.value = bool as boolean
  617. }
  618. const handleCheckedChatChange = (value: CheckboxValueType[]) => {
  619. const checkedCount = value.length
  620. checkAll.value = checkedCount === tool.toolList.length
  621. }
  622. const checkboxChange = (data?: any) => {
  623. const index = multipleSelection.value.indexOf(data?.id)
  624. if (index === -1) {
  625. multipleSelection.value.push(data?.id)
  626. } else {
  627. multipleSelection.value.splice(index, 1)
  628. }
  629. checkAll.value = multipleSelection.value.length === tool.toolList.length
  630. }
  631. function deleteMulTool() {
  632. MsgConfirm(
  633. `${t('views.document.delete.confirmTitle1')} ${multipleSelection.value.length} ${t('views.tool.delete.confirmTitle2')}`,
  634. t('views.paragraph.delete.confirmMessage'),
  635. {
  636. confirmButtonText: t('common.confirm'),
  637. confirmButtonClass: 'danger',
  638. },
  639. )
  640. .then(() => {
  641. loadSharedApi({type: 'tool', systemType: apiType.value})
  642. .delMulTool(multipleSelection.value, loading)
  643. .then(() => {
  644. batchSelectedHandle(false)
  645. paginationConfig.current_page = 1
  646. tool.setToolList([])
  647. getList()
  648. MsgSuccess(t('views.document.delete.successMessage'))
  649. })
  650. })
  651. .catch(() => {
  652. })
  653. }
  654. function openEditDialog(data?: any) {
  655. if (isBatch.value) {
  656. const index = multipleSelection.value.indexOf(data?.id)
  657. if (index === -1) {
  658. multipleSelection.value.push(data?.id)
  659. } else {
  660. multipleSelection.value.splice(index, 1)
  661. }
  662. checkAll.value = multipleSelection.value.length === tool.toolList.length
  663. return
  664. }
  665. // 有template_id的不允许编辑,是模板转换来的
  666. if (data?.template_id) {
  667. return
  668. }
  669. // 共享过来的工具不让编辑
  670. if (isShared.value) {
  671. return
  672. }
  673. if (data) {
  674. bus.emit('select_node', data.folder_id)
  675. }
  676. // 有版本号的展示readme,是商店更新过来的
  677. if (data?.version) {
  678. let readMe = ''
  679. storeTools.value
  680. .filter((item) => item.id === data.template_id)
  681. .forEach((item) => {
  682. readMe = item.readMe
  683. })
  684. toolStoreDescDrawerRef.value?.open(readMe, data)
  685. return
  686. }
  687. // mcp工具
  688. if (data?.tool_type === 'MCP') {
  689. openCreateMcpDialog(data)
  690. return
  691. }
  692. // 数据源工具
  693. if (data?.tool_type === 'DATA_SOURCE') {
  694. openCreateDataSourceDialog(data)
  695. return
  696. }
  697. // 技能
  698. if (data?.tool_type === 'SKILL') {
  699. openCreateSkillDialog(data)
  700. return
  701. }
  702. // 工作流
  703. if (data?.tool_type === 'WORKFLOW') {
  704. toWorkflow(data)
  705. return
  706. }
  707. ToolDrawertitle.value = t('views.tool.editTool')
  708. if (data) {
  709. loadSharedApi({type: 'tool', systemType: apiType.value})
  710. .getToolById(data?.id, loading)
  711. .then((res: any) => {
  712. ToolFormDrawerRef.value.open(res.data)
  713. })
  714. }
  715. }
  716. const MoveToDialogRef = ref()
  717. function openMoveToDialog(data?: any) {
  718. let obj
  719. if (isBatch.value) {
  720. obj = {
  721. id_list: multipleSelection.value,
  722. }
  723. } else {
  724. obj = {
  725. id: data.id,
  726. folder_id: data.folder,
  727. }
  728. }
  729. MoveToDialogRef.value?.open(obj)
  730. }
  731. function refreshToolList(row: any) {
  732. if (row) {
  733. // 不是根目录才会移除
  734. if (folder.currentFolder?.parent_id) {
  735. const list = cloneDeep(tool.toolList)
  736. const index = list.findIndex((v) => v.id === row.id)
  737. list.splice(index, 1)
  738. tool.setToolList(list)
  739. }
  740. } else {
  741. batchSelectedHandle(false)
  742. paginationConfig.current_page = 1
  743. tool.setToolList([])
  744. getList()
  745. }
  746. }
  747. const AuthorizedWorkspaceDialogRef = ref()
  748. function openAuthorizedWorkspaceDialog(row: any) {
  749. if (AuthorizedWorkspaceDialogRef.value) {
  750. AuthorizedWorkspaceDialogRef.value.open(row, 'Tool')
  751. }
  752. }
  753. const toolStoreDescDrawerRef = ref<InstanceType<typeof ToolStoreDescDrawer>>()
  754. function openCreateDialog() {
  755. ToolDrawertitle.value = t('views.tool.createTool')
  756. ToolFormDrawerRef.value.open()
  757. }
  758. function openCreateMcpDialog(data?: any) {
  759. // 有template_id的不允许编辑,是模板转换来的
  760. if (data?.template_id) {
  761. return
  762. }
  763. // 共享过来的工具不让编辑
  764. if (isShared.value) {
  765. return
  766. }
  767. McpToolDrawertitle.value = data
  768. ? t('views.tool.mcp.editMcpTool')
  769. : t('views.tool.mcp.createMcpTool')
  770. if (data) {
  771. loadSharedApi({type: 'tool', systemType: apiType.value})
  772. .getToolById(data?.id, loading)
  773. .then((res: any) => {
  774. McpToolFormDrawerRef.value.open(res.data)
  775. })
  776. } else {
  777. McpToolFormDrawerRef.value.open(data)
  778. }
  779. }
  780. function openCreateSkillDialog(data?: any) {
  781. // 有版本号的展示readme,是商店更新过来的
  782. if (data?.version) {
  783. let readMe = ''
  784. storeTools.value
  785. .filter((item) => item.id === data.template_id)
  786. .forEach((item) => {
  787. readMe = item.readMe
  788. })
  789. toolStoreDescDrawerRef.value?.open(readMe, data)
  790. return
  791. }
  792. // 有template_id的不允许编辑,是模板转换来的
  793. if (data?.template_id) {
  794. return
  795. }
  796. // 共享过来的工具不让编辑
  797. if (isShared.value) {
  798. return
  799. }
  800. SkillToolDrawertitle.value = data
  801. ? t('views.tool.skill.editSkillTool')
  802. : t('views.tool.skill.createSkillTool')
  803. if (data) {
  804. loadSharedApi({type: 'tool', systemType: apiType.value})
  805. .getToolById(data?.id, loading)
  806. .then((res: any) => {
  807. SkillToolFormDrawerRef.value.open(res.data)
  808. })
  809. } else {
  810. SkillToolFormDrawerRef.value.open(data)
  811. }
  812. }
  813. function toWorkflow(data: any) {
  814. const folderId = data.scope === 'SHARED' ? 'shared' : data.folder_id
  815. router.push({name: 'ToolWorkflow', params: {id: data.id, folderId: folderId}})
  816. }
  817. const workflowFormDialogRef = ref<InstanceType<typeof WorkflowFormDialog>>()
  818. const workflowFormDialogTitle = ref('')
  819. const openCreateWorkflowDialog = (data?: any) => {
  820. // 有template_id的不允许编辑,是模板转换来的
  821. if (data?.template_id) {
  822. return
  823. }
  824. // 共享过来的工具不让编辑
  825. if (isShared.value) {
  826. return
  827. }
  828. workflowFormDialogTitle.value = data
  829. ? t('common.edit')
  830. : t('views.tool.toolWorkflow.creatToolWorkflow')
  831. if (data) {
  832. loadSharedApi({type: 'tool', systemType: apiType.value})
  833. .getToolById(data?.id, loading)
  834. .then((res: any) => {
  835. workflowFormDialogRef.value?.open(res.data)
  836. })
  837. } else {
  838. workflowFormDialogRef.value?.open(data)
  839. }
  840. }
  841. function openCreateDataSourceDialog(data?: any) {
  842. // 有template_id的不允许编辑,是模板转换来的
  843. if (data?.template_id) {
  844. return
  845. }
  846. // 共享过来的工具不让编辑
  847. if (isShared.value) {
  848. return
  849. }
  850. DataSourceToolDrawertitle.value = data
  851. ? t('views.tool.dataSource.editDataSource')
  852. : t('views.tool.dataSource.createDataSource')
  853. if (data) {
  854. loadSharedApi({type: 'tool', systemType: apiType.value})
  855. .getToolById(data?.id, loading)
  856. .then((res: any) => {
  857. DataSourceToolFormDrawerRef.value.open(res.data)
  858. })
  859. } else {
  860. DataSourceToolFormDrawerRef.value.open(data)
  861. }
  862. }
  863. async function changeState(row: any) {
  864. if (row.is_active) {
  865. MsgConfirm(
  866. `${t('views.tool.disabled.confirmTitle')}${row.name} ?`,
  867. t('views.tool.disabled.confirmMessage'),
  868. {
  869. confirmButtonText: t('common.status.disable'),
  870. confirmButtonClass: 'danger',
  871. },
  872. ).then(() => {
  873. const obj = {
  874. is_active: !row.is_active,
  875. }
  876. loadSharedApi({type: 'tool', systemType: apiType.value})
  877. .putTool(row.id, obj, changeStateloading)
  878. .then(() => {
  879. const list = cloneDeep(tool.toolList)
  880. const index = list.findIndex((v) => v.id === row.id)
  881. list[index].is_active = !row.is_active
  882. tool.setToolList(list)
  883. return true
  884. })
  885. .catch(() => {
  886. return false
  887. })
  888. })
  889. } else {
  890. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  891. row.id,
  892. changeStateloading,
  893. )
  894. if (row.tool_type === 'WORKFLOW' && !res.data.is_publish) {
  895. MsgConfirm(t('common.tip'), t('views.tool.toolWorkflow.toActiveTip')).then(() => {
  896. toWorkflow(row)
  897. })
  898. return
  899. }
  900. if (
  901. (!res.data.init_params || Object.keys(res.data.init_params).length === 0) &&
  902. res.data.init_field_list &&
  903. res.data.init_field_list.length > 0 &&
  904. res.data.init_field_list.filter((item: any) => item.default_value && item.show_default_value)
  905. .length !== res.data.init_field_list.length
  906. ) {
  907. InitParamDrawerRef.value.open(res.data, !row.is_active)
  908. return false
  909. }
  910. const obj = {
  911. is_active: !row.is_active,
  912. }
  913. loadSharedApi({type: 'tool', systemType: apiType.value})
  914. .putTool(row.id, obj, changeStateloading)
  915. .then(() => {
  916. const list = cloneDeep(tool.toolList)
  917. const index = list.findIndex((v) => v.id === row.id)
  918. list[index].is_active = !row.is_active
  919. tool.setToolList(list)
  920. return true
  921. })
  922. .catch(() => {
  923. return false
  924. })
  925. }
  926. }
  927. async function copyTool(row: any) {
  928. // mcp工具
  929. if (row?.tool_type === 'MCP') {
  930. bus.emit('select_node', row.folder_id)
  931. await copyMcpTool(row)
  932. return
  933. }
  934. // 数据源工具
  935. if (row?.tool_type === 'DATA_SOURCE') {
  936. bus.emit('select_node', row.folder_id)
  937. await copyDataSource(row)
  938. return
  939. }
  940. // 技能
  941. if (row?.tool_type === 'SKILL') {
  942. bus.emit('select_node', row.folder_id)
  943. await copySkillTool(row)
  944. return
  945. }
  946. if (row?.tool_type === 'WORKFLOW') {
  947. workflowFormDialogTitle.value = t('views.tool.toolWorkflow.copyToolWorkflow')
  948. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  949. row.id,
  950. changeStateloading,
  951. )
  952. const obj = cloneDeep(res.data)
  953. delete obj['id']
  954. obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
  955. workflowFormDialogRef.value?.open(obj)
  956. return
  957. }
  958. ToolDrawertitle.value = t('views.tool.copyTool')
  959. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  960. row.id,
  961. changeStateloading,
  962. )
  963. const obj = cloneDeep(res.data)
  964. delete obj['id']
  965. obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
  966. ToolFormDrawerRef.value.open(obj)
  967. }
  968. async function copyMcpTool(row: any) {
  969. McpToolDrawertitle.value = t('views.tool.mcp.copyMcpTool')
  970. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  971. row.id,
  972. changeStateloading,
  973. )
  974. const obj = cloneDeep(res.data)
  975. delete obj['id']
  976. obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
  977. McpToolFormDrawerRef.value.open(obj)
  978. }
  979. async function copyDataSource(row: any) {
  980. DataSourceToolDrawertitle.value = t('views.tool.dataSource.copyDataSource')
  981. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  982. row.id,
  983. changeStateloading,
  984. )
  985. const obj = cloneDeep(res.data)
  986. delete obj['id']
  987. obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
  988. DataSourceToolFormDrawerRef.value.open(obj)
  989. }
  990. async function copySkillTool(row: any) {
  991. SkillToolDrawertitle.value = t('views.tool.skill.copySkillTool')
  992. const res = await loadSharedApi({type: 'tool', systemType: apiType.value}).getToolById(
  993. row.id,
  994. changeStateloading,
  995. )
  996. const obj = cloneDeep(res.data)
  997. delete obj['id']
  998. obj['name'] = obj['name'] + ` ${t('common.copyTitle')}`
  999. SkillToolFormDrawerRef.value.open(obj)
  1000. }
  1001. function exportTool(row: any) {
  1002. loadSharedApi({type: 'tool', systemType: apiType.value})
  1003. .exportTool(row.id, row.name, loading)
  1004. .catch((e: any) => {
  1005. if (e.response.status !== 403) {
  1006. e.response.data.text().then((res: string) => {
  1007. MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
  1008. })
  1009. }
  1010. })
  1011. }
  1012. function deleteTool(row: any) {
  1013. MsgConfirm(
  1014. `${t('views.tool.delete.confirmTitle')}:${row.name} ?`,
  1015. row.resource_count > 0 ? t('views.tool.delete.resourceCountMessage', row.resource_count) : '',
  1016. {
  1017. confirmButtonText: t('common.confirm'),
  1018. cancelButtonText: t('common.cancel'),
  1019. confirmButtonClass: 'danger',
  1020. },
  1021. )
  1022. .then(() => {
  1023. loadSharedApi({type: 'tool', systemType: apiType.value})
  1024. .delTool(row.id, loading)
  1025. .then(() => {
  1026. const list = cloneDeep(tool.toolList)
  1027. const index = list.findIndex((v) => v.id === row.id)
  1028. list.splice(index, 1)
  1029. tool.setToolList(list)
  1030. MsgSuccess(t('common.deleteSuccess'))
  1031. })
  1032. })
  1033. .catch(() => {
  1034. })
  1035. }
  1036. function configInitParams(item: any) {
  1037. loadSharedApi({type: 'tool', systemType: apiType.value})
  1038. .getToolById(item?.id, changeStateloading)
  1039. .then((res: any) => {
  1040. InitParamDrawerRef.value.open(res.data)
  1041. })
  1042. }
  1043. const toolStoreDialogRef = ref<InstanceType<typeof ToolStoreDialog>>()
  1044. function openToolStoreDialog() {
  1045. toolStoreDialogRef.value?.open(folder.currentFolder.id)
  1046. }
  1047. const AddInternalToolDialogRef = ref<InstanceType<typeof AddInternalToolDialog>>()
  1048. function addInternalTool(data?: any, isEdit?: boolean) {
  1049. AddInternalToolDialogRef.value?.open(data, isEdit)
  1050. }
  1051. function confirmAddInternalTool(data?: any, isEdit?: boolean) {
  1052. if (isEdit) {
  1053. loadSharedApi({type: 'tool', systemType: apiType.value})
  1054. .putTool(data?.id as string, {name: data.name}, loading)
  1055. .then((res: any) => {
  1056. MsgSuccess(t('common.saveSuccess'))
  1057. refresh()
  1058. })
  1059. }
  1060. }
  1061. const storeTools = ref<any[]>([])
  1062. function getStoreToolList() {
  1063. ToolStoreApi.getStoreToolList({name: ''}, loading).then((res: any) => {
  1064. storeTools.value = res.data.apps
  1065. })
  1066. }
  1067. function showUpdateStoreTool(item: any) {
  1068. for (const tool of storeTools.value) {
  1069. if (tool.id === item.template_id && tool.version !== item.version) {
  1070. item.downloadUrl = tool.downloadUrl
  1071. item.downloadCallbackUrl = tool.downloadCallbackUrl
  1072. item.icon = tool.icon
  1073. item.versions = tool.versions
  1074. item.label = tool.label
  1075. return true
  1076. }
  1077. }
  1078. }
  1079. function updateStoreTool(item: any) {
  1080. MsgConfirm(
  1081. t('views.tool.toolStore.confirmTip') + item.name,
  1082. t('views.tool.toolStore.updateStoreToolMessage'),
  1083. {
  1084. cancelButtonText: t('common.cancel'),
  1085. confirmButtonText: t('common.confirm'),
  1086. },
  1087. )
  1088. .then(() => {
  1089. const obj = {
  1090. download_url: item.downloadUrl,
  1091. download_callback_url: item.downloadCallbackUrl,
  1092. icon: item.icon,
  1093. versions: item.versions,
  1094. label: item.label,
  1095. }
  1096. loadSharedApi({type: 'tool', systemType: apiType.value})
  1097. .updateStoreTool(item.id, obj, loading)
  1098. .then(async (res: any) => {
  1099. if (res?.data) {
  1100. tool.setToolList([])
  1101. return user.profile().then(() => {
  1102. getList()
  1103. })
  1104. }
  1105. })
  1106. })
  1107. .catch(() => {
  1108. })
  1109. }
  1110. const elUploadRef = ref()
  1111. function importTool(file: any) {
  1112. const formData = new FormData()
  1113. formData.append('file', file.raw, file.name)
  1114. formData.append('folder_id', folder.currentFolder.id || user.getWorkspaceId())
  1115. elUploadRef.value.clearFiles()
  1116. loadSharedApi({type: 'tool', systemType: apiType.value})
  1117. .postImportTool(formData, loading)
  1118. .then(async (res: any) => {
  1119. if (res?.data) {
  1120. tool.setToolList([])
  1121. return user.profile().then(() => {
  1122. getList()
  1123. })
  1124. }
  1125. })
  1126. .catch((e: any) => {
  1127. if (e.code === 400) {
  1128. MsgConfirm(t('common.tip'), t('views.application.tip.professionalMessage'), {
  1129. cancelButtonText: t('common.confirm'),
  1130. confirmButtonText: t('common.professional'),
  1131. }).then(() => {
  1132. window.open('https://maxkb.cn/pricing.html', '_blank')
  1133. })
  1134. }
  1135. })
  1136. }
  1137. const McpToolConfigDialogRef = ref()
  1138. function showMcpConfig(item: any) {
  1139. loadSharedApi({type: 'tool', systemType: apiType.value})
  1140. .getToolById(item?.id, loading)
  1141. .then((res: any) => {
  1142. McpToolConfigDialogRef.value.open(res.data)
  1143. })
  1144. }
  1145. function refresh(data?: any) {
  1146. if (data) {
  1147. const list = cloneDeep(tool.toolList)
  1148. const index = list.findIndex((v) => v.id === data.id)
  1149. list.splice(index, 1, data)
  1150. tool.setToolList(list)
  1151. } else {
  1152. paginationConfig.total = 0
  1153. paginationConfig.current_page = 1
  1154. tool.setToolList([])
  1155. getList()
  1156. }
  1157. }
  1158. // 文件夹相关
  1159. const CreateFolderDialogRef = ref()
  1160. function openCreateFolder() {
  1161. CreateFolderDialogRef.value.open(SourceTypeEnum.TOOL, folder.currentFolder.id)
  1162. }
  1163. watch(
  1164. () => folder.currentFolder,
  1165. (newValue) => {
  1166. if (newValue && newValue.id) {
  1167. batchSelectedHandle(false)
  1168. paginationConfig.current_page = 1
  1169. tool.setToolList([])
  1170. getList()
  1171. }
  1172. },
  1173. {deep: true, immediate: true},
  1174. )
  1175. watch(
  1176. () => tool.tool_type,
  1177. () => {
  1178. paginationConfig.current_page = 1
  1179. tool.setToolList([])
  1180. getList()
  1181. },
  1182. )
  1183. function getList() {
  1184. const params: any = {
  1185. folder_id: folder.currentFolder?.id || user.getWorkspaceId(),
  1186. scope: apiType.value === 'systemShare' ? 'SHARED' : 'WORKSPACE',
  1187. tool_type: tool.tool_type || '',
  1188. }
  1189. if (search_form.value[search_type.value]) {
  1190. params[search_type.value] = search_form.value[search_type.value]
  1191. }
  1192. loadSharedApi({type: 'tool', isShared: isShared.value, systemType: apiType.value})
  1193. .getToolListPage(paginationConfig, params, loading)
  1194. .then((res: any) => {
  1195. paginationConfig.total = res.data?.total
  1196. tool.setToolList([...tool.toolList, ...res.data?.records])
  1197. })
  1198. }
  1199. function refreshFolder() {
  1200. emit('refreshFolder')
  1201. }
  1202. function searchHandle() {
  1203. paginationConfig.current_page = 1
  1204. tool.setToolList([])
  1205. getList()
  1206. }
  1207. onMounted(() => {
  1208. if (apiType.value !== 'workspace') {
  1209. getList()
  1210. }
  1211. loadSharedApi({type: 'workspace', isShared: isShared.value, systemType: apiType.value})
  1212. .getAllMemberList(user.getWorkspaceId(), loading)
  1213. .then((res: any) => {
  1214. user_options.value = res.data
  1215. })
  1216. getStoreToolList()
  1217. })
  1218. </script>
  1219. <style lang="scss" scoped></style>