目前代码仍然有些许BUG,如图单页面上存在 单图,多图,多图时 上传图片会出现丢图的情况。
但是单个页面单次使用多图上传功能时没有问题。
正常情况下需要手动点击进行上传。
可以在提交事件中验证是否上传,进行自动上传图片。
附代码:
<view>
<view class="imageUpload" bindtap="selectIcon" wx:if="{{!goods.icon_url}}">+view>
<view class="imageItem" wx:for-key="index" wx:if="{{goods.icon_url}}">
<image src="{{goods.icon_url}}" draggable="true" bindtap="previewImage">image>
<view wx:if="isShowDel" class="imageDel" bindtap="deleteIcon">xview>
view>
view>
<upload-image bind:getImageList="getSwiperImageList" image-list="{{goods.swiper}}">upload-image>
<upload-image bind:getImageList="getDescImageList" image-list="{{goods.desc}}">upload-image>
// pages/admin/goods/add.js
import Utils from '../../../static/utils/utils';
import Toast from '../../../static/dist/toast/toast';
const db = wx.cloud.database()
const cloud = wx.cloud;
Page({
/**
* 页面的初始数据
*/
data: {
goods: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.setData({
goods_id: options.id
})
this.init();
},
selectIcon() {
let that = this;
let goods = this.data.goods;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
let tempPath = res.tempFilePaths[0];
let fileName = new Date().getTime() + '.' + tempPath.substring(tempPath.lastIndexOf('.') + 1, tempPath.length);
wx.cloud.uploadFile({
cloudPath: 'goods/icon/' + new Date().getTime() + fileName,
filePath: tempPath, // 文件路径
}).then(res => {
console.log(res);
let fileID = res.fileID;
wx.cloud.getTempFileURL({
fileList: [fileID],
success: res => {
// get temp file URL
console.log(res.fileList)
console.log(res)
goods.icon_id = res.fileList[0].fileID;
goods.icon_url = res.fileList[0].tempFileURL;
console.log(goods);
that.setData({
goods: goods
})
},
fail: err => {
console.log(err)
// handle error
}
})
}).catch(console.error)
},
fail(res) {
console.log(res);
},
complete(res) {
console.log(res);
}
})
},
deleteIcon(e) {
let goods = this.data.goods;
goods.icon_id = '';
goods.icon_url = '';
this.setData({
goods: goods
})
},
getSwiperImageList(e) {
let imageList = e.detail;
let goods = this.data.goods;
goods.swiper = imageList;
this.setData({
goods: goods
})
console.log(goods);
Toast.success('上传成功');
},
getDescImageList(e) {
let imageList = e.detail;
let goods = this.data.goods;
goods.desc = imageList;
this.setData({
goods: goods
})
Toast.success('上传成功');
},
// 提交
submit(e) {
let goods = this.data.goods;
console.log(goods);
let flag = this.check(goods);
if (!flag) {
return;
}
let _id = goods._id;
if (_id) {
delete goods._id;
delete goods._openid;
wx.cloud.callFunction({
// 要调用的云函数名称
name: 'update',
// 传递给云函数的event参数
data: {
_id: _id,
data: goods,
}
}).then(res => {
console.log(res)
Toast.success('修改成功');
}).catch(console.error)
} else {
db.collection('goods').add({
// data 字段表示需新增的 JSON 数据
data: goods
}).then(res => {
console.log(res)
Toast.success('提交成功');
}).catch(console.error)
}
},
check(goods) {
if (!goods.ptype_id) {
Toast.fail('请选择类型');
return false;
}
if (!goods.brand_id) {
Toast.fail('请选择品牌');
return false;
}
if (!goods.model_id) {
Toast.fail('请选择型号');
return false;
}
let min_price = goods.min_price;
let max_price = goods.max_price;
if (min_price > max_price) {
Toast.fail('最低价格大于最高价格');
return false;
}
if (!goods.icon_url) {
Toast.fail('请上传图标');
return false;
}
if (!goods.swiper || goods.swiper.length == 0) {
Toast.fail('请上传顶部轮播图');
return false;
}
if (!goods.desc || goods.desc.length == 0) {
Toast.fail('请上传图标');
return false;
}
return true;
},
// 选择类型三个方法
focusPtype(e) {
console.log(e)
let that = this;
db.collection('ptype').where({
is_stop: 1
}).get().then(res => {
let ptypeArray = res.data;
let ptypeList = [];
for (let item of ptypeArray) {
ptypeList.push(item.name);
}
that.setData({
ptypeShow: true,
ptypeList: ptypeList,
ptypeArray: ptypeArray
})
}).catch(console.error)
},
cancelPtype(e) {
this.setData({
ptypeShow: false
})
},
selectPtype(e) {
let goods = this.data.goods;
let index = e.detail.index;
let ptypeArray = this.data.ptypeArray;
goods.ptype_id = ptypeArray[index]._id;
goods.ptype_name = e.detail.value;
this.setData({
ptypeShow: false,
goods: goods
})
},
// 选择品牌三个方法
focusBrand(e) {
console.log(e)
let that = this;
db.collection('brand').where({
is_stop: 1
}).get().then(res => {
let brandArray = res.data;
let brandList = [];
for (let item of brandArray) {
brandList.push(item.name);
}
that.setData({
brandShow: true,
brandList: brandList,
brandArray: brandArray
})
}).catch(console.error)
},
cancelBrand(e) {
this.setData({
brandShow: false
})
},
selectBrand(e) {
let goods = this.data.goods;
let index = e.detail.index;
let brandArray = this.data.brandArray;
goods.brand_id = brandArray[index]._id;
goods.brand_name = e.detail.value;
this.setData({
brandShow: false,
goods: goods
})
},
// 选择系列三个方法
focusSeries(e) {
let ptype_id = this.data.goods.ptype_id;
let brand_id = this.data.goods.brand_id;
if (!ptype_id && !brand_id) {
Toast.fail("请先选择系列和品牌");
return;
}
let that = this;
wx.cloud.callFunction({
// 要调用的云函数名称
name: 'getSeries',
// 传递给云函数的event参数
data: {
ptype_id: ptype_id,
brand_id: brand_id,
is_stop: 1
}
}).then(res => {
let seriesArray = res.result.seriesList;
let seriesList = [];
let n = -1;
for (let i = 0; i < seriesArray.length; i++) {
let item = seriesArray[i];
if (!item.name) {
n = i;
continue;
}
seriesList.push(item.name);
}
seriesArray.splice(n, 1);
that.setData({
seriesShow: true,
seriesList: seriesList,
seriesArray: seriesArray
})
}).catch(console.error)
},
cancelSeries(e) {
this.setData({
seriesShow: false
})
},
selectSeries(e) {
let goods = this.data.goods;
let index = e.detail.index;
let seriesArray = this.data.seriesArray;
let phoneArray = seriesArray[index].phoneList;
goods.series_id = seriesArray[index]._id;
goods.series_name = e.detail.value;
this.setData({
seriesShow: false,
goods: goods,
phoneArray: phoneArray
})
},
// 选择系列三个方法
focusModel(e) {
console.log(this.data.goods)
let ptype_id = this.data.goods.ptype_id;
let brand_id = this.data.goods.brand_id;
let series_id = this.data.goods.series_id;
if (!ptype_id && !brand_id) {
Toast.fail("请先选择系列和品牌");
return;
}
let that = this;
console.log(series_id);
if (series_id) {
let modelArray = this.data.phoneArray;
console.log(modelArray)
let modelList = [];
for (let item of modelArray) {
modelList.push(item.name);
}
that.setData({
modelShow: true,
modelList: modelList,
modelArray: modelArray
})
} else {
wx.cloud.callFunction({
// 要调用的云函数名称
name: 'getSeries',
// 传递给云函数的event参数
data: {
ptype_id: ptype_id,
brand_id: brand_id,
is_stop: 1
}
}).then(res => {
let seriesArray = res.result.seriesList;
let modelList = [];
let modelArray = [];
for (let item of seriesArray) {
if (!item.name) {
modelArray = item.phoneList;
break;
}
}
for (let item of modelArray) {
modelList.push(item.name);
}
that.setData({
modelShow: true,
modelList: modelList,
modelArray: modelArray
})
}).catch(console.error)
}
},
cancelModel(e) {
this.setData({
modelShow: false
})
},
selectModel(e) {
let goods = this.data.goods;
let index = e.detail.index;
let modelArray = this.data.modelArray;
goods.model_id = modelArray[index]._id;
goods.model_name = e.detail.value;
this.setData({
modelShow: false,
goods: goods
})
},
inputMinPrice(e) {
console.log(e);
let minPrice = e.detail;
let goods = this.data.goods;
goods.min_price = parseFloat(minPrice);
this.setData({
goods: goods
})
},
inputMaxPrice(e) {
console.log(e);
let maxPrice = e.detail;
let goods = this.data.goods;
goods.max_price = parseFloat(maxPrice);
this.setData({
goods: goods
})
},
// 页面初始化
init() {
let goods_id = this.data.goods_id;
let that = this;
db.collection('goods').where({
_id: goods_id, // 填入当前用户 openid
}).get().then(res => {
that.setData({
goods: res.data[0]
})
}).catch(err => {
console.error(err)
})
}
})
/* pages/admin/goods/add.wxss */
.min_price {
width: 100rpx !important;
display: inline-block;
}
.max_price {
width: 100rpx !important;
display: inline-block;
}
.imageUpload {
line-height: 130rpx;
text-align: center;
font-size: 150rpx;
color: #d9d9d9;
border: 1px solid #d9d9d9;
border-radius: 8rpx;
width: 160rpx;
height: 160rpx;
margin: 10rpx;
}
.imageItem, .imageUpload {
width: 160rpx;
height: 160rpx;
margin: 10rpx;
}
.imageDel {
position: relative;
left: 120rpx;
bottom: 165rpx;
background-color: rgba(0, 0, 0, 0.5);
width: 36rpx;
text-align: center;
line-height: 35rpx;
border-radius: 17rpx;
color: white;
font-size: 30rpx;
padding-bottom: 2rpx;
}
.imageItem image {
width: 160rpx;
height: 160rpx;
border-radius: 8rpx;
}
.submit {
width: 100%;
}
{
"usingComponents": {
"upload-image": "/static/components/upload-image"
}
}
<view class="imageUploadContainer">
<view class="imageUploadList">
<view class="imageItem" wx:for-key="index" wx:for="{{imageList}}">
<image src="{{item.path}}" class="{{item.dragging == '' ? isDragging(index):''}}" draggable="true" bindtap="previewImage" data-index="{{index}}" bindtouchstart="start" bindtouchmove="move" bindtouchend="stop">image>
<view wx:if="isShowDel" class="imageDel" bindtap="deleteImage" data-index="{{index}}">xview>
view>
<view wx:if="isShowAdd" class="imageUpload" bindtap="selectImage">+view>
view>
<image wx:if="showMoveImage" class="moveImage {{showMoveImage ? '':'hide'}}" style="left:{{moveLeft}}px; top:{{moveTop}}px" src="{{moveImagePath}}">image>
view>
<button size="mini" type="primary" class="upload" bindtap="getImageList">上传button>
// static/components/upload-image.js
Component({
/**
* 组件的属性列表
*/
properties: {
imageList: {
type: Array,
value: [],
observer: function() {
}
}
},
created() {
// this.setData({
// imageList: imageList
// })
},
/**
* 组件的初始数据
*/
data: {
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:[]
},
/**
* 组件的方法列表
*/
methods: {
selectImage: function() {
console.log('selectImage');
let that = this;
wx.chooseImage({
count: 9,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
console.log(res);
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths;
let tempFiles = res.tempFiles;
let imgList = [];
for (let item of tempFiles) {
let url = item.path;
wx.cloud.uploadFile({
cloudPath: 'goods/' + new Date().getTime() + '.' + url.substring(url.lastIndexOf('.') + 1, url.length),
filePath: item.path,
}).then(res => {
console.log(res.fileID)
imgList.push({
file_id: res.fileID,
path: item.path
})
that.setData({
imageList: that.data.imageList.concat(imgList)
})
imgList = [];
}).catch(error => {
console.error
// handle error
})
}
// that.setData({
// imageList: that.data.imageList.concat(imgList)
// })
},
fail(res) {
console.log(res);
},
complete(res) {
console.log(res);
}
})
},
deleteImage: function(e) {
console.log('deleteImage');
var imageIndex = e.currentTarget.dataset.index
var deletedImagePath = this.data.imageList[imageIndex]
let imageList = this.data.imageList;
imageList.splice(imageIndex, 1)
this.setData({
imageList: imageList
})
},
previewImage: function(e) {
var imageIndex = e.currentTarget.dataset.index
let imageList = this.data.imageList;
let imgurls = [];
for (let item of imageList) {
imgurls.push(item.path);
}
wx.previewImage({
current: imageList[imageIndex].path, // 当前显示图片的http链接
urls: imgurls // 需要预览的图片http链接列表
})
},
initImageBasePos: function() {
let paddingRate = 0.024
let _self = this
let imageBasePos = this.data.imageBasePos;
//计算图片基准位置
wx.getSystemInfo({
success: function(obj) {
let screenWidth = obj.screenWidth
let leftPadding = Math.ceil(paddingRate * screenWidth)
let imageWidth = Math.ceil((screenWidth - 2 * leftPadding) / 4)
imageBasePos.x0 = leftPadding
imageBasePos.w = imageWidth
imageBasePos.h = imageWidth
_self.setData({
imageBasePos: imageBasePos
})
}
})
},
findOverlapImage: function(posX, posY) {
let rows = Math.floor((posX - this.data.imageBasePos.x0) / this.data.imageBasePos.w)
let cols = Math.floor((posY - this.data.imageBasePos.y0) / this.data.imageBasePos.h)
let indx = cols * 4 + rows
return indx
},
isDragging: function(indx) {
return this.dragIndex === indx
},
start: function(e) {
console.log('start')
// console.log(this.data.isDragable)
// if (!this.data.isDragable) {
// return
// }
let dragIndex = e.currentTarget.dataset.index
let moveImagePath = this.data.imageList[dragIndex].path;
let showMoveImage = true;
let imageBasePos = this.data.imageBasePos;
//计算纵向图片基准位置
if (imageBasePos.y0 === -1) {
this.initImageBasePos()
let basePosY = Math.floor(dragIndex / 4) * imageBasePos.h
let currentImageOffsetTop = e.currentTarget.offsetTop
imageBasePos.y0 = currentImageOffsetTop - basePosY
}
//设置选中图片当前左上角的坐标
let moveLeft = e.target.offsetLeft
let moveTop = e.target.offsetTop
this.setData({
dragIndex: dragIndex,
imageBasePos: imageBasePos,
moveImagePath: moveImagePath,
moveLeft: moveLeft,
showMoveImage: showMoveImage,
moveTop: moveTop
})
},
move: function(e) {
console.log('move');
// if (!this.isDragable) {
// return
// }
console.log(e)
const touch = e.touches[0]
let targetImageIndex = this.findOverlapImage(touch.clientX, touch.clientY)
//初始化deltaLeft/deltaTop
let deltaLeft = this.data.deltaLeft;
let deltaTop = this.data.deltaTop;
if (deltaLeft === 0) {
deltaLeft = touch.clientX - this.data.moveLeft
deltaTop = touch.clientY - this.data.moveTop
}
//设置移动图片位置
let moveLeft = touch.clientX - this.data.deltaLeft
let moveTop = touch.clientY - this.data.deltaTop
console.log(targetImageIndex);
this.setData({
targetImageIndex: targetImageIndex,
deltaLeft: deltaLeft,
deltaTop: deltaTop || this.data.deltaTop,
moveLeft: moveLeft,
moveTop: moveTop
})
},
stop: function(e) {
console.log('stop')
// if (!this.isDragable) {
// return
// }
let dragIndex = this.data.dragIndex;
let targetImageIndex = this.data.targetImageIndex;
console.log(dragIndex)
console.log(targetImageIndex)
let imageList = this.data.imageList;
if (dragIndex !== null && targetImageIndex !== null) {
if (targetImageIndex < 0) {
targetImageIndex = 0
}
if (targetImageIndex >= imageList.length) {
targetImageIndex = imageList.length - 1
}
console.log(dragIndex)
console.log(targetImageIndex)
//交换图片
if (dragIndex !== targetImageIndex) {
let item = imageList[dragIndex]
imageList[dragIndex] = imageList[targetImageIndex]
imageList[targetImageIndex] = item
}
}
this.setData({
dragIndex: null,
targetImageIndex: null,
deltaLeft: 0,
deltaTop: 0,
showMoveImage: false,
imageList: imageList,
dragIndex: dragIndex,
targetImageIndex: targetImageIndex
})
console.log(this.data.showMoveImage);
// this.$emit('input', this.imageList)
},
getImageList() {
let imageList = this.data.imageList;
console.log(imageList)
this.triggerEvent("getImageList", imageList);
}
},
})
.imageUploadContainer {
padding: 10rpx 5rpx;
margin: 10rpx 5rpx;
}
.dragging {
transform: scale(1.2);
}
.imageUploadList {
display: flex;
flex-wrap: wrap;
}
.imageItem, .imageUpload {
width: 160rpx;
height: 160rpx;
margin: 10rpx;
}
.imageDel {
position: relative;
left: 120rpx;
bottom: 165rpx;
background-color: rgba(0, 0, 0, 0.5);
width: 36rpx;
text-align: center;
line-height: 35rpx;
border-radius: 17rpx;
color: white;
font-size: 30rpx;
padding-bottom: 2rpx;
}
.imageItem image, .moveImage {
width: 160rpx;
height: 160rpx;
border-radius: 8rpx;
}
.imageUpload {
line-height: 130rpx;
text-align: center;
font-size: 150rpx;
color: #d9d9d9;
border: 1px solid #d9d9d9;
border-radius: 8rpx;
}
.moveImage {
position: absolute;
z-index: -1;
}
page {
position: relative;
}
.hide {
display: none;
}
.upload {
text-align: right;
margin-left: 80%;
}
{
"component": true,
"usingComponents": {}
}
附完整的插件
https://download.csdn.net/download/weixin_39608271/12115313