120 lines
3.4 KiB
Vue
120 lines
3.4 KiB
Vue
<template>
|
||
<a-flex justify="space-between" align="center">
|
||
<a-alert message="单个文件不超过5MB,最多只能上传10个文件" type="info" show-icon />
|
||
<a-upload :multiple="true" :before-upload="beforeUpload" :show-upload-list="false">
|
||
<a-button type="primary"> 选择文件 </a-button>
|
||
</a-upload>
|
||
</a-flex>
|
||
|
||
<DynamicTable :search="false" :data-source="fileList" :columns="columns" />
|
||
|
||
<a-flex justify="flex-end" gap="10">
|
||
<Button @click="onCancel">取消</Button>
|
||
<Button :type="'primary'" @click="onOk" :disabled="disabledUpload">上传</Button></a-flex
|
||
>
|
||
</template>
|
||
|
||
<script setup lang="tsx">
|
||
import { ref, computed } from 'vue';
|
||
import { message, type UploadProps } from 'ant-design-vue';
|
||
import { UploadResultStatus, fileListColumns, type FileItem } from './upload-columns';
|
||
import { useTable, type TableColumn } from '@/components/core/dynamic-table';
|
||
import Button from '@/components/basic/button';
|
||
import Api from '@/api/';
|
||
|
||
const emit = defineEmits(['close']);
|
||
|
||
const [DynamicTable] = useTable();
|
||
|
||
const fileList = ref<FileItem[]>([]);
|
||
|
||
const disabledUpload = computed(() => {
|
||
return !fileList.value.some((n) => n.status !== UploadResultStatus.SUCCESS);
|
||
});
|
||
|
||
const fileToBase64 = (file: File): Promise<string> => {
|
||
const { promise, resolve, reject } = Promise.withResolvers<string>();
|
||
|
||
const reader = new FileReader();
|
||
|
||
reader.onload = () => {
|
||
resolve(reader.result as string);
|
||
};
|
||
reader.onerror = (error) => {
|
||
reject(error);
|
||
};
|
||
|
||
reader.readAsDataURL(file);
|
||
return promise;
|
||
};
|
||
|
||
const onCancel = () => {
|
||
const hasSuccess = fileList.value.some((n) => n.status === UploadResultStatus.SUCCESS);
|
||
emit('close', hasSuccess);
|
||
fileList.value = [];
|
||
};
|
||
|
||
const onOk = async () => {
|
||
const uploadFileList = fileList.value.filter((n) => n.status !== UploadResultStatus.SUCCESS);
|
||
await Promise.all(
|
||
uploadFileList.map(async (item) => {
|
||
try {
|
||
await Api.toolsUpload.uploadUpload({ file: item.file }, undefined, {
|
||
onUploadProgress(progressEvent) {
|
||
const complete = ((progressEvent.loaded / progressEvent.total!) * 100) | 0;
|
||
item.percent = complete;
|
||
item.status = UploadResultStatus.UPLOADING;
|
||
},
|
||
});
|
||
item.status = UploadResultStatus.SUCCESS;
|
||
} catch (error) {
|
||
console.log(error);
|
||
item.status = UploadResultStatus.ERROR;
|
||
}
|
||
}),
|
||
);
|
||
};
|
||
|
||
const beforeUpload: UploadProps['beforeUpload'] = async (file) => {
|
||
if (file.size / 1024 / 1024 > 5) {
|
||
message.error('单个文件不超过5MB');
|
||
} else {
|
||
const item: FileItem = {
|
||
file,
|
||
uid: file.uid,
|
||
name: file.name,
|
||
size: file.size,
|
||
status: '',
|
||
percent: 0,
|
||
thumbUrl: await fileToBase64(file),
|
||
};
|
||
fileList.value.push(item);
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
const handleRemove = (record: FileItem) => {
|
||
fileList.value = fileList.value.filter((n) => n.uid !== record.uid);
|
||
};
|
||
|
||
const columns: TableColumn<FileItem>[] = [
|
||
...fileListColumns,
|
||
{
|
||
width: 120,
|
||
title: '操作',
|
||
dataIndex: 'ACTION',
|
||
fixed: false,
|
||
actions: ({ record }) => [
|
||
{
|
||
label: '删除',
|
||
color: 'red',
|
||
onClick: () => handleRemove(record),
|
||
},
|
||
],
|
||
},
|
||
];
|
||
</script>
|
||
|
||
<style scoped></style>
|