Files
SaaS-lib/lib/component/form/etable/uplods.vue
xuziqiang d0155dbe3c push
2024-05-15 17:29:42 +08:00

324 lines
8.3 KiB
Vue
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>
<div>
<a-upload
:before-upload="beforeUpload"
@change="handleChange"
:multiple="count != 1"
:customRequest="selfUpload"
:showUploadList="false"
>
<!-- {{ $attrs.value }} -->
<span style="color: #17be6b">{{ $attrs.value ? '证书文件' : fileName }}&nbsp;&nbsp;</span>
<span>上传pdf文件</span>
</a-upload>
<!-- 上传图片框/内置input /-->
</div>
<!-- 错误消息提示 -->
<div class="err-msg" v-if="!isJpgOrPngOrJpeg">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ fileType.join(',') }}123 </p>
</div>
<div class="err-msg" v-if="isJpgOrPngOrJpeg ? !isLt5M : ''">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ maxSize / 1024 / 1024 }} </p>
</div>
<!-- 错误消息提示 /-->
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import { http } from '/nerv-lib/util/http';
import { NsMessage } from '../../message';
import { context } from 'ant-design-vue/es/vc-image/src/PreviewGroup';
interface FileItem {
uid: string;
type: string;
size: number;
name?: string;
status?: string;
response?: string;
percent?: number;
url?: string;
preview?: string;
originFileObj?: any;
}
interface FileInfo {
file: FileItem;
fileList: FileItem[];
}
// 转base64
function getBase64(file: File) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
export default defineComponent({
name: 'NvUpload',
components: {},
props: {
// 上传的地址
url: {
type: String,
require: true,
},
// 上传的图片大小
// maxSize: {
// type: Number,
// / default: 5242880,
// },
// 上传的图片类型
fileType: {
type: Array,
default: () => {
return ['jpg', 'png', 'jpeg'];
},
},
// 展示图片数量
count: {
type: Number,
default: 1,
},
// 上传文件类型0-证书1-图片2-身份证件
uploadType: {
type: Number,
default: 1,
},
},
emits: ['change'],
setup(props, { emit, attrs }) {
console.log(props, 'propslk');
const host = window.location.host;
const previewVisible = ref<boolean>(false);
const isLt5M = ref<boolean>(true);
const isJpgOrPngOrJpeg = ref<boolean>(true);
const previewImage = ref<string | undefined>('');
const fileName = ref<string | undefined>('');
const fileList = ref<FileItem[]>([]);
const currentImg = ref<string[]>([]);
const maskShow = ref<boolean[]>([]);
const fileUuid = ref<string>('');
// console.log(attrs.value, 'uuuuiiiii');
// fileName = `http://` + host + `/api/pension/pension/objs/CertificateFile/` + attrs.value;
const acceptType = computed(() =>
props.fileType.map((item: String) => {
return 'application/' + item;
})
);
const beforeUpload = (file: FileItem) => {
// 上传出错后下次上传图片前重置为true让图片可以上传
isLt5M.value = true;
isJpgOrPngOrJpeg.value = true;
// 限制图片格式,服务器不支持gif图片
if (file.type === 'image/gif') {
NsMessage.warn('不支持gif图片');
return false;
}
console.log(file.type, acceptType.value, 'zhouzhuupload');
isJpgOrPngOrJpeg.value = acceptType.value.includes(file.type);
// 如果大于指定的大小,显示错误信息
// if (file.size > props.maxSize) {
// isLt5M.value = false;
// }
fileName.value = file.name;
return isLt5M.value && isJpgOrPngOrJpeg.value;
};
const handleChange = ({ fileList: newFileList }: FileInfo) => {
console.log(fileList, 'FileInfo');
// 单图上传
// if (props.count === 1) {
// // 删除图片时newFileList.length = 0
// // 图片大小不符合规范时,!isLt5M.value为true
// if (!isLt5M.value || !isJpgOrPngOrJpeg.value || newFileList.length - 1 < 0) {
// // 让图片不显示,也不上传
// fileList.value = [];
// } else {
// // 添加\更换图片
// // newFileList[newFileList.length - 1]的目的是为了只显示最新一张图片
// fileList.value = [newFileList[newFileList.length - 1]];
// }
// } else {
// // 多图上传
// if (!isLt5M.value || !isJpgOrPngOrJpeg.value) {
// fileList.value = newFileList.slice(0, newFileList.length - 1);
// } else {
// fileList.value = newFileList;
// }
// }
};
const selfUpload = async ({ file }) => {
console.log(file, 'file');
const params = {
uploadType: props.uploadType,
};
const formData = new FormData();
formData.append('file', file);
formData.append('uploadType', props.uploadType);
const config = {
headers: {
'Content-Type': 'multipart/form-data',
},
params: params,
};
console.log('uploading....', props.url, formData, config);
http
.post(props.url, formData, config)
.then((res) => {
fileUuid.value = res.data.fileUuid;
emit('change', fileUuid.value);
})
.catch((e) => {
console.log(e, 'e');
NsMessage.error('上传失败,请重试');
});
};
const handlePreview = async (index: number) => {
previewImage.value = (await getBase64(fileList.value[index].originFileObj)) as string;
previewVisible.value = true;
};
const deleteImg = (index: number) => {
currentImg.value.splice(index, 1);
fileList.value.splice(index, 1);
};
const handleCancel = () => {
previewVisible.value = false;
};
const mouseEnter = (index: number) => {
maskShow.value[index] = true;
};
const mouseLeave = (index: number) => {
maskShow.value[index] = false;
};
return {
previewVisible,
previewImage,
fileList,
isLt5M,
isJpgOrPngOrJpeg,
fileName,
currentImg,
maskShow,
fileUuid,
selfUpload,
handleCancel,
handlePreview,
handleChange,
beforeUpload,
mouseEnter,
mouseLeave,
deleteImg,
};
},
});
</script>
<style>
.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card {
margin: 0;
width: 80px;
height: 80px;
border: 1px solid #d9d9d9;
}
.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card:hover {
border-color: #d9d9d9;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
color: #666;
font-size: 12px;
}
.ant-upload-picture-card-wrapper .ant-upload-list-picture-card-container {
width: 88px;
height: 80px;
}
.ant-upload-picture-card-wrapper .ant-upload-list-picture-card .ant-upload-list-item {
margin: 0;
padding: 0;
width: 80px;
height: 80px;
}
.title,
.err-msg {
text-align: left;
}
.err-msg p {
margin: 0;
}
.container {
display: flex;
}
.imgList {
display: flex;
}
.imgContainer {
margin-right: 16px;
border: 1px solid #d9d9d9;
position: relative;
}
.imgCover {
width: 80px;
height: 80px;
object-fit: contain;
}
.imgContainer .mask {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.5);
text-align: center;
line-height: 80px;
}
.mask .anticon-eye {
color: white;
margin-right: 18px;
}
.mask .anticon-eye:hover {
color: #00acff;
margin-right: 18px;
}
.mask .anticon-delete {
color: white;
}
.mask .anticon-delete:hover {
color: #00acff;
}
</style>