<!--
|
* @Date: 2019-08-30 18:04:49
|
* @LastEditors: zxq
|
* @LastEditTime: 2022-08-05 15:10:37
|
* @Description:
|
-->
|
<template>
|
<div class="component-photo-upload-img">
|
<!--title 和上传按钮的图标-->
|
<div class="pic-title">
|
<span v-if="hasTips" style="font-size:14px;color:#FF6666;">*</span>
|
<span style="font-size:14px;font-weight:500;color:#333333;">{{ title }}</span>
|
</div>
|
<!--图片上传列表,删除即重新上传-->
|
<div class="photo-list">
|
<!--图片上传列表-->
|
<template v-for="(item, index) in picList">
|
<div class="pic-item-box" v-if="picList instanceof Array && picList.length" :key="index">
|
<div class="close-div">
|
<div class="close-div-box">
|
<van-icon name="clear" v-if="picList.length > 1" @click="deletPhoto(item,index)" />
|
</div>
|
</div>
|
<!-- <img :src="item.fileUrl" @click="handleDeletePicture(index)" /> -->
|
<img :src="item" @click="handleDeletePicture(index)" />
|
</div>
|
</template>
|
<!--上传按钮-->
|
<div class="pic-item-box" @click="handleUploadPicture" v-if="showUploadBtn">
|
<i class="iconfont iconzhaoxiang"></i>
|
</div>
|
</div>
|
<!-- 真正的上传按钮-->
|
<div>
|
<input
|
style="display: none"
|
type="file"
|
ref="androidInputFileImage"
|
@change="handlePhotoChange($event)"
|
accept="image/*"
|
/>
|
<input
|
style="display: none"
|
type="file"
|
ref="androidInputFileCapture"
|
@change="handlePhotoChange($event)"
|
accept="image/*"
|
capture="camera"
|
/>
|
</div>
|
<!--选择上传图片还是拍照-->
|
|
<!-- <van-action-sheet
|
v-model="selectModel"
|
:close-on-click-overlay="false"
|
cancel-text="取消"
|
:actions="nav"
|
@select="handleMenuSelect"
|
></van-action-sheet> -->
|
<van-action-sheet v-model="selectModel" cancel-text="取消">
|
<div class="content">
|
<div class="upload_input" @click="handleMenuSelect">
|
<div>拍照</div>
|
<input
|
style="cursor:pointer;width:100%;opacity:0;"
|
type="file"
|
id='inputFileCapture'
|
ref="androidInputFileCapture"
|
@change="handlePhotoChange($event,2)"
|
accept="image/*"
|
capture="camera"
|
/>
|
</div>
|
<div class="upload_input" @click="handleMenuSelect">
|
<div>本地相册上传</div>
|
<input
|
style="cursor:pointer;width:100%;opacity: 0;"
|
type="file"
|
id='inputFileImage'
|
ref="androidInputFileImage"
|
@change="handlePhotoChange($event,1)"
|
accept="image/jpg, image/jpeg, image/png"
|
/>
|
</div>
|
</div>
|
</van-action-sheet>
|
</div>
|
</template>
|
|
<script>
|
import { SET_APP_LOADING } from "@/store/mutations-types";
|
import { mapMutations } from "vuex";
|
import EXIF from "exif-js";
|
|
import { _imgCompress, _fileToBase64 } from "@/utils/index";
|
import Vue from "vue";
|
import { Icon } from "vant";
|
import { ActionSheet } from 'vant';
|
|
Vue.use(ActionSheet);
|
Vue.use(Icon);
|
export default {
|
name: "sceneUploadFile",
|
data() {
|
return {
|
selectModel: false, // 模态窗选择拍照还是相册
|
deleteIndex: -1, // 删除图片的index
|
nav: [{ name: "拍照" }, { name: "从手机相册选择" }]
|
};
|
},
|
props: [
|
"title",
|
"fileType", // 文件类型1-合同资料 2-现场合照 3-资料证明
|
"picList",
|
"sourceType",
|
"typeId",
|
"hasTips"
|
],
|
computed: {
|
showUploadBtn() {
|
let num = Number(this.fileType),
|
isArray = Array.isArray(this.picList);
|
|
// 这里只能上传一张
|
if (num === 2 ) {
|
return isArray && this.picList.length < 1;
|
} else if (num === 10 || num === 13) {
|
// 这个类型,只能上传两张
|
return isArray && this.picList.length < 2;
|
} else {
|
return isArray && this.picList.length < 4;
|
}
|
}
|
},
|
methods: {
|
...mapMutations([SET_APP_LOADING]),
|
//删除照片
|
deletPhoto(item, i) {
|
//console.log(item);
|
this.picList.splice(i, 1);
|
},
|
// 处理图片上传的事件(deleteIndex---删除图片的索引)
|
handlePhotoChange: function(evt) {
|
let that = this;
|
that.SET_APP_LOADING(true);
|
// 图片是单选还是多选
|
const files = Array.prototype.slice.call(evt.target.files);
|
// 图片的处理
|
files.forEach(function(file, i) {
|
// 图片的拍摄方向
|
var orientation;
|
// 格式是否支持的判断
|
if (!/\/(?:jpg|jpeg|png)/i.test(file.type)) {
|
that.$vux.toast.text("仅支持jpg|png图片格式", "middle");
|
that.SET_APP_LOADING(false);
|
return;
|
}
|
// 读取图片的元信息
|
EXIF.getData(file, function() {
|
orientation = EXIF.getTag(this, "Orientation");
|
});
|
// 获取文件内容
|
let reader = new FileReader();
|
reader.onload = function() {
|
that.$refs.androidInputFileCapture.value = null;
|
that.$refs.androidInputFileImage.value = null;
|
// 使用exif,处理图片的旋转问题,然后执行回调函数
|
that.getImgData(this.result, orientation, function(data) {
|
// 这里可以使用校正后的图片data了
|
var img = new Image();
|
img.src = data;
|
|
// 图片加载完毕之后进行压缩,然后上传
|
if (img.complete) {
|
callback();
|
} else {
|
img.onload = callback;
|
}
|
// 图片的路径获取成功后
|
function callback() {
|
// 压缩后的图片的base64字符串
|
let data = that.compress(img);
|
// 调取接口上传图片
|
that.submitUploadImg(that.fileType, data, that.deleteIndex);
|
}
|
});
|
};
|
reader.readAsDataURL(file);
|
});
|
},
|
// type文件上传的路径,data图片的base64字符串(删除图片即重新上传)
|
submitUploadImg: function(type, base64, deleteIndex) {
|
let that = this;
|
// 防止操作的模态窗
|
let submitInfo = {
|
base64Data: base64.split(",")[1], // 文件base64
|
//fileType: type,
|
suffix: base64
|
.split(",")[0]
|
.split(";")
|
["0"].split("/")[1]
|
};
|
this.$api
|
.uploadFile({
|
...submitInfo,
|
})
|
.then(
|
res => {
|
// 如果存在删除图片索引
|
if (deleteIndex >= 0) {
|
// 删除以前的那张照片,然后添加新上传的图片
|
// this.picList.splice(deleteIndex, 1, {
|
// fileUrl: res.body.fileUrl,
|
// fileId: res.body.fileId
|
// });
|
this.picList.splice(deleteIndex, 1, res.body.fileUrl);
|
// 将删除索引重置为-1,即当前状态重置为新增,而非删除状态
|
this.deleteIndex = -1;
|
} else {
|
// this.picList.unshift({
|
// fileUrl: res.body.fileUrl,
|
// fileId: res.body.fileId
|
// });
|
this.picList.unshift(
|
res.body.fileUrl
|
);
|
}
|
// 如果是支付二维码的话,需要调取检查授权
|
if (Number(this.fileType) === 8) {
|
this.checkAuth(res.body.fileId);
|
}
|
that.SET_APP_LOADING(false);
|
// 提交整个图片列表
|
this.$emit("on-change-pic", this.picList);
|
},
|
error => {
|
this.SET_APP_LOADING(false);
|
}
|
);
|
|
},
|
// 图片旋转处理
|
getImgData: function(img, dir, next) {
|
// @param {string} img 图片的base64
|
// @param {int} dir exif获取的方向信息
|
// @param {function} next 回调方法,返回校正方向后的base64
|
var image = new Image();
|
let canvas = document.createElement("canvas");
|
let ctx = canvas.getContext("2d");
|
image.onload = function() {
|
let resultWidth = 0;
|
let resultHeight = 0;
|
let maxWidthOrHeight = 1024;
|
let drawWidth = this.naturalWidth;
|
let drawHeight = this.naturalHeight;
|
|
// 以下改变图片大小,控制最大宽度为1024
|
var maxSide = Math.max(drawWidth, drawHeight);
|
if (maxSide > maxWidthOrHeight) {
|
let minSide = Math.min(drawWidth, drawHeight);
|
minSide = (minSide / maxSide) * maxWidthOrHeight;
|
maxSide = maxWidthOrHeight;
|
if (drawWidth > drawHeight) {
|
resultWidth = maxSide;
|
resultHeight = minSide;
|
} else {
|
resultWidth = minSide;
|
resultHeight = maxSide;
|
}
|
} else {
|
resultWidth = drawWidth;
|
resultHeight = drawHeight;
|
}
|
|
if (dir === 3) {
|
canvas.width = resultWidth;
|
canvas.height = resultHeight;
|
ctx.translate(resultWidth, resultHeight);
|
ctx.rotate(Math.PI);
|
} else if (dir === 6) {
|
canvas.width = resultHeight;
|
canvas.height = resultWidth;
|
ctx.translate(resultHeight, 0);
|
ctx.rotate(Math.PI / 2);
|
} else if (dir === 8) {
|
canvas.width = resultHeight;
|
canvas.height = resultWidth;
|
ctx.translate(0, resultWidth);
|
ctx.rotate(-Math.PI / 2);
|
} else {
|
canvas.width = resultWidth;
|
canvas.height = resultHeight;
|
}
|
ctx.drawImage(this, 0, 0, resultWidth, resultHeight);
|
// 返回校正图片
|
next(canvas.toDataURL("image/jpeg", 0.8));
|
};
|
image.src = img;
|
},
|
compress(img) {
|
let quality = 0.92, //压缩比例
|
w = img.width,
|
h = img.height,
|
canvas = document.createElement("canvas"),
|
ctx = canvas.getContext("2d");
|
canvas.width = w;
|
canvas.height = h;
|
ctx.drawImage(img, 0, 0, w, h);
|
return canvas.toDataURL("image/jpeg", quality);
|
},
|
checkAuth(id) {
|
// authStatus: 0 未授权 1授权---用户授权后才能执行下一步
|
this.$api
|
.checkAuth({
|
fileId: id
|
})
|
.then(res => {
|
if (res.body.authStatus === 1) {
|
this.$emit("on-check-auth", "下一步");
|
}
|
});
|
},
|
// 点击上传按钮
|
handleUploadPicture() {
|
if(this.fileType==2){
|
this.$refs.androidInputFileCapture.click();
|
}else{
|
this.selectModel = true;
|
}
|
|
},
|
// 选择拍照或者相册选项
|
handleMenuSelect(item, index) {
|
// if (index === 0) {
|
// this.$refs.androidInputFileCapture.click();
|
// } else {
|
// this.$refs.androidInputFileImage.click();
|
// }
|
this.selectModel = false;
|
},
|
// 处理图片的删除
|
handleDeletePicture(index) {
|
this.deleteIndex = index;
|
this.selectModel = true;
|
}
|
}
|
};
|
</script>
|
|
<style lang="less">
|
.component-photo-upload-img {
|
.upload_input{
|
font-size: 16px;
|
width: 100%;
|
height: 45px;
|
position: relative;
|
text-align: center;
|
margin-top: 10px;
|
input{
|
position: absolute;
|
left: 0;
|
top: 0;
|
}
|
}
|
.pic-title {
|
margin-bottom: 10px;
|
}
|
|
.photo-list {
|
display: flex;
|
padding-bottom: 20px;
|
flex-wrap: wrap;
|
|
.pic-item-box {
|
position: relative;
|
height: 100px;
|
width: 100px;
|
margin-right: 10px;
|
margin-bottom: 10px;
|
line-height: 100px;
|
text-align: center;
|
background: rgba(245, 249, 255, 1);
|
border: 1px dashed rgba(81, 148, 254, 1);
|
border-radius: 4px;
|
.iconzhaoxiang {
|
font-size: 30px;
|
color: #5194fe;
|
}
|
.close-div {
|
position: absolute;
|
top: -45px;
|
right: -10px;
|
//border: 1px red solid;
|
//border-radius:50% ;
|
height: 20px;
|
width: 20px;
|
.close-div-box {
|
//border: 1px red solid;
|
//border-radius:50% ;
|
height: 20px;
|
width: 20px;
|
i {
|
font-size: 20px;
|
}
|
}
|
}
|
img {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
}
|
}
|
</style>
|