|
|
|
@ -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> |