@@ -5,8 +5,10 @@ import type { FormInstance, FormRules } from 'element-plus'
55import type ToolApi from ' @/api/admin/workspace/tool/tool'
66import type SystemResourceToolApi from ' @/api/admin/system/resource-management/tool/tool'
77import type SystemSharedToolApi from ' @/api/admin/system/shared-resources/tool/tool'
8- import { TOOL_TYPE } from ' @/api/enums'
8+ import { FILE_SOURCE_TYPE , TOOL_TYPE } from ' @/api/enums'
9+ import FileApi from ' @/api/admin/file'
910import type { ToolItem , ToolPayload } from ' @/api/types'
11+ import MkEditAvatar from ' @/components/mk-edit-avatar/index.vue'
1012import { useStore } from ' @/stores'
1113import { MsgConfirm , MsgError , MsgSuccess } from ' @/utils/message'
1214
@@ -43,6 +45,12 @@ const formRules: FormRules<McpFormModel> = {
4345 name: [{ whitespace: true , required: true , message: ' 请输入 MCP 名称' , trigger: ' blur' }],
4446}
4547
48+ // 暂存确认后的头像文件,恢复默认时清空。
49+ const iconFile = ref <File | null >(null )
50+ function handleIconChange(file : File | null ) {
51+ iconFile .value = file
52+ }
53+
4654function isValidConfig() {
4755 try {
4856 const config: unknown = JSON .parse (mcpForm .code )
@@ -55,27 +63,37 @@ function isValidConfig() {
5563}
5664
5765function handleSubmit() {
58- formRef .value ?.validate ((valid ) => {
59- if (! valid || ! isValidConfig ()) return
66+ return formRef .value ?.validate ((valid ) => {
67+ if (! valid || loading . value || ! isValidConfig ()) return
6068
61- const payload: ToolPayload = { ... cloneDeep (mcpForm ), tool_type: TOOL_TYPE .MCP }
6269 loading .value = true
6370 const currentEditId = editId .value
6471 const isEdit = Boolean (currentEditId )
65- const request = currentEditId
66- ? props .api .putTool (currentEditId , payload )
67- : ' postTool' in props .api
68- ? props .api .postTool ({ ... payload , folder_id: props .folderId || null })
69- : Promise .reject (new Error (' 资源管理不支持创建工具' ))
70-
71- request
72- .then ((savedTool ) => {
73- const refreshCurrentUser = isEdit ? Promise .resolve () : auth .loadAuthBaseProfile ()
74- return refreshCurrentUser .then (() => {
75- MsgSuccess (isEdit ? ' 保存成功' : ' 创建成功' )
76- visible .value = false
77- if (isEdit ) emit (' update' , savedTool )
78- else emit (' refresh' )
72+ // 新头像先上传并替换预览地址,再提交完整工具表单。
73+ const uploadIcon = iconFile .value
74+ ? FileApi .postUploadFile (iconFile .value , currentEditId , FILE_SOURCE_TYPE .TOOL ).request .then ((icon ) => {
75+ mcpForm .icon = icon
76+ iconFile .value = null
77+ })
78+ : Promise .resolve ()
79+
80+ return uploadIcon
81+ .then (() => {
82+ const payload: ToolPayload = { ... cloneDeep (mcpForm ), tool_type: TOOL_TYPE .MCP }
83+ const request = currentEditId
84+ ? props .api .putTool (currentEditId , payload )
85+ : ' postTool' in props .api
86+ ? props .api .postTool ({ ... payload , folder_id: props .folderId || null })
87+ : Promise .reject (new Error (' 资源管理不支持创建工具' ))
88+
89+ return request .then ((savedTool ) => {
90+ const refreshCurrentUser = isEdit ? Promise .resolve () : auth .loadAuthBaseProfile ()
91+ return refreshCurrentUser .then (() => {
92+ MsgSuccess (isEdit ? ' 保存成功' : ' 创建成功' )
93+ visible .value = false
94+ if (isEdit ) emit (' update' , savedTool )
95+ else emit (' refresh' )
96+ })
7997 })
8098 })
8199 .finally (() => {
@@ -128,6 +146,7 @@ function open(tool?: ToolItem, asCopy = false) {
128146}
129147
130148function handleBeforeClose() {
149+ if (loading .value ) return
131150 if (JSON .stringify (mcpForm ) === originalForm .value ) {
132151 visible .value = false
133152 return
@@ -141,6 +160,7 @@ function handleBeforeClose() {
141160
142161function resetData() {
143162 Object .assign (mcpForm , { code: ' ' , desc: ' ' , icon: ' ' , name: ' ' })
163+ iconFile .value = null
144164 editId .value = undefined
145165 originalForm .value = ' '
146166 loading .value = false
@@ -160,7 +180,7 @@ defineExpose({ open })
160180 <MkDrawer v-model =" visible " :before-close =" handleBeforeClose " :title =" title " size="60%" @closed =" handleClosed " >
161181 <el-form
162182 ref =" formRef"
163- v-loading =" formLoading"
183+ v-loading =" formLoading || loading "
164184 :model =" mcpForm"
165185 :rules =" formRules"
166186 label-position =" top"
@@ -170,8 +190,12 @@ defineExpose({ open })
170190 <h4 class =" mk-title-decoration mb-4" >基本信息</h4 >
171191 <el-form-item label =" 名称" prop =" name" >
172192 <div class =" flex-align-center w-full gap-3" >
173- <!-- // TODO修改头像 -->
174- <ToolIcon :icon =" mcpForm .icon " :size =" 32 " :type =" TOOL_TYPE .MCP " />
193+ <!-- 设置工具头像 -->
194+ <MkEditAvatar v-model =" mcpForm .icon " @change =" handleIconChange " >
195+ <template #default =" { icon } " >
196+ <ToolIcon :icon =" icon " :type =" TOOL_TYPE .MCP " />
197+ </template >
198+ </MkEditAvatar >
175199 <el-input v-model =" mcpForm.name" maxlength =" 64" placeholder =" 请输入 MCP 名称" show-word-limit @blur =" mcpForm.name = mcpForm.name.trim()" />
176200 </div >
177201 </el-form-item >
@@ -199,7 +223,7 @@ defineExpose({ open })
199223 </el-form >
200224
201225 <template #footer >
202- <el-button plain :disabled =" loading" @click =" handleBeforeClose" >取消</el-button >
226+ <el-button plain :disabled =" loading || formLoading " @click =" handleBeforeClose" >取消</el-button >
203227 <el-button plain :disabled =" loading || formLoading" @click =" handleTestConnection" > 测试连接 </el-button >
204228 <el-button type =" primary" :disabled =" formLoading" :loading =" loading" @click =" handleSubmit" >
205229 {{ editId ? '保存' : '创建' }}
0 commit comments