wms-antdvue/.svn/pristine/fa/faf33672a180bb1d031ba56baaadd17c5d220007.svn-base
2024-11-07 16:33:03 +08:00

294 lines
7.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="upload-box">
<div v-for="(item, index) in fileList" class="items">
<img v-if="item.filePath" :src="item.filePath" class="upload-image" />
<div class="upload-handle" @click.stop>
<div class="handle-icon" @click="handleEdit(index)" v-if="!self_disabled">
<EditOutlined style="font-size: 20px" />
</div>
<div class="handle-icon" @click="onPreview(index)">
<ZoomInOutlined style="font-size: 20px" />
</div>
<div class="handle-icon" @click="handleRemove(index)" v-if="!self_disabled">
<DeleteOutlined style="font-size: 20px" />
</div>
</div>
</div>
<a-upload-dragger
action="#"
:id="uuid"
class="upload-demo my-upload-images"
:multiple="multiple"
ref="uploadRef"
:style="{ width: width, height: height }"
:disabled="loading ? true : self_disabled || fileList.length >= props.limit"
:custom-request="handleHttpUpload"
:before-upload="beforeUpload"
list-type="picture-card"
:maxCount="limit"
:file-list="fileList"
:show-upload-list="false"
v-if="!self_disabled"
:on-exceed="onExceed"
:accept="props.fileType"
>
<PlusOutlined v-if="!loading" />
<a-progress type="circle" v-else :percentage="progress" />
</a-upload-dragger>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { generateUUID } from '@/utils/auth';
import {
PlusOutlined,
EditOutlined,
DeleteOutlined,
ZoomInOutlined,
} from '@ant-design/icons-vue';
import { notification } from 'ant-design-vue';
const uploadRef = ref();
import { upload } from '@/api/common';
// 接受父组件参数
const props = defineProps({
zIndex: {
default: -1,
},
multiple: {
type: Boolean,
default: false,
},
btnTip: {
type: String,
default: '',
},
limit: {
type: Number,
default: undefined,
},
width: {
type: String,
default: '120px',
},
height: {
type: String,
default: '120px',
},
borderRadius: {
type: String,
default: '8px',
},
fileList: {
type: Array,
required: true,
default: [],
},
disabled: {
default: false,
},
fileSize: {
default: 200,
},
orderNo: {
default: '',
},
fileType: {
default: '',
},
name: {
default: '',
},
});
// 生成组件唯一id
const uuid = ref('id-' + generateUUID());
// 判断是否禁用上传和删除
const self_disabled = computed(() => {
return props.disabled;
});
let editIndex = '';
const emit = defineEmits(['upload']);
const progress = ref(0);
const loading = ref(false);
const handleHttpUpload = async (options) => {
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));
if (editIndex !== '') {
list.splice(editIndex, 1, {
url: res.fileUrl,
name: res.originalName,
filePath: res.fileUrl,
fileName: res.originalName,
});
editIndex = '';
} else {
list.push({
url: res.fileUrl,
name: res.originalName,
filePath: res.fileUrl,
fileName: res.originalName,
});
}
emit('upload', list, props.zIndex);
} else {
emit('upload', res, 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 {
progress.value = 0;
loading.value = false;
}
};
const onPreview = (index: any) => {
window.open(props.fileList[index].filePath);
};
const handleEdit = (index: any) => {
editIndex = index;
const dom = document.querySelector(`.ant-upload #${uuid.value}`);
dom && dom.dispatchEvent(new MouseEvent('click'));
};
const handleRemove = (index: any) => {
editIndex = index;
if (props.multiple) {
emit(
'upload',
props.fileList.filter((f, i) => !(editIndex == i)),
props.zIndex,
);
} else {
uploadRef.value!.clearFiles();
emit('upload', '', props.zIndex);
}
};
const onExceed = () => {
if (props.limit) {
notification.warning({
message: '温馨提示',
description: `最多支持上传${props.limit}张`,
});
}
};
/**
* @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 scoped lang="less">
.upload-box {
position: relative;
display: flex;
flex-wrap: wrap;
> div {
margin-right: 10px;
margin-bottom: 10px;
position: relative;
&.items {
width: v-bind(width);
height: v-bind(height);
border: 1px dashed #d9d9d9;
border-radius: 4px;
padding: 5px;
}
&:hover {
.upload-handle {
opacity: 1;
}
}
}
:deep(.ant-upload) {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: v-bind(width);
height: v-bind(height);
overflow: hidden;
border-radius: 4px;
}
.upload-image {
width: 100%;
height: 100%;
object-fit: contain;
}
.upload-handle {
position: absolute;
top: 0;
right: 0;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
cursor: pointer;
background: rgb(0 0 0 / 60%);
opacity: 0;
.handle-icon {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 6%;
color: aliceblue;
span {
font-size: 85%;
line-height: 85%;
}
}
}
}
</style>