一、新建NewUpload.vue文件
<template>
<div class="multi_upload_box">
<van-uploader
:show-upload="showupload"
:deletable="isdelect"
v-model="extant"
:after-read="afterRead"
:name="uploadName"
:multiple="multiple"
:max-count="maxLen"
:before-delete="deleteImgList"
:before-read="beforeRead"
accept=""
:disabled="isdisabled"
>
<van-button v-if="uploadtype == 2" type="info">去上传</van-button>
</van-uploader>
</div>
</template>
<script>
import { upLoaderImg } from '@/utils/upload.js'
import { imgPreview } from "@/utils/imgPreview.js";
export default {
name: 'NewUpload',
props: {
extantFiles: {//反馈到父组件的列表
type: Array,
default: function () {
return []
}
},
maxLen: {
type: Number,
default: 6
},
type: {
type: String,
default: ''
},
multiple: {
type: Boolean,
default: true
},
uploadName: {
type: String,
default: ''
},
isdelect: {
type: Boolean,
default: true
},
showupload: {
type: Boolean,
default: true
},
acceptype: {
type: String,
default: ''
},
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg'],
},
fileSize: {
type: Number,
default: 2,
},
uploadtype: {
type: Number,
default: 1
},
isdisabled: {
type: Boolean,
default: false
}
},
computed: {
},
data() {
return {
extant: [],
vueFile: {},
imgList: [],
count: 0
}
},
watch: {
'extantFiles': {
handler: function (val) {
this.showlist(val)
},
immediate: true,
deep: true
},
'extant': {
handler: function (val) {
this.getlist(val)
},
immediate: true,
deep: true
},
},
methods: {
beforeRead(file) {
//图片上传之前校验类型
this.count = this.extant.length;
// 校验图片上传的格式
// let fileType = '';
// if (file instanceof Array && file.length) {
// for (let i = 0; i < file.length; i++) {
// fileType = file[i].type.substr(0, file[i].type.indexOf('/'));
// console.log(999, fileType)
// if (fileType !== 'image') {
// this.$toast.fail('格式错误')
// return false;
// }
// }
// } else {
// fileType = file.type.substr(0, file.type.indexOf('/'));
// console.log(888, fileType)
// if (fileType !== 'image') {
// this.$toast.fail('格式错误')
// return false;
// }
// }
if (file instanceof Array && file.length) {
for (let i = 0; i < file.length; i++) {
const isTypeOk = this.fileType.some((item) => {
let fileExtension = "";
if (file[i].name.lastIndexOf(".") > -1) {
fileExtension = file[i].name.slice(file[i].name.lastIndexOf(".") + 1);
}
// if (file[i].type.indexOf(item) > -1) return true;
if (fileExtension && fileExtension.indexOf(item) > -1) return true;
return false;
});
if (!isTypeOk && file) {
this.$toast.fail(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
}
// if (this.fileSize && file) {
// const isLt = file[i].size / 1024 / 1024 < this.fileSize;
// if (!isLt) {
// this.$toast.fail(`上传文件大小不能超过 ${this.fileSize} MB!`);
// return false;
// }
// }
}
} else {
if (this.fileType && file) {
const isTypeOk = this.fileType.some((item) => {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
console.log('22', file.type)
// if (file.type.indexOf(item) > -1) return true;
if (fileExtension && fileExtension.indexOf(item) > -1) return true;
return false;
});
if (!isTypeOk && file) {
this.$toast.fail(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
}
}
// if (this.fileSize && file) {
// const isLt = file.size / 1024 / 1024 < this.fileSize;
// if (!isLt) {
// this.$toast.fail(`上传文件大小不能超过 ${this.fileSize} MB!`);
// return false;
// }
// }
}
return true;
},
afterRead(file) {
this.imgList = []
if (Array.isArray(file)) {
// 多图
this.imgList = file
// this.$emit('imgList', this.imgList)
this.imgList.forEach((item) => {
item.loading = false
}) // 为了校验图片是否上传成功
for (let index = 0; index < file.length; index++) {
this.postImg(file[index], this.count + index, index)
}
} else {
// 单图
this.imgList.push(file)
this.imgList.forEach((item) => {
item.loading = false
}) // 为了校验图片是否上传成功
// this.$emit('imgList', this.imgList)
// let index = 0
this.postImg(file, this.count, 0)
}
},
async postImg(file, index, item) {
file.status = 'uploading'
file.message = '上传中...'
await imgPreview(file.file, async (obj) => {
var that = this;
const data = obj
var newData = new FormData()
newData.append('file', data)
await upLoaderImg(newData).then(
(resp) => {
if (resp.code === 0) {
this.$toast.success('上传成功')
console.log('9955', resp)
// that.extant[index].href = resp
this.$set(that.extant[index], 'url', resp.payload.imgUrl) //这个可以是域名拼接的链接
// that.extant[index].url = resp.payload.imgUrl //这个可以是域名拼接的链接
this.$set(that.imgList[item], 'loading', true)
// that.imgList[item].loading = true;
if (that.imgList.length > 0) {
file.status = ''
file.message = ''
}
} else {
that.$toast.fail(resp.errorMessage)
}
},
(error) => {
console.log('err', error)
file.status = 'failed'
file.message = '上传失败'
for (var i = 0; i < this.extant.length; i++) {
if (this.extant[i].file.name === obj.name) {
this.extant.splice(i, 1) // 上传失败后清除正在上传的图片
}
}
}
)
})
},
deleteImgList(file) {
for (var i = 0; i < this.extant.length; i++) {
if (this.extant[i].url === file.url) {
this.extant.splice(i, 1)
}
}
},
getlist(val) {
// console.log('我是监听', val)
var list = []
for (let i = 0; i < val.length; i++) {
// this.extant[i].url = this.extant[i].fileUrl
list.push({
url: val[i].url,
// href: val[i].href,
// title: val[i].file.name,
isImage: true //加上这个解决图片不显示的问题
})
}
// this.$emit('update:extantFiles', list)
this.$emit('change', list)
},
//从父组件拿需要渲染的图片列表
showlist(val) {
var newslist = val;//传进来图片值
var oldlist = this.extant;//当前页面的图片值
if (newslist.length != oldlist.length) {
this.extant = val
} else {
// 长度相等且不为空
var iscommon = true;
// console.log('监听过来的',this.extant)
// console.log('监听2222',val)
if (this.extant.length > 0) {
for (var i = 0; i < this.extant.length; i++) {
if ((val[i].url != this.extant[i].url) && val[i].url && this.extant[i].url) {
// console.log('qqqq',val[i].url)
// console.log('ooooo',this.extant[i])
iscommon = false
break;
}
}
if (!iscommon) {
this.extant = val
}
}
}
}
}
}
</script>
<style lang="less" scoped>
.imgshow {
display: flex;
flex-wrap: wrap;
margin-top: 40px;
background: pink;
}
.imgshow li {
width: 100px;
}
.imgshow li img {
display: block;
width: 100%;
}
.multi_upload_box {
::v-deep .van-uploader__wrapper {
justify-content: flex-start;
.van-uploader__preview {
margin-right: 24px;
border-radius: 4px;
border: 0.5px solid #eee;
box-sizing: border-box;
}
}
}
</style>
二、新建upload.js文件,imgPreview.js图片压缩文件
// upload.js文件
import axios from 'axios' //引入axios
import { Toast } from 'vant' //引入Toast
export function upLoaderImg(file) { //file为 你读取成功的回调文件信息
let config = {
headers: { //添加请求头
'Content-Type': 'multipart/form-data'
}
}
return new Promise((resolve, reject) => {
axios.post(`/api/common/upload`, file,
config).then(res => {
resolve(res.data)
}).catch(err => {
Toast.fail('系统异常')
reject(err)
});
})
}
export function formatter(time) {
let nowdata = time == null ? new Date() : new Date(time);
let year = nowdata.getFullYear();
let month = nowdata.getMonth() + 1;
let date = nowdata.getDate();
let nowtime = year + "-";
if (month < 10) {
nowtime += "0";
}
nowtime += month + "-";
if (date < 10) {
nowtime += "0";
}
nowtime += date;
return nowtime;
}
// 图片压缩
export const imgPreview = (file, callback) => {
//将base64转换为文件
function dataURLtoFile(dataurl, file) {
var arr = dataurl.split(","),
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], file.name, {
type: file.type
});
}
// 压缩图片
function compress(img) {
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
//瓦片canvas
let tCanvas = document.createElement("canvas");
let tctx = tCanvas.getContext("2d");
// let initSize = img.src.length;
let width = img.width;
let height = img.height;
//如果图片大于四百万像素,计算压缩比并将大小压至400万以下
let ratio;
if ((ratio = (width * height) / 4000000) > 1) {
// console.log("大于400万像素");
ratio = Math.sqrt(ratio);
width /= ratio;
height /= ratio;
} else {
ratio = 1;
}
canvas.width = width;
canvas.height = height;
// 铺底色
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
//如果图片像素大于100万则使用瓦片绘制
let count;
if ((count = (width * height) / 1000000) > 1) {
// console.log("超过100W像素");
count = ~~(Math.sqrt(count) + 1); //计算要分成多少块瓦片
// 计算每块瓦片的宽和高
let nw = ~~(width / count);
let nh = ~~(height / count);
tCanvas.width = nw;
tCanvas.height = nh;
for (let i = 0; i < count; i++) {
for (let j = 0; j < count; j++) {
tctx.drawImage(
img,
i * nw * ratio,
j * nh * ratio,
nw * ratio,
nh * ratio,
0,
0,
nw,
nh
);
ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
}
}
} else {
ctx.drawImage(img, 0, 0, width, height);
}
//进行最小压缩
let ndata = canvas.toDataURL("image/jpeg", 0.3);
tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
return ndata;
}
// 看支持不支持FileReader
if (!file || !window.FileReader) {
return;
}
if (/^image/.test(file.type)) {
// 创建一个reader
let reader = new FileReader();
// 将图片转成 base64 格式
reader.readAsDataURL(file);
// 读取成功后的回调
reader.onloadend = function () {
let result = this.result;
let img = new Image();
img.src = result;
//判断图片是否大于500K,是就直接上传,反之压缩图片
if (this.result.length <= 2000 * 1024) {
// 上传图片
let imageFile = dataURLtoFile(this.result, file);
callback(imageFile);
} else {
img.onload = function () {
let data = compress(img);
// 上传图片
let imageFile = dataURLtoFile(data, file);
callback(imageFile);
};
}
}
} else {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function () {
let result = this.result;
let img = new Image();
img.src = result;
let imageFile = dataURLtoFile(this.result, file);
callback(imageFile);
}
}
};
三、其他文件引用NewUpload组件
<template>
<div id="checkOrder">
<div class="infoSubAll">
<van-form @submit="onSubmit" :label-width="110" :scroll-to-error="true">
<div class="infoSubTop">
<div class="infoSubOne">
<div class="addLiAll">
<div class="nameStyl">上传验收结果</div>
<NewUpload
:extantFiles="enterpriseList"
:uploadName="'enterprisename'"
:maxLen="6"
:fileType="['jpg', 'png', 'jpeg']"
@change="enterpriseChange"
></NewUpload>
<div class="contBtnAll">
<van-button
round
block
type="info"
native-type="submit"
:loading="subFlag"
loading-type="spinner"
>提交工单</van-button
>
</div>
</div>
</div>
</div>
</van-form>
</div>
</div>
</template>
<script>
import NewUpload from '@/components/NewUpload.vue'
export default {
name: 'CheckOrder',
data() {
return {
enterpriseList: [],//接收子组件传过来的值
subInfo: {
newPicArr: []
},
}
},
components: {
NewUpload
},
mounted() {
},
methods: {
enterpriseChange(value) {
this.enterpriseList = value
this.subInfo.newPicArr = []
this.enterpriseList.forEach((item) => {
this.subInfo.newPicArr.push(item.url)
})
},
getSubmitSave() {
const data = {
checkResultUrls: this.subInfo.newPicArr.join(',')
}
this.subFlag = true
checkSubmit(data).then(
(resp) => {
if (resp.code === 0) {
this.showSub = true
setTimeout(() => {
this.$router.push({
path: '/homePage'
})
}, 3000)
} else {
this.$toast.fail(resp.errorMessage)
}
this.subFlag = false
},
(error) => {
this.subFlag = false
this.$toast.fail(error)
}
)
},
onSubmit() {
this.getSubmitSave()
},
},
}
</script>