<template>
<div class="a-upload-container">
<a-upload
v-model:file-list="fileListModel"
:maxCount="maxCount"
:listType="listType"
:multiple="multiple"
:before-upload="beforeUpload"
:customRequest="customRequest"
:showUploadList="showUploadList"
:progress="progress"
>
<div v-if="fileListModel.length < maxCount">
<a-button v-if="listType === 'text'">
<upload-outlined></upload-outlined>
Upload
</a-button>
<div v-else>
<plus-outlined />
<div style="margin-top: 8px">Upload</div>
</div>
</div>
<template
#iconRender="{ file: UploadFile }"
v-if="customIconRender.isCustom"
>
<img
v-if="handelFileSuffix(UploadFile.name) === 'PDF'"
src="@/assets/bulkUpload/pdf.png"
/>
<img
v-if="['EXCEL', 'XLSX'].includes(handelFileSuffix(UploadFile.name))"
src="@/assets/bulkUpload/excel.png"
/>
<span v-else>
{{ handelFileSuffix(UploadFile.name) }}
</span>
</template>
</a-upload>
<s-modal
:width="800"
v-model:visible="visible"
title="preview"
:footer="null"
>
<div style="height: 500px">
<iframe
class="child"
:src="fileUrl"
style="width: 100%; height: 100%"
frameborder="0"
></iframe>
</div>
</s-modal>
</div>
</template>
<script>
import { message, Upload } from 'ant-design-vue';
import {
PlusOutlined,
UploadOutlined,
LoadingOutlined,
} from '@ant-design/icons-vue';
import { computed, defineComponent } from 'vue';
import { upload } from '@/api/supload';
export default defineComponent({
name: 'Supload',
components: {
PlusOutlined,
UploadOutlined,
LoadingOutlined,
},
props: {
listType: {
type: String,
default: 'picture-card',
},
maxCount: {
type: Number,
default: 2,
},
multiple: {
type: Boolean,
default: true,
},
showUploadList: {
type: Object,
default: {
showPreviewIcon: true,
showRemoveIcon: true,
},
},
modelValue: {
type: Array,
default: () => [],
},
validType: {
type: Array,
default: () => ['PDF', 'EXCEL', 'XLSX'],
},
isLtSize: {
type: Number,
default: 2,
},
checkFile: {
type: Object,
default: () => {
return { isCheck: false };
},
},
customIconRender: {
type: Object,
default: () => {
return {
isCustom: false,
};
},
},
maxChooseCount: {
type: Number,
default: 3,
},
},
setup(props, { emit }) {
const { isLtSize, validType, checkFile, maxCount, maxChooseCount } = props;
const visible = ref(false);
const fileUrl = ref('');
const openFile = ref('');
const progress = {
strokeColor: {
'0%': '#108ee9',
'100%': '#87d068',
},
strokeWidth: 3,
format: (percent) => `${parseFloat(percent.toFixed(2))}%`,
};
const fileListModel = computed({
get: () => props.modelValue,
set: (val) => {
emit('update:modelValue', val);
},
});
const beforeUpload = async (file, fileList) => {
const dataList = JSON.parse(JSON.stringify(fileListModel.value));
let index = dataList.findIndex((item) => item.name === file.name);
const isLt2M = file.size / 1024 / 1024 < isLtSize;
const suffix = file.name
.substring(file.name.lastIndexOf('.') + 1)
.toUpperCase();
const isValidType = validType.includes(suffix);
if (fileList.length > maxChooseCount && file.name === fileList[0].name) {
message.error(`文件超出最大选择限制!`);
return Upload.LIST_IGNORE;
}
if (dataList > maxCount && file.name === fileList[0].name) {
message.error(`文件数量超出限制!`);
return Upload.LIST_IGNORE;
}
if (index > -1) {
message.error(`【${file.name}】文件名重复!`);
return Upload.LIST_IGNORE;
}
if (!isLt2M) {
message.error(`【${file.name}】文件大小超过限制!`);
return Upload.LIST_IGNORE;
}
if (!isValidType) {
message.error(`【${file.name}】文件格式不合法!`);
return Upload.LIST_IGNORE;
}
if (checkFile.isCheck) {
try {
const res = await checkFile.api(file.name);
if (res.code === 0 && res.msg === 'active success') {
return file;
} else {
message.error(res.msg);
return Upload.LIST_IGNORE;
}
} catch (error) {
message.error('Failed to validate file');
return Upload.LIST_IGNORE;
}
}
};
const customRequest = (options) => {
emitIsFinsh(false);
const formData = new FormData();
formData.append('file', options.file);
upload(formData)
.then((res) => {
if (res.code === 0) {
options.onSuccess(res, options.file);
emitIsFinsh(true);
} else {
message.error({
content: res.msg,
});
}
})
.catch((err) => {
message.error(err);
});
};
const emitIsFinsh = (val) => {
emit('update:isFinsh', val);
};
const handlePreview = (file) => {
const { data } = file.response;
openFile.value = file;
if (['XLSX', 'EXCEL'].includes(handelFileSuffix(file.name))) {
window.open(data.url);
return;
}
if (data.url) {
visible.value = true;
fileUrl.value = data.url;
}
};
const handelFileSuffix = (name) => {
return name.substring(name.lastIndexOf('.') + 1).toUpperCase();
};
return {
fileListModel,
visible,
fileUrl,
beforeUpload,
customRequest,
progress,
handelFileSuffix,
openFile,
};
},
});
</script>
<style lang="scss" scoped>
.a-upload-container {
.icon {
width: 50px;
margin: 0 auto;
}
}
</style>
<Supload
v-model="importFileList"
v-model:isFinsh="isFinsh"
:checkFile="{
isCheck: true,
api: checkFileName,
}"
></Supload>