push
This commit is contained in:
349
lib/component/form/upload-file/upload-fileV2.vue
Normal file
349
lib/component/form/upload-file/upload-fileV2.vue
Normal file
@@ -0,0 +1,349 @@
|
||||
<!-- @format -->
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<p v-if="value && showFile">
|
||||
<a download="" target="_blank" :href="value">{{ downloadName }}</a>
|
||||
<!-- <span class="close">
|
||||
<ns-icon name="close" @click="remove" />
|
||||
</span> -->
|
||||
</p>
|
||||
<div class="clearfix container">
|
||||
<!--:multiple="showCount != 1"-->
|
||||
<!--:showUploadList="false"-->
|
||||
<a-upload
|
||||
:accept="acceptFileType.join()"
|
||||
:before-upload="beforeUpload"
|
||||
:customRequest="selfUpload"
|
||||
:showUploadList="false">
|
||||
<a-button>
|
||||
<upload-outlined />
|
||||
上传文件
|
||||
</a-button>
|
||||
<div class="upload-tips">
|
||||
<!--上传提示信息-->
|
||||
<p v-if="acceptType && acceptType.length > 0"> 支持扩展名:{{ acceptType.join(' ') }} </p>
|
||||
<p v-if="fixedFileName && fixedFileName.length > 0">
|
||||
仅支持文件:{{ fixedFileName.join(' ') }}
|
||||
</p>
|
||||
</div>
|
||||
</a-upload>
|
||||
</div>
|
||||
<!-- 提示 -->
|
||||
<div class="err-msg">
|
||||
<p :style="{ color: 'red' }" v-if="error">{{ error }}</p>
|
||||
</div>
|
||||
<p v-if="!error" :style="{ color: uploadResult === '上传成功' ? '#51b97b' : '#323232' }">
|
||||
{{ fileName }} {{ uploadResult }}
|
||||
</p>
|
||||
<!-- 提示 -->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {
|
||||
UploadOutlined,
|
||||
LoadingOutlined,
|
||||
EyeOutlined,
|
||||
DeleteOutlined,
|
||||
} from '@ant-design/icons-vue';
|
||||
import { defineComponent, ref, computed, reactive, PropType } from 'vue';
|
||||
// import {http} from '/nerv-lib/util/http';
|
||||
import { NsMessage } from '../../message';
|
||||
import { NSAxios } from '/nerv-lib/util/http/axios';
|
||||
import { get, isArray } from 'lodash-es';
|
||||
|
||||
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 interface sizeItem {
|
||||
fileType: Array<string>;
|
||||
maxSize: number;
|
||||
errorTip?: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'NsUploadFileV2',
|
||||
components: {
|
||||
UploadOutlined,
|
||||
LoadingOutlined,
|
||||
DeleteOutlined,
|
||||
EyeOutlined,
|
||||
},
|
||||
props: {
|
||||
// 上传的地址
|
||||
url: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
// 上传的图片大小
|
||||
maxSize: {
|
||||
type: Number || (Array as PropType<Array<sizeItem>>), // [ { 'maxSize':512488000,'fileType': ['jpg', 'png'] } ]
|
||||
default: 524288000,
|
||||
},
|
||||
// 上传的图片类型
|
||||
fileType: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return ['.jpg', '.png', '.jpeg'];
|
||||
},
|
||||
},
|
||||
//弹窗限制的类型
|
||||
acceptFileType: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return ['jpg', 'png', 'jpeg'];
|
||||
},
|
||||
},
|
||||
// 固定限制的文件名称
|
||||
fixedFileName: {
|
||||
type: Array,
|
||||
},
|
||||
//随file添加固定传参
|
||||
params: {
|
||||
type: [Object],
|
||||
},
|
||||
// 展示图片数量
|
||||
showCount: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
// 上传文件类型,0-证书,1-图片,2-身份证件
|
||||
uploadType: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
//是否显示下载附件
|
||||
showFile: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
//传入数据数据源
|
||||
dataSouce: {
|
||||
type: Object,
|
||||
},
|
||||
//处理传入数据用于触发change事件
|
||||
setDataSouce: {
|
||||
type: Function,
|
||||
},
|
||||
//获取下载链接
|
||||
getUrlOrName: {
|
||||
type: Function,
|
||||
},
|
||||
//设置取值字段
|
||||
valueField: {
|
||||
type: String,
|
||||
default: 'data.httpUrl',
|
||||
},
|
||||
value: {
|
||||
type: String || Object,
|
||||
},
|
||||
downloadName: {
|
||||
type: String || Object,
|
||||
default: '下载文件',
|
||||
},
|
||||
},
|
||||
emits: ['change'],
|
||||
setup(props, { attrs, emit }) {
|
||||
function createHttp() {
|
||||
/** todo 临时去除超时时间 */
|
||||
return new NSAxios({
|
||||
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
|
||||
withCredentials: true,
|
||||
});
|
||||
}
|
||||
const uploadHttp = createHttp();
|
||||
const previewVisible = ref<boolean>(false);
|
||||
const error = ref<string>('');
|
||||
const uploadResult = ref<string>('');
|
||||
const previewImage = ref<string | undefined>('');
|
||||
const fileName = ref<string | undefined>('');
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
const currentImg = ref<string[]>([]);
|
||||
const maskShow = ref<boolean[]>([]);
|
||||
let data = reactive({});
|
||||
let tempData = ref({});
|
||||
const acceptType = computed(() =>
|
||||
props.fileType.map((item: String) => {
|
||||
return item;
|
||||
}),
|
||||
);
|
||||
const beforeUpload = (file: FileItem) => {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
fileName.value = file.name;
|
||||
/** 1.判断类型和大小 */
|
||||
error.value = '';
|
||||
uploadResult.value = '';
|
||||
// 文件类型
|
||||
const type = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase();
|
||||
if (acceptType.value && acceptType.value.length > 0) {
|
||||
// 限定文件类型
|
||||
if (acceptType.value.includes(type)) {
|
||||
error.value = '';
|
||||
} else {
|
||||
error.value = `请选择${props.fileType.join(',')}文件`;
|
||||
return false;
|
||||
}
|
||||
} else if (props.fixedFileName) {
|
||||
// 固定文件名称
|
||||
const fixedFileName = props.fixedFileName;
|
||||
if (fixedFileName && fixedFileName.includes(file.name)) {
|
||||
error.value = '';
|
||||
} else {
|
||||
console.log(props.fixedFileName.join(','));
|
||||
error.value = `请选择${props.fixedFileName.join(',')}的文件`;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 文件大小
|
||||
let valid = true;
|
||||
error.value = '';
|
||||
if (isArray(props.maxSize)) {
|
||||
props.maxSize.some((el) => {
|
||||
if (el.fileType.includes(type)) {
|
||||
valid = file.size <= el.maxSize;
|
||||
error.value = valid
|
||||
? ''
|
||||
: el['errorTip'] || ` 请选择${el.maxSize / 1024 / 1024}M内的文件`;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else if (file.size > props.maxSize) {
|
||||
error.value = ` 请选择${props.maxSize / 1024 / 1024}M内的文件`;
|
||||
valid = false;
|
||||
}
|
||||
if (!valid) return valid;
|
||||
return error.value == '';
|
||||
};
|
||||
|
||||
const selfUpload = async ({ file }) => {
|
||||
currentImg.value.unshift(await getBase64(file));
|
||||
const params = {
|
||||
// uploadType: props.uploadType,
|
||||
};
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const config = {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
params: params,
|
||||
};
|
||||
Object.keys(props.params).map((item) => {
|
||||
formData.append(item, props.params[item]);
|
||||
});
|
||||
uploadResult.value = '上传中...';
|
||||
uploadHttp
|
||||
.post(props.url, formData, config)
|
||||
.then((res) => {
|
||||
error.value = '';
|
||||
uploadResult.value = '上传成功';
|
||||
data = res;
|
||||
tempData.value = res.data;
|
||||
if (attrs['fieldMap']) {
|
||||
emit('change', data);
|
||||
} else {
|
||||
emit('change', get(data, props.valueField));
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('err', err);
|
||||
uploadResult.value = '';
|
||||
error.value = `${file.name} 上传失败,请重试`;
|
||||
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;
|
||||
};
|
||||
const remove = () => {
|
||||
Object.keys(tempData.value).map((key) => {
|
||||
tempData.value[key] = '';
|
||||
});
|
||||
emit('change', { data: tempData.value });
|
||||
};
|
||||
const doWnload = (url) => {
|
||||
let a = document.createElement('a');
|
||||
document.body.appendChild(a);
|
||||
a.href = encodeURI(url);
|
||||
//设置下载的文件名
|
||||
// a.download = fileName.value;
|
||||
//触发a标签的点击事件,进行下载
|
||||
a.click();
|
||||
};
|
||||
|
||||
return {
|
||||
previewVisible,
|
||||
previewImage,
|
||||
fileList,
|
||||
error,
|
||||
uploadResult,
|
||||
fileName,
|
||||
currentImg,
|
||||
maskShow,
|
||||
data,
|
||||
tempData,
|
||||
acceptType,
|
||||
selfUpload,
|
||||
handleCancel,
|
||||
handlePreview,
|
||||
beforeUpload,
|
||||
mouseEnter,
|
||||
mouseLeave,
|
||||
deleteImg,
|
||||
doWnload,
|
||||
remove,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.close {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user