Browse Source

style(frontend): 上传页让「选择文件夹上传」与「选择文件」按钮同行显示

将独立成行的文件夹上传按钮并入 t-upload file-flow 的 trigger 插槽,
与「选择文件」按钮并排一行,消除上传区顶部孤零按钮的松散观感。

- 文件夹上传:@click.stop.prevent 触发独立 webkitdirectory input
- 选择文件:调用官方实例方法 uploadRef.triggerUpload() 打开多文件选择器
- 两个入口各自触发、互不误触;拖拽卡与底部上传按钮逻辑保持不变
Spring-AI-1.1.2
wanghanlin 1 month ago
parent
commit
6c35aa0ff6
  1. 34
      frontend/src/views/DocUpload.vue

34
frontend/src/views/DocUpload.vue

@ -27,14 +27,19 @@
<!-- 上传模式 Tab -->
<t-tabs v-model="uploadMode">
<t-tab-panel value="file" label="📄 文件上传">
<div class="folder-upload-bar">
<t-button variant="outline" size="small" :loading="folderUploading" @click="pickFolder">📁 选择文件夹上传</t-button>
<span v-if="folderUploading" class="folder-progress">上传中 {{ folderProgress ?? 0 }}%</span>
<input ref="folderInput" type="file" webkitdirectory style="display:none;" @change="onFolderSelected" />
</div>
<t-upload :auto-upload="false" theme="file-flow" multiple :before-upload="beforeFileUpload"
<t-upload ref="uploadRef" :auto-upload="false" theme="file-flow" multiple :before-upload="beforeFileUpload"
:request-method="handleFileUpload" accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.md,.json,.csv,.html,.xml,.rtf"
:size-limit="{ size: 50, unit: 'MB', message: '文件大小不能超过 50MB' }" />
:size-limit="{ size: 50, unit: 'MB', message: '文件大小不能超过 50MB' }">
<template #trigger>
<div class="upload-trigger-row">
<t-button variant="outline" :loading="folderUploading" @click.stop.prevent="pickFolder">📁 选择文件夹上传</t-button>
<t-button variant="outline" @click.stop.prevent="pickFile">📄 选择文件</t-button>
<span v-if="folderUploading" class="folder-progress">上传中 {{ folderProgress ?? 0 }}%</span>
</div>
</template>
</t-upload>
<!-- 独立的文件夹选择隐藏 input(不随 t-upload 的 trigger 打开) -->
<input ref="folderInput" type="file" webkitdirectory style="display:none;" @change="onFolderSelected" />
</t-tab-panel>
<t-tab-panel value="text" label="📝 文本">
<t-textarea v-model="textContent" placeholder="粘贴文本内容..." :autosize="{ minRows: 6, maxRows: 12 }" />
@ -54,7 +59,7 @@
<script setup lang="ts">
import { ref, computed, watch, h } from 'vue'
import { DialogPlugin } from 'tdesign-vue-next'
import type { UploadFile } from 'tdesign-vue-next'
import type { UploadFile, UploadInstanceFunctions } from 'tdesign-vue-next'
import { useCategoryStore } from '@/stores/category'
import { useDocumentStore } from '@/stores/document'
import { uploadFile, uploadMarkdown, uploadJsonBasic, uploadFolder } from '@/api/upload'
@ -68,6 +73,9 @@ const uploadMode = ref('file')
const uploadCategory = ref('')
const uploading = ref(false)
// t-upload 实例(用于自定义 trigger 时打开文件选择器)
const uploadRef = ref<UploadInstanceFunctions>()
// 目标目录(value 形如 'folder:xxx',空 = 分类根)
const uploadFolderId = ref('')
const folderTreeData = ref<any[]>([])
@ -224,7 +232,13 @@ function onFolderChange(_value: any, ctx: any) {
}
}
// ==================== 文件夹上传 ====================
// ==================== 上传触发(自定义 trigger 行的两个入口) ====================
/** 选择文件:调用 t-upload 实例方法打开文件选择器 */
function pickFile() {
uploadRef.value?.triggerUpload?.()
}
/** 选择文件夹:触发独立的 webkitdirectory input */
function pickFolder() {
folderInput.value?.click()
}
@ -332,6 +346,6 @@ async function onFolderSelected(e: Event) {
<style scoped>
.upload-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 12px; background: var(--color-bg-subtle); border-radius: 8px; border: 1px solid var(--color-border); margin-bottom: 16px; }
.tag-input-wrapper { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; flex: 1; padding: 4px 8px; border: 1px solid var(--color-border); border-radius: 4px; background: var(--td-bg-color-container); }
.folder-upload-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.upload-trigger-row { display: flex; align-items: center; gap: 8px; }
.folder-progress { font-size: 12px; color: var(--td-text-color-secondary); }
</style>
Loading…
Cancel
Save