246 lines
5.9 KiB
Plaintext
246 lines
5.9 KiB
Plaintext
<template>
|
||
<div class="file-upload-box">
|
||
<component
|
||
:is="!isBtn ? 'a-upload-dragger' : 'a-upload'"
|
||
action="#"
|
||
:id="uuid"
|
||
class="upload-demo my-upload-file"
|
||
:class="fileList.length > 0 && !loading ? 'success-file' : ''"
|
||
:multiple="multiple"
|
||
ref="uploadRef"
|
||
:disabled="loading ? true : self_disabled"
|
||
:custom-request="handleHttpUpload"
|
||
:file-list="fileList"
|
||
@preview="onPreview"
|
||
@remove="handleRemove"
|
||
:before-upload="beforeUpload"
|
||
:showUploadList="showFileList"
|
||
:maxCount="limit"
|
||
:style="getCSSProperties"
|
||
>
|
||
<template v-if="isBtn">
|
||
<a-button type="primary">
|
||
<template #icon>
|
||
<UploadOutlined />
|
||
</template>
|
||
点击上传</a-button
|
||
>
|
||
</template>
|
||
<template v-else>
|
||
<div>
|
||
<FileDoneOutlined
|
||
style="color: #67c23a; font-size: 40px"
|
||
v-if="fileList.length > 0 && !loading"
|
||
/>
|
||
<CloudUploadOutlined v-else style="font-size: 40px" />
|
||
</div>
|
||
<div v-if="!self_disabled">{{
|
||
loading ? '上传中' : fileList.length > 0 ? '上传成功' : '点击或将文件拖拽到这里上传'
|
||
}}</div>
|
||
</template>
|
||
</component>
|
||
<div v-if="!isBtn" class="ant-upload__tip">
|
||
<div v-if="props.fileType">支持扩展名:{{ props.fileType }}</div>
|
||
<div v-if="props.multiple && props.limit">最多上传{{ props.limit }}个文件</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, ref } from 'vue';
|
||
import {
|
||
CloudUploadOutlined,
|
||
FileDoneOutlined,
|
||
UploadOutlined,
|
||
PlusOutlined,
|
||
EditOutlined,
|
||
DeleteOutlined,
|
||
ZoomInOutlined,
|
||
} from '@ant-design/icons-vue';
|
||
import { notification } from 'ant-design-vue';
|
||
import { generateUUID } from '@/utils/auth';
|
||
|
||
const uploadRef = ref();
|
||
import { upload } from '@/api/common';
|
||
|
||
// 接受父组件参数
|
||
const props = defineProps({
|
||
zIndex: {
|
||
default: -1,
|
||
},
|
||
width: {
|
||
default: 200,
|
||
},
|
||
height: {
|
||
default: 200,
|
||
},
|
||
multiple: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
isBtn: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
showFileList: {
|
||
type: Boolean,
|
||
default: true,
|
||
},
|
||
btnTip: {
|
||
type: String,
|
||
default: '',
|
||
},
|
||
limit: {
|
||
type: Number,
|
||
default: undefined,
|
||
},
|
||
fileList: {
|
||
type: Array,
|
||
required: true,
|
||
default: [],
|
||
},
|
||
disabled: {
|
||
default: false,
|
||
},
|
||
fileSize: {
|
||
default: 200,
|
||
},
|
||
orderNo: {
|
||
default: '',
|
||
},
|
||
fileType: {
|
||
default: '',
|
||
},
|
||
name: {
|
||
default: '',
|
||
},
|
||
autoUpload: {
|
||
default: true,
|
||
},
|
||
});
|
||
|
||
// 生成组件唯一id
|
||
const uuid = ref('id-' + generateUUID());
|
||
|
||
const getCSSProperties = computed(() => {
|
||
return {
|
||
width: `${props.width}px`,
|
||
};
|
||
});
|
||
// 判断是否禁用上传和删除
|
||
const self_disabled = computed(() => {
|
||
return props.disabled;
|
||
});
|
||
|
||
const emit = defineEmits(['upload']);
|
||
|
||
const loading = ref(false);
|
||
const handleHttpUpload = async (options) => {
|
||
if (!props.autoUpload) {
|
||
emit('upload', options);
|
||
return;
|
||
}
|
||
loading.value = true;
|
||
try {
|
||
const formData = new FormData();
|
||
formData.append('file', options.file);
|
||
formData.append('name', props.name);
|
||
const res = await upload(formData);
|
||
if (props.multiple) {
|
||
let list = JSON.parse(JSON.stringify(props.fileList));
|
||
list.push({
|
||
url: res.fileUrl,
|
||
name: res.originalName,
|
||
filePath: res.fileUrl,
|
||
fileName: res.originalName,
|
||
});
|
||
emit('upload', list, props.zIndex);
|
||
} else {
|
||
emit('upload', res.fileUrl, res.originalName, props.zIndex);
|
||
}
|
||
} catch (error) {
|
||
notification.error({
|
||
message: '温馨提示',
|
||
description: '上传文件失败!',
|
||
});
|
||
if (props.multiple) {
|
||
emit('upload', props.fileList, props.zIndex);
|
||
} else {
|
||
// uploadRef.value!.clearFiles();
|
||
emit('upload', '', '', props.zIndex);
|
||
}
|
||
options.onError(error as any);
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
|
||
const onPreview = (uploadFile) => {
|
||
window.open(uploadFile?.url);
|
||
};
|
||
|
||
const handleRemove = (file: any) => {
|
||
if (props.multiple) {
|
||
emit(
|
||
'upload',
|
||
props.fileList.filter((f) => !(f.url === file.url)),
|
||
props.zIndex,
|
||
);
|
||
} else {
|
||
// uploadRef.value!.clearFiles();
|
||
emit('upload', '', '', props.zIndex);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* @description 文件上传之前判断
|
||
* @param rawFile 选择的文件
|
||
* */
|
||
const beforeUpload = (rawFile) => {
|
||
const imgSize = rawFile.size / 1024 / 1024 < props.fileSize;
|
||
if (!imgSize) {
|
||
notification.warning({
|
||
message: '温馨提示',
|
||
description: `上传文件大小不能超过 ${props.fileSize}M!`,
|
||
});
|
||
return false;
|
||
}
|
||
if (props.fileType) {
|
||
let fileType = props.fileType.replace(/\s/g, '');
|
||
fileType.split('.').join('|');
|
||
let fileIndex = rawFile.name.lastIndexOf('.');
|
||
let substrName = rawFile.name.substr(fileIndex);
|
||
if (fileType.indexOf(substrName) == -1) {
|
||
notification.warning({
|
||
message: '温馨提示',
|
||
description: '上传文件不符合所需的格式!',
|
||
});
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
</script>
|
||
<style lang="less">
|
||
.success-file.ant-upload.ant-upload-drag {
|
||
border-width: 3px;
|
||
border-color: #67c23a !important;
|
||
}
|
||
.file-upload-box {
|
||
.my-upload-file.ant-upload.ant-upload-drag {
|
||
height: 160px !important;
|
||
.ant-upload {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
.ant-upload__tip {
|
||
line-height: 18px;
|
||
font-size: 12px;
|
||
margin-top: 7px;
|
||
}
|
||
}
|
||
</style>
|