Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion ui/src/views/home/components/ranking/HomeRankings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ function handleRangeChange({ startTime, endTime }: MkDateRangeValue) {
function handleOpenRanking(kind: HomeRankingKind) {
selectedKind.value = kind
}
function handleRankingDrawerClosed() {
selectedKind.value = undefined
}
onMounted(loadRankings)
</script>
<template>
Expand Down Expand Up @@ -131,6 +134,13 @@ onMounted(loadRankings)
<template #description="{ record }">对话 {{ numberFormat(record.chat_record_count) }} 次</template>
</RankingCard>
</div>
<RankingDrawer :api="api" v-if="selectedKind" :workspace-id="workspaceId" :initial-kind="selectedKind" :initial-range="range" />
<RankingDrawer
v-if="selectedKind"
:api="api"
:workspace-id="workspaceId"
:initial-kind="selectedKind"
:initial-range="range"
@closed="handleRankingDrawerClosed"
/>
</section>
</template>
68 changes: 46 additions & 22 deletions ui/src/views/tool/tool-form/DataSourceFormDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import type { FormInstance, FormRules } from 'element-plus'
import type ToolApi from '@/api/admin/workspace/tool/tool'
import type SystemResourceToolApi from '@/api/admin/system/resource-management/tool/tool'
import type SystemSharedToolApi from '@/api/admin/system/shared-resources/tool/tool'
import { TOOL_TYPE } from '@/api/enums'
import { FILE_SOURCE_TYPE, TOOL_TYPE } from '@/api/enums'
import FileApi from '@/api/admin/file'
import type { DynamicFormField, ToolInputField, ToolItem, ToolPayload } from '@/api/types'
import MkEditAvatar from '@/components/mk-edit-avatar/index.vue'
import { useStore } from '@/stores'
import { MsgConfirm, MsgSuccess } from '@/utils/message'
import InitFieldTable from './component/init-field/InitFieldTable.vue'
Expand Down Expand Up @@ -56,28 +58,44 @@ const formRules: FormRules<DataSourceFormModel> = {
name: [{ whitespace: true, required: true, message: '请输入数据源名称', trigger: 'blur' }],
}

// 暂存确认后的头像文件,恢复默认时清空。
const iconFile = ref<File | null>(null)
function handleIconChange(file: File | null) {
iconFile.value = file
}

function handleSubmit() {
formRef.value?.validate((valid) => {
if (!valid) return
return formRef.value?.validate((valid) => {
if (!valid || loading.value) return

const payload: ToolPayload = { ...cloneDeep(dataSourceForm), tool_type: TOOL_TYPE.DATA_SOURCE }
loading.value = true
const currentEditId = editId.value
const isEdit = Boolean(currentEditId)
const request = currentEditId
? props.api.putTool(currentEditId, payload)
: 'postTool' in props.api
? props.api.postTool({ ...payload, folder_id: props.folderId || null })
: Promise.reject(new Error('资源管理不支持创建工具'))

request
.then((savedTool) => {
const refreshCurrentUser = isEdit ? Promise.resolve() : auth.loadAuthBaseProfile()
return refreshCurrentUser.then(() => {
MsgSuccess(isEdit ? '保存成功' : '创建成功')
visible.value = false
if (isEdit) emit('update', savedTool)
else emit('refresh')
// 新头像先上传并替换预览地址,再提交完整工具表单。
const uploadIcon = iconFile.value
? FileApi.postUploadFile(iconFile.value, currentEditId, FILE_SOURCE_TYPE.TOOL).request.then((icon) => {
dataSourceForm.icon = icon
iconFile.value = null
})
: Promise.resolve()

return uploadIcon
.then(() => {
const payload: ToolPayload = { ...cloneDeep(dataSourceForm), tool_type: TOOL_TYPE.DATA_SOURCE }
const request = currentEditId
? props.api.putTool(currentEditId, payload)
: 'postTool' in props.api
? props.api.postTool({ ...payload, folder_id: props.folderId || null })
: Promise.reject(new Error('资源管理不支持创建工具'))

return request.then((savedTool) => {
const refreshCurrentUser = isEdit ? Promise.resolve() : auth.loadAuthBaseProfile()
return refreshCurrentUser.then(() => {
MsgSuccess(isEdit ? '保存成功' : '创建成功')
visible.value = false
if (isEdit) emit('update', savedTool)
else emit('refresh')
})
})
})
.finally(() => {
Expand Down Expand Up @@ -123,6 +141,7 @@ function open(tool?: ToolItem, asCopy = false) {
}

function handleBeforeClose() {
if (loading.value) return
if (JSON.stringify(dataSourceForm) === originalForm.value) {
visible.value = false
return
Expand All @@ -136,6 +155,7 @@ function handleBeforeClose() {

function resetData() {
Object.assign(dataSourceForm, { code: codeTemplate, desc: '', icon: '', init_field_list: [], input_field_list: [], name: '' })
iconFile.value = null
editId.value = undefined
originalForm.value = ''
loading.value = false
Expand All @@ -155,7 +175,7 @@ defineExpose({ open })
<MkDrawer v-model="visible" :before-close="handleBeforeClose" :title="title" size="60%" @closed="handleClosed">
<el-form
ref="formRef"
v-loading="formLoading"
v-loading="formLoading || loading"
:model="dataSourceForm"
:rules="formRules"
label-position="top"
Expand All @@ -165,8 +185,12 @@ defineExpose({ open })
<h4 class="mk-title-decoration mb-4">基本信息</h4>
<el-form-item label="名称" prop="name">
<div class="flex-align-center w-full gap-3">
<!-- // TODO 修改头像 -->
<ToolIcon :icon="dataSourceForm.icon" :size="32" :type="TOOL_TYPE.DATA_SOURCE" />
<!-- 设置工具头像 -->
<MkEditAvatar v-model="dataSourceForm.icon" @change="handleIconChange">
<template #default="{ icon }">
<ToolIcon :icon="icon" :type="TOOL_TYPE.DATA_SOURCE" />
</template>
</MkEditAvatar>
<el-input
v-model="dataSourceForm.name"
maxlength="64"
Expand Down Expand Up @@ -194,7 +218,7 @@ defineExpose({ open })
</el-form>

<template #footer>
<el-button plain :disabled="loading" @click="handleBeforeClose">取消</el-button>
<el-button plain :disabled="loading || formLoading" @click="handleBeforeClose">取消</el-button>
<el-button type="primary" :disabled="formLoading" :loading="loading" @click="handleSubmit">
{{ editId ? '保存' : '创建' }}
</el-button>
Expand Down
68 changes: 46 additions & 22 deletions ui/src/views/tool/tool-form/McpFormDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import type { FormInstance, FormRules } from 'element-plus'
import type ToolApi from '@/api/admin/workspace/tool/tool'
import type SystemResourceToolApi from '@/api/admin/system/resource-management/tool/tool'
import type SystemSharedToolApi from '@/api/admin/system/shared-resources/tool/tool'
import { TOOL_TYPE } from '@/api/enums'
import { FILE_SOURCE_TYPE, TOOL_TYPE } from '@/api/enums'
import FileApi from '@/api/admin/file'
import type { ToolItem, ToolPayload } from '@/api/types'
import MkEditAvatar from '@/components/mk-edit-avatar/index.vue'
import { useStore } from '@/stores'
import { MsgConfirm, MsgError, MsgSuccess } from '@/utils/message'

Expand Down Expand Up @@ -43,6 +45,12 @@ const formRules: FormRules<McpFormModel> = {
name: [{ whitespace: true, required: true, message: '请输入 MCP 名称', trigger: 'blur' }],
}

// 暂存确认后的头像文件,恢复默认时清空。
const iconFile = ref<File | null>(null)
function handleIconChange(file: File | null) {
iconFile.value = file
}

function isValidConfig() {
try {
const config: unknown = JSON.parse(mcpForm.code)
Expand All @@ -55,27 +63,37 @@ function isValidConfig() {
}

function handleSubmit() {
formRef.value?.validate((valid) => {
if (!valid || !isValidConfig()) return
return formRef.value?.validate((valid) => {
if (!valid || loading.value || !isValidConfig()) return

const payload: ToolPayload = { ...cloneDeep(mcpForm), tool_type: TOOL_TYPE.MCP }
loading.value = true
const currentEditId = editId.value
const isEdit = Boolean(currentEditId)
const request = currentEditId
? props.api.putTool(currentEditId, payload)
: 'postTool' in props.api
? props.api.postTool({ ...payload, folder_id: props.folderId || null })
: Promise.reject(new Error('资源管理不支持创建工具'))

request
.then((savedTool) => {
const refreshCurrentUser = isEdit ? Promise.resolve() : auth.loadAuthBaseProfile()
return refreshCurrentUser.then(() => {
MsgSuccess(isEdit ? '保存成功' : '创建成功')
visible.value = false
if (isEdit) emit('update', savedTool)
else emit('refresh')
// 新头像先上传并替换预览地址,再提交完整工具表单。
const uploadIcon = iconFile.value
? FileApi.postUploadFile(iconFile.value, currentEditId, FILE_SOURCE_TYPE.TOOL).request.then((icon) => {
mcpForm.icon = icon
iconFile.value = null
})
: Promise.resolve()

return uploadIcon
.then(() => {
const payload: ToolPayload = { ...cloneDeep(mcpForm), tool_type: TOOL_TYPE.MCP }
const request = currentEditId
? props.api.putTool(currentEditId, payload)
: 'postTool' in props.api
? props.api.postTool({ ...payload, folder_id: props.folderId || null })
: Promise.reject(new Error('资源管理不支持创建工具'))

return request.then((savedTool) => {
const refreshCurrentUser = isEdit ? Promise.resolve() : auth.loadAuthBaseProfile()
return refreshCurrentUser.then(() => {
MsgSuccess(isEdit ? '保存成功' : '创建成功')
visible.value = false
if (isEdit) emit('update', savedTool)
else emit('refresh')
})
})
})
.finally(() => {
Expand Down Expand Up @@ -128,6 +146,7 @@ function open(tool?: ToolItem, asCopy = false) {
}

function handleBeforeClose() {
if (loading.value) return
if (JSON.stringify(mcpForm) === originalForm.value) {
visible.value = false
return
Expand All @@ -141,6 +160,7 @@ function handleBeforeClose() {

function resetData() {
Object.assign(mcpForm, { code: '', desc: '', icon: '', name: '' })
iconFile.value = null
editId.value = undefined
originalForm.value = ''
loading.value = false
Expand All @@ -160,7 +180,7 @@ defineExpose({ open })
<MkDrawer v-model="visible" :before-close="handleBeforeClose" :title="title" size="60%" @closed="handleClosed">
<el-form
ref="formRef"
v-loading="formLoading"
v-loading="formLoading || loading"
:model="mcpForm"
:rules="formRules"
label-position="top"
Expand All @@ -170,8 +190,12 @@ defineExpose({ open })
<h4 class="mk-title-decoration mb-4">基本信息</h4>
<el-form-item label="名称" prop="name">
<div class="flex-align-center w-full gap-3">
<!-- // TODO修改头像 -->
<ToolIcon :icon="mcpForm.icon" :size="32" :type="TOOL_TYPE.MCP" />
<!-- 设置工具头像 -->
<MkEditAvatar v-model="mcpForm.icon" @change="handleIconChange">
<template #default="{ icon }">
<ToolIcon :icon="icon" :type="TOOL_TYPE.MCP" />
</template>
</MkEditAvatar>
<el-input v-model="mcpForm.name" maxlength="64" placeholder="请输入 MCP 名称" show-word-limit @blur="mcpForm.name = mcpForm.name.trim()" />
</div>
</el-form-item>
Expand Down Expand Up @@ -199,7 +223,7 @@ defineExpose({ open })
</el-form>

<template #footer>
<el-button plain :disabled="loading" @click="handleBeforeClose">取消</el-button>
<el-button plain :disabled="loading || formLoading" @click="handleBeforeClose">取消</el-button>
<el-button plain :disabled="loading || formLoading" @click="handleTestConnection"> 测试连接 </el-button>
<el-button type="primary" :disabled="formLoading" :loading="loading" @click="handleSubmit">
{{ editId ? '保存' : '创建' }}
Expand Down
Loading
Loading