<template>
<div>
<a-modal
centered
title="批量上传图片"
v-model="dataVisible"
:keyboard="false"
class="img-modal"
:mask-closable="maskClosable"
ref="imgModal"
@cancel="closemodel"
>
<div class="many_pic">
<input type="file" v-show="false" class="img-file-input" ref="fileInput" multiple :accept="accept" @change="addImg2"/>
<div class="drag_upload_items" :class="changeclass" style="position: relative">
<a-upload-dragger
:accept="fileAccept"
v-show="showupload"
name="file"
:multiple="true"
:before-upload="()=>false"
@change="handleChange"
:show-upload-list="false"
>
<div class="ant-upload-drag-icon">
<img src="~@assets/images/pic_view/drag.png" alt="">
<a-button style="height: 31px;width: 111px;font-size: 14px" shape="round" type="primary">添加图片</a-button>
</div>
</a-upload-dragger>
<ul class="img-list" v-if="imgListShow">
<li class="img-li" v-for="({ src }, index) in imgList" :key="index">
<div class="img-li-inner">
<div class="img-wrapper" @mousedown.prevent="dragStart($event, index)" ref="imgWrapperList">
<img class="img" :src="src" ref="imgList"/>
<div class="img-del-btn-wrapper">
<a-button class="img-del-btn" size="small" type="danger" title="删除图片" @click="delImg(index)" @mousedown.stop>删除图片</a-button>
</div>
<div class="img-name">{{items[index] && items[index].supplierPartId}}</div>
</div>
</div>
</li>
<li class="img-li">
<a-button class="img-add-btn" @click="addImgTip" title="上传图片" v-show="!showupload">
<a-icon type="plus" style="font-size: 21px;color: #3D97D4;font-weight: 400"/>
添加图片
</a-button>
</li>
</ul>
<a-spin style="position: absolute;top: 50%;left: 50%" size="large" v-show="loadings"/>
</div>
</div>
<template #footer>
<a-button title="保存" type="primary" @click="save" class="footer-btn">保存</a-button>
<a-button title="清空" class="form-right-btn empty" @click="clearimglist">清空</a-button>
</template>
</a-modal>
<div class="drag-img-outer" v-show="dragShow" ref="dragObj">
<div class="drag-img-inner">
<img class="drag-img" :src="dragSrc"/>
</div>
</div>
</div>
</template>
<script>
import ModalMixin from "@/mixins/ModalMixin";
import BaseMsg from "@/tools/BaseMsg";
const getElementToPageTop = element => {
const { offsetParent, offsetTop } = element;
return offsetParent ? (getElementToPageTop(offsetParent) + offsetTop) : offsetTop;
};
const getElementToPageLeft = element => {
const { offsetParent, offsetLeft } = element;
return offsetParent ? (getElementToPageLeft(offsetParent) + offsetLeft) : offsetLeft;
};
const MODAL_DIALOG_SELECTOR = "[role=dialog]";
export default {
data() {
return {
imgType: ["image/jpeg", "image/png"],
imgList: [],
dragShow: false,
dragSrc: "",
dragSpeed: 10,
dragMouseX: null,
dragMouseY: null,
dragIndex: null,
showupload:true,
changeflag:true,
items:[],
hasup:0,
fileType: ["image/jpeg", "image/png", "image/jpg"],
loadings:false,
}
},
computed: {
imgListShow() {
return this.imgList && this.imgList.length > 0;
},
accept() {
return this.imgType.join(',');
},
maxCount() {
return this.items ? (this.items.length > 10 ? 10 : this.items.length) : 0;
},
changeclass(){
let changeclass = this.changeflag ? "changeclass": ""
return changeclass
},
fileAccept() {
return this.fileType.length === 0 ? "*" : this.fileType.join(",");
},
},
methods: {
getItems(e){
this.items = e
this.showupload = true
this.changeflag = true;
this.hasup = 0;
},
//第二种新增
addImg2({ target: { files, value } }) {
if (!value) {
return;
}
this.addImg(files)
},
// 新增图片
addImg(files) {
const { error } = BaseMsg;
if (files && files.length > 0) {
const promises = [];
const length = files.length > this.maxCount ? this.maxCount : files.length;
for (let i = 0; i < length; i++) {
const file = files[i];
const { type, size, name } = file;
if (!this.imgType.includes(type)) {
error('请选择JPG或PNG格式图片');
return;
}
const MAX_FILE_NAME_LENGTH = 128;
if (name.length > MAX_FILE_NAME_LENGTH) {
error(`文件名称不能超过${MAX_FILE_NAME_LENGTH}个字符`);
return;
}
if (size < 10240) {
error('图片需大于10KB');
return;
}
const formData = new FormData();
formData.append('reapPicUrl', file);
this.loadings = true
applyReapPicV2(
formData
).then(({data}) => {
this.imgList.push({MD5Name:data.md5Name,src:data.url})
}).finally(()=> this.loadings = false)
}
//Promise.all(promises).then(imgList => this.imgList.push(...imgList));
}
},
// 删除图片
delImg(index) {
this.imgList.splice(index, 1);
if(this.imgList.length ===0){
this.showupload = true;
this.changeflag = true;
}
},
save() {
if (!this.imgListShow) {
BaseMsg.error("至少上传一张图片");
return;
}
const itemIdList = this.items.map(({ itemId,supplierOrderId }) => ({itemId,supplierOrderId}));
const fileList = this.imgList.map(e => ({ MD5Name: e.MD5Name }));
const mergedArray = [];
let size_sum = 0
if(itemIdList.length > fileList.length){
itemIdList.forEach((e,index)=>{
if(index < fileList.length){
const reapPicUrl = fileList[index];
mergedArray.push({ ...reapPicUrl, ...e });
//size_sum += reapPicUrl.size
}else{
const reapPicUrl = fileList[fileList.length -1];
mergedArray.push({ ...reapPicUrl, ...e });
//size_sum += reapPicUrl.size
}
})
}else{
fileList.forEach((reapPicUrl, index) => {
const objB = itemIdList[index];
mergedArray.push({ ...reapPicUrl, ...objB });
//size_sum += reapPicUrl.size
});
}
if(size_sum > 20971520){
BaseMsg.error("图片总大小超过20M")
}
let param = {
"reapPicApplyReqVOS":mergedArray
}
BaseMsg.confirm({
content: "确认保存?",
onOk: () => batchBuyerApplyReapPic(
param
).then(({data}) => {
this.$emit("ok");
BaseMsg.success("已保存");
this.$emit("manyImg",data)
this.close();
})
});
},
show() {
this.imgList = [];
},
addImgTip() {
if (this.imgList.length < this.maxCount) {
const { fileInput } = this.$refs;
if (fileInput) {
fileInput.value = "";
fileInput.click();
}
} else {
BaseMsg.info("图片文件数不能大于选中的商品数量(一次最多10张)");
}
},
// 开始拖动
dragStart({ currentTarget, pageX, pageY }, index) {
const { imgList, dragObj, imgModal } = this.$refs;
const { src, width, height } = imgList?.[index];
this.dragSrc = src;
const pageLeft = getElementToPageLeft(currentTarget);
const pageTop = getElementToPageTop(currentTarget);
const imgModalDialog = imgModal.$el.querySelector(MODAL_DIALOG_SELECTOR);
const { scrollTop, scrollLeft } = imgModalDialog;
// edge浏览器和其他浏览器不一致
const bodyScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const bodyScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
dragObj.style.left = `${pageLeft - scrollLeft}px`;
dragObj.style.top = `${pageTop - scrollTop}px`;
dragObj.style.width = `${width}px`;
dragObj.style.height = `${height}px`;
this.dragShow = true;
this.dragMouseX = pageX - bodyScrollLeft + scrollLeft - pageLeft;
this.dragMouseY = pageY - bodyScrollTop + scrollTop - pageTop;
this.dragIndex = index;
document.addEventListener("mousemove", this.drag);
document.addEventListener("mouseup", this.dragEnd);
},
// 拖动
drag($event) {
debugger
$event.preventDefault();
const { $refs: { dragObj, imgModal }, dragMouseX, dragMouseY } = this;
const { pageX, pageY } = $event;
const imgModalDialog = imgModal.$el.querySelector(MODAL_DIALOG_SELECTOR);
const { scrollTop, scrollLeft } = imgModalDialog;
// edge浏览器和其他浏览器不一致
const bodyScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const bodyScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
const { offsetHeight } = dragObj;
const { clientHeight } = document.documentElement;
const left = pageX - bodyScrollLeft - dragMouseX;
const top = pageY - bodyScrollTop - dragMouseY;
// 拖动到边缘
if (top <= 5) {
imgModalDialog.scrollTop = scrollTop - this.dragSpeed;
if (top <= -40) {
if (this.dragSpeed < 100) {
this.dragSpeed++;
}
} else {
this.dragSpeed = 10;
}
} else if (top + offsetHeight >= clientHeight - 5) {
imgModalDialog.scrollTop = scrollTop + this.dragSpeed;
if (top + offsetHeight >= clientHeight + 40) {
if (this.dragSpeed < 100) {
this.dragSpeed++;
}
} else {
this.dragSpeed = 10;
}
} else {
this.dragSpeed = 10;
}
dragObj.style.left = `${left}px`;
dragObj.style.top = `${top}px`;
},
// 拖动结束
dragEnd($event) {
$event.preventDefault();
document.removeEventListener("mousemove", this.drag);
document.removeEventListener("mouseup", this.dragEnd);
const { imgWrapperList, dragObj, imgModal } = this.$refs;
if (dragObj) {
const { offsetLeft, offsetTop, clientHeight, clientWidth } = dragObj;
if (imgWrapperList) {
let column = 1;
let row = 1;
const ROW_COUNT = 5;
const imgModalDialog = imgModal.$el.querySelector(MODAL_DIALOG_SELECTOR);
const { scrollTop, scrollLeft } = imgModalDialog;
for (const verticalIndex in imgWrapperList) {
if (verticalIndex > 0 && verticalIndex % ROW_COUNT == 0) {
const imgWrapper = imgWrapperList[verticalIndex];
const top = getElementToPageTop(imgWrapper) - scrollTop;
const dragBottom = offsetTop + clientHeight;
const imgMiddle = top + imgWrapper.clientHeight / 2;
if (dragBottom < imgMiddle) {
column = (+verticalIndex) / ROW_COUNT;
break;
}
const tempColumn = Math.floor((imgWrapperList.length - 1) / ROW_COUNT);
if (verticalIndex == tempColumn * ROW_COUNT) {
column = tempColumn + 1;
}
}
}
for (const horizontalIndex in imgWrapperList) {
if (horizontalIndex >= ROW_COUNT) {
break;
}
if (horizontalIndex > 0) {
const imgWrapper = imgWrapperList[horizontalIndex];
const left = getElementToPageLeft(imgWrapper) - scrollLeft;
const dragRight = offsetLeft + clientWidth;
const imgMiddle = left + imgWrapper.clientWidth / 2;
if (dragRight < imgMiddle) {
row = +horizontalIndex;
break;
}
if (horizontalIndex == imgWrapperList.length - 1) {
row = imgWrapperList.length;
} else if (horizontalIndex == ROW_COUNT - 1) {
row = ROW_COUNT;
}
}
}
let newIndex = (column - 1) * ROW_COUNT + row - 1;
if (newIndex >= this.imgList.length) {
newIndex = this.imgList.length - 1;
}
const { dragIndex } = this;
const [oldImg] = this.imgList.splice(dragIndex, 1);
this.imgList.splice(newIndex, 0, oldImg);
}
}
this.dragShow = false;
},
handleChange({file}){
this.hasup++
if(this.hasup > 10){
BaseMsg.error("单次最多可选择10张图片")
}
else if(10 > this.hasup && this.hasup > this.maxCount){
return false
}else{
let a = [file]
this.addImg(a)
this.showupload = false
this.changeflag = false;
}
},
closemodel(){
this.hasup = 0
},
clearimglist(){
this.showupload = true
this.changeflag = true;
this.hasup = 0;
this.imgList = [];
}
},
mounted() {
const { dragObj } = this.$refs;
if (dragObj) {
document.body.appendChild(dragObj);
}
},
beforeDestroy() {
const { dragObj } = this.$refs;
if (dragObj) {
document.body.removeChild(dragObj);
}
document.removeEventListener("mousemove", this.drag);
document.removeEventListener("mouseup", this.dragEnd);
}
};
</script>
<style lang="less" scoped>
@import "~@assets/less/base-mixin.less";
.img-modal{
.img-file-tip{
color: @main-color;
font-size: 14px;
margin-bottom: 10px;
}
.img-list{
.clearfix;
margin: 10px -5px;
.img-li{
float: left;
padding: 5px;
width: 132px;
height: 132px;
margin: 0 5px;
.img-li-inner{
border: 1px solid #DDD;
.radius(5px);
padding: 5px;
cursor: pointer;
.img-wrapper{
height: 0;
padding-bottom: 100%;
display: block;
position: relative;
text-align: center;
.img{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.img-del-btn-wrapper{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
.opacity(0);
.baseTransition;
.img-del-btn{
display: inline-block;
vertical-align: middle;
z-index: 2;
}
&::before{
content: "";
height: 100%;
display: inline-block;
vertical-align: middle;
}
}
.img-name {
position: absolute;
bottom: 0;
left: 0;
right: 0;
color: #FFF;
background-color: @main-color;
padding: 2px 0;
}
}
&:hover .img-wrapper{
&::before{
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.1);
z-index: 1;
}
.img-del-btn-wrapper{
.opacity(1);
}
}
}
}
}
}
.drag-img-outer{
position: fixed;
overflow: hidden;
z-index: 9999;
.opacity(0.7);
.drag-img-inner{
width: 100%;
height: $width;
.drag-img{
width: 100%;
height: $width;
}
}
}
.many_pic{
min-height: 313px;
width: 100%;
display: flex;
flex-direction: column;
.drag_upload_items{
flex: 1;
display: flex;
span{
display: block;
width: 322px;
height: 173px;
}
}
}
.img-add-btn{
width: 122px;
height: 122px;
color: #3D97D4;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
/deep/ .ant-modal-body .ant-upload-drag{
background-color: #fff;
}
.drag_icon{
width: 132px;
height: 13px;
font-size: 12px;
font-family: Microsoft YaHei;
font-weight: 300;
color: #999999;
}
.ant-upload-drag-icon{
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
height: 80%;
img {
width: 31px;
height: 26px;
}
}
.changeclass{
justify-content: center;
align-items: center;
}
</style>
拖拽批量上传的图片 vue2
最新推荐文章于 2024-05-08 16:44:13 发布