<template> <view> <button @click="clickBut()">tdddd</button> <view class="a_mask" v-if="cancelShow"> <form class="a_box" > <view class="a_input"> <view class="tatilstyle"> <view style="font-size: 36rpx;">请添加微信号和微信二维码</view> <view style="margin-top: 12rpx; font-size: 28rpx;">当您下单完成时,陪玩官将需要通过您本次添加的微信号和微信二维码来完成您的订单任务。</view> <view style="margin-top: 14rpx; height: 60rpx; 100%;"> <view style="margin-left: 100rpx; float: left;color: #007AFF;font-weight: 600;">微信号</view> <view style="margin-left: 10rpx;float: left; border-bottom: #fff 1rpx solid ;height: 40rpx; 246rpx;"> <input v-model="weixin" style="font-size: 26rpx;color: #000; " placeholder="点击输入微信号" /> </view> </view> <!-- 添加二维码的图片 --> <robby-image-upload style="float: left;" :value="imageData" :server-url="serverUrl" :showUploadProgress="true" :limit="limitNumber" @delete="deleteImage" @add="addImage" :enable-drag="enableDrag" :enable-del="enableDel" :enable-add="enableAdd"></robby-image-upload> <!-- 添加二维码的图片 --> </view> <view class="button_but"> <view class="but-color" @click="submits()" > <view class="yuan"></view> <view class="returnStyle">返回</view> </view> <view class="but-color" @click="submits()" > <view class="determine"></view> <view class="returnStyle">保存</view> </view> </view> </view> </form> </view> </view> </template> <script> import robbyImageUpload from '@/components/robby-image-upload-weixin.vue'; export default { data() { return { title: 'Hello', cancelShow: false, //弹窗 weixin:'',//微信号 enableDel: true, enableAdd: true, enableDrag: true, limitNumber: 1, imageData: [], } }, onLoad() { }, components: { robbyImageUpload, }, methods: { clickBut() { this.cancelShow = true; }, addImage: function(e) { this.imageData = e.allImages; }, } } </script> <style lang="scss"> .returnStyle{ margin-left: 20rpx; font-size: 34rpx; float: left; } .determine{ width: 50rpx ; height: 50rpx; border-radius: 40rpx; background-color: #007AFF; float: left; margin-left: 20rpx; line-height: 160rpx; margin-top: 20rpx; } .yuan{ width: 50rpx ; height: 50rpx; border-radius: 40rpx; background-color: #000000; float: left; margin-left: 20rpx; line-height: 160rpx; margin-top: 20rpx; } /* 悬浮弹窗效果测试 */ .button_but{ float: left; position: absolute; } .but-color { margin-left: 72upx; width: 190upx; float: left; height: 90rpx; font-size: 28upx; line-height: 90rpx; float: left; border-radius: 28upx; background-color: #fff; box-shadow: 0px 16px 16px -7px #E5E0E0; } .tatilstyle { margin-left: 28rpx; width: 548rpx; height:700upx; margin-top: 10rpx; } .a_mask { position: fixed; z-index: 99999; top: 0; left: 0; bottom: 0; right: 0; .a_box { width: 636upx; background-color: #FFC878; float: left; border-radius: 20upx; opacity: 1; position: relative; position: fixed; top: 26%; left: 33%; box-shadow: 0px 16px 40px -7px #F7CB8E; transform: translate(-30%, -10%); .a_input { padding: 30upx 20upx; float: left; font-size: 28upx; background-color: #FFC878; border-radius: 50upx; input { text-align: center; } } } } /* 悬浮弹窗效果测试 */ </style>
<template> <view class="imageUploadContainer"> <view class="imageUploadList"> <view class="imageItem" v-bind:key="index" v-for="(path,index) in imageListData"> <image :src="path" :class="{'dragging':isDragging(index)}" draggable="true" @tap="previewImage" :data-index="index" @touchstart="start" @touchmove.stop.prevent="move" @touchend="stop"></image> <view v-if="isShowDel" class="imageDel" @tap="deleteImage" :data-index="index">x</view> </view> <view v-if="isShowAdd" class="imageUpload" @tap="selectImage"> <view style="margin-top: 140rpx;"> 点击添加</br>添加微信二维码 </view> </view> </view> <image v-if="showMoveImage" class="moveImage" :style="{left:posMoveImageLeft, top:posMoveImageTop}" :src="moveImagePath"></image> </view> </template> <script> export default { name: 'robby-image-upload', props: ['value', 'enableDel', 'enableAdd', 'enableDrag', 'serverUrl', 'formData', 'header', 'limit', 'fileKeyName', 'showUploadProgress', 'serverUrlDeleteImage' ], data() { return { imageBasePos: { x0: -1, y0: -1, w: -1, h: -1, }, showMoveImage: false, moveImagePath: '', moveLeft: 0, moveTop: 0, deltaLeft: 0, deltaTop: 0, dragIndex: null, targetImageIndex: null, imageList: [], isDestroyed: false } }, mounted: function() { this.imageList = this.value if (this.showUploadProgress === false) { this.showUploadProgress = false } else { this.showUploadProgress = true } }, destroyed: function() { this.isDestroyed = true }, computed: { imageListData: function() { if (this.value) { return this.value } }, posMoveImageLeft: function() { return this.moveLeft + 'px' }, posMoveImageTop: function() { return this.moveTop + 'px' }, isShowDel: function() { if (this.enableDel === false) { return false } else { return true } }, isShowAdd: function() { if (this.enableAdd === false) { return false } if (this.limit && this.imageList.length >= this.limit) { return false } return true }, isDragable: function() { if (this.enableDrag === false) { return false } else { return true } } }, methods: { selectImage: function() { var _self = this if (!_self.imageList) { _self.imageList = [] } uni.chooseImage({ count: _self.limit ? (_self.limit - _self.imageList.length) : 999, success: function(e) { var imagePathArr = e.tempFilePaths //如果设置了limit限制,在web上count参数无效,这里做判断控制选择的数量是否合要求 //在非微信小程序里,虽然可以选多张,但选择的结果会被截掉 //在app里,会自动做选择数量的限制 if (_self.limit) { var availableImageNumber = _self.limit - _self.imageList.length if (availableImageNumber < imagePathArr.length) { uni.showToast({ title: '图片总数限制为' + _self.limit + '张,当前还可以选' + availableImageNumber + '张', icon: 'none', mask: false, duration: 2000 }); return } } //检查服务器地址是否设置,设置即表示图片要上传到服务器 if (_self.serverUrl) { uni.showToast({ title: '上传进度:0/' + imagePathArr.length, icon: 'none', mask: false }); var remoteIndexStart = _self.imageList.length - imagePathArr.length var promiseWorkList = [] var keyname = (_self.fileKeyName ? _self.fileKeyName : 'upload-images'); var completeImages = 0 for (let i = 0; i < imagePathArr.length; i++) { promiseWorkList.push(new Promise((resolve, reject) => { let remoteUrlIndex = remoteIndexStart + i console.log(imagePathArr[i]) uni.uploadFile({ url:_self.serverUrl, files: 'image', formData:_self.formData, filePath: imagePathArr[i], name: keyname, success: function(res) { if (res.statusCode === 200) { console.log("返回数据") console.log(res) if (_self.isDestroyed) { return } completeImages++ if (_self.showUploadProgress) { uni.showToast({ title: '上传进度:' + completeImages + '/' + imagePathArr.length, icon: 'none', mask: false, duration: 500 }); } console.log('success to upload image: ' + res.data) resolve(res.data) } else { console.log('fail to upload image:' + res.data) reject('fail to upload image:' + remoteUrlIndex) } }, fail: function(res) { console.log('fail to upload image:' + res) reject('fail to upload image:' + remoteUrlIndex) } }) })) } Promise.all(promiseWorkList).then((result) => { if (_self.isDestroyed) { return } for (let i = 0; i < result.length; i++) { _self.imageList.push(result[i]) } _self.$emit('add', { currentImages: imagePathArr, allImages: _self.imageList }) _self.$emit('input', _self.imageList) }) } else { for (let i = 0; i < imagePathArr.length; i++) { _self.imageList.push(imagePathArr[i]) } _self.$emit('add', { currentImages: imagePathArr, allImages: _self.imageList }) _self.$emit('input', _self.imageList) } } }) }, deleteImage: function(e) { var imageIndex = e.currentTarget.dataset.index var deletedImagePath = this.imageList[imageIndex] this.imageList.splice(imageIndex, 1) //检查删除图片的服务器地址是否设置,如果设置则调用API,在服务器端删除该图片 if (this.serverUrlDeleteImage) { uni.request({ url: this.serverUrlDeleteImage, method: 'GET', data: { imagePath: deletedImagePath }, success: res => { console.log(res.data) } }); } this.$emit('delete', { currentImage: deletedImagePath, allImages: this.imageList }) this.$emit('input', this.imageList) }, previewImage: function(e) { var imageIndex = e.currentTarget.dataset.index uni.previewImage({ current: this.imageList[imageIndex], indicator: "number", loop: "true", urls: this.imageList }) }, initImageBasePos: function() { let paddingRate = 0.024 var _self = this //计算图片基准位置 uni.getSystemInfo({ success: function(obj) { let screenWidth = obj.screenWidth let leftPadding = Math.ceil(paddingRate * screenWidth) let imageWidth = Math.ceil((screenWidth - 2 * leftPadding) / 4) _self.imageBasePos.x0 = leftPadding _self.imageBasePos.w = imageWidth _self.imageBasePos.h = imageWidth } }) }, findOverlapImage: function(posX, posY) { let rows = Math.floor((posX - this.imageBasePos.x0) / this.imageBasePos.w) let cols = Math.floor((posY - this.imageBasePos.y0) / this.imageBasePos.h) let indx = cols * 4 + rows return indx }, isDragging: function(indx) { return this.dragIndex === indx }, start: function(e) { console.log(this.isDragable) if (!this.isDragable) { return } this.dragIndex = e.currentTarget.dataset.index this.moveImagePath = this.imageList[this.dragIndex] this.showMoveImage = true //计算纵向图片基准位置 if (this.imageBasePos.y0 === -1) { this.initImageBasePos() let basePosY = Math.floor(this.dragIndex / 4) * this.imageBasePos.h let currentImageOffsetTop = e.currentTarget.offsetTop this.imageBasePos.y0 = currentImageOffsetTop - basePosY } //设置选中图片当前左上角的坐标 this.moveLeft = e.target.offsetLeft this.moveTop = e.target.offsetTop }, move: function(e) { if (!this.isDragable) { return } const touch = e.touches[0] this.targetImageIndex = this.findOverlapImage(touch.clientX, touch.clientY) //初始化deltaLeft/deltaTop if (this.deltaLeft === 0) { this.deltaLeft = touch.clientX - this.moveLeft this.deltaTop = touch.clientY - this.moveTop } //设置移动图片位置 this.moveLeft = touch.clientX - this.deltaLeft this.moveTop = touch.clientY - this.deltaTop }, stop: function(e) { if (!this.isDragable) { return } if (this.dragIndex !== null && this.targetImageIndex !== null) { if (this.targetImageIndex < 0) { this.targetImageIndex = 0 } if (this.targetImageIndex >= this.imageList.length) { this.targetImageIndex = this.imageList.length - 1 } //交换图片 if (this.dragIndex !== this.targetImageIndex) { this.imageList[this.dragIndex] = this.imageList[this.targetImageIndex] this.imageList[this.targetImageIndex] = this.moveImagePath } } this.dragIndex = null this.targetImageIndex = null this.deltaLeft = 0 this.deltaTop = 0 this.showMoveImage = false this.$emit('input', this.imageList) } } } </script> <style> .imageUploadContainer { margin-left: 100rpx; margin-top: 30rpx; } .dragging { transform: scale(1.2) } .imageUploadList { display: flex; flex-wrap: wrap; } .imageItem, .imageUpload { width: 340upx; height: 380upx; } .imageItem image, .moveImage { width: 340upx; height: 380upx; border-radius: 8upx; } .imageDel { position: relative; left: 288upx; bottom: 370upx; background-color: rgba(0, 0, 0, 0.5); width: 36upx; text-align: center; line-height: 35upx; border-radius: 17upx; color: white; font-size: 30upx; } .imageUpload { text-align: center; font-size: 28upx; color: #000; border: 1rpx solid #000; border-radius: 8upx; } .moveImage { position: absolute; } </style>
引入
import robbyImageUpload from '@/components/robby-image-upload-weixin.vue';
效果如图:
支持h5,微信小程序,其他没有测试。