feat: 更新依赖项版本,优化上传组件和路由配置,调整表单字段
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import type { UploadCustomRequestOptions, UploadFileInfo } from 'naive-ui';
|
||||
import { type UploadFetchOptions, getS3FileMetadata, uploadToS3 } from '@/utils/aws/s3';
|
||||
import { client, safeClient } from '@/service/api';
|
||||
import { type UploadFetchOptions, uploadToS3 } from '@/utils/aws/s3';
|
||||
|
||||
defineOptions({ name: 'UploadS3' });
|
||||
|
||||
@@ -34,39 +35,24 @@ const emit = defineEmits<{
|
||||
const fileList = ref<UploadFileInfo[]>([]);
|
||||
const loading = ref(false);
|
||||
|
||||
// 初始化文件列表
|
||||
async function initFileList() {
|
||||
const fileIds = props.modelValue.filter(id => id && id.trim() !== '');
|
||||
|
||||
if (!props.modelValue || fileIds.length === 0) {
|
||||
fileList.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const fileInfoPromises = props.modelValue.map(async fileId => {
|
||||
try {
|
||||
const metadata = await getS3FileMetadata(fileId);
|
||||
return {
|
||||
id: fileId,
|
||||
name: metadata.fileName || fileId,
|
||||
status: 'finished' as const,
|
||||
url: fileId,
|
||||
file: null as any
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
id: fileId,
|
||||
name: fileId,
|
||||
status: 'error' as const,
|
||||
url: fileId,
|
||||
file: null as any
|
||||
};
|
||||
}
|
||||
});
|
||||
const { data } = await safeClient(client.api.file_storage.access_urls.post({ fileIds }));
|
||||
|
||||
fileList.value = await Promise.all(fileInfoPromises);
|
||||
fileList.value =
|
||||
data.value?.map(item => ({
|
||||
id: item.id,
|
||||
name: item.fileName || item.id,
|
||||
status: 'finished' as const,
|
||||
url: item.url,
|
||||
file: null as any
|
||||
})) || [];
|
||||
} catch (error) {
|
||||
window.$message?.error('加载文件列表失败');
|
||||
} finally {
|
||||
@@ -74,11 +60,9 @@ async function initFileList() {
|
||||
}
|
||||
}
|
||||
|
||||
// 监听 modelValue 变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal, oldVal) => {
|
||||
// 只在外部变化时重新加载(避免内部上传/删除时重复加载)
|
||||
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
||||
initFileList();
|
||||
}
|
||||
@@ -86,15 +70,12 @@ watch(
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// 组件挂载时初始化
|
||||
onMounted(() => {
|
||||
initFileList();
|
||||
});
|
||||
|
||||
// 自定义上传请求
|
||||
async function handleCustomRequest({ file, onProgress, onFinish, onError }: UploadCustomRequestOptions) {
|
||||
try {
|
||||
// 验证文件大小
|
||||
const fileSizeMB = file.file!.size / 1024 / 1024;
|
||||
if (fileSizeMB > props.maxSize) {
|
||||
window.$message?.error(`文件大小不能超过 ${props.maxSize}MB`);
|
||||
@@ -102,14 +83,12 @@ async function handleCustomRequest({ file, onProgress, onFinish, onError }: Uplo
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证文件数量
|
||||
if (fileList.value.length > props.maxFiles) {
|
||||
window.$message?.error(`最多只能上传 ${props.maxFiles} 个文件`);
|
||||
onError();
|
||||
return;
|
||||
}
|
||||
|
||||
// 上传到 S3
|
||||
const options = {
|
||||
fileName: file.name,
|
||||
fileSize: file.file?.size,
|
||||
@@ -124,38 +103,30 @@ async function handleCustomRequest({ file, onProgress, onFinish, onError }: Uplo
|
||||
}
|
||||
});
|
||||
|
||||
// 添加到文件列表
|
||||
fileList.value.push({
|
||||
id: fileId,
|
||||
name: file.name,
|
||||
status: 'finished',
|
||||
url: fileId,
|
||||
file: null as any
|
||||
});
|
||||
// 直接修改 file 对象的 id,NaiveUI 会自动同步到 fileList
|
||||
file.id = fileId;
|
||||
file.status = 'finished';
|
||||
file.url = fileId;
|
||||
|
||||
// 更新文件 ID 到 modelValue
|
||||
const newFileIds = [...props.modelValue, fileId];
|
||||
emit('update:modelValue', newFileIds);
|
||||
|
||||
onFinish();
|
||||
window.$message?.success(`文件 ${file.name} 上传成功`);
|
||||
} catch (error: any) {
|
||||
window.$message?.error(error.message || '上传失败');
|
||||
onError();
|
||||
}
|
||||
}
|
||||
|
||||
// 删除文件
|
||||
function handleRemove({ file }: { file: UploadFileInfo }) {
|
||||
// 从文件列表中移除
|
||||
fileList.value = fileList.value.filter(f => f.id !== file.id);
|
||||
// 更新 modelValue
|
||||
const newFileIds = props.modelValue.filter(id => id !== file.id);
|
||||
emit('update:modelValue', newFileIds);
|
||||
// 只删除上传成功的文件(有有效 id 的文件)
|
||||
if (file.id && typeof file.id === 'string' && props.modelValue.includes(file.id)) {
|
||||
const newFileIds = props.modelValue.filter(id => id !== file.id);
|
||||
emit('update:modelValue', newFileIds);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 上传前验证
|
||||
function beforeUpload({ file }: { file: UploadFileInfo }) {
|
||||
const fileSizeMB = file.file!.size / 1024 / 1024;
|
||||
if (fileSizeMB > props.maxSize) {
|
||||
|
||||
Reference in New Issue
Block a user