小程序做线上商城就离不开交互,包括最重要的支付和订单评价系统。订单评价简单的只有商品评价,比较齐全的是商品和商家一起评价。
本文介绍的目录包含,商品评价,商家评价,星级评分,上传照片,以及评论字数限制。
目录:
(一)星级评分的写法
(二)评论区的字数显示和限制
(三)图片张数限制和上传到服务器
(四)完整代码
看看开发工具中的样品图:
在评论页中展示商品和商家两栏的评价内容,并且提交评价的时候也要区分开,将商品和商家的评论内容用数组的形式提交。
注意array和[object,object]的数据格式。
先说逻辑,因为两块其实是同一个功能,只不过是把方法名字区分为A和B,A和B的函数内容一样的,只有数据内容不一样。
所以这里是只讲A方法。
(一)先说星级评分方法;
<view class='stars'>
<view class='text'>评分</view>
<view class='star_list'>
<block wx:for="{{stars}}" wx:key>
<image class="star-image" name="defen" value="{{key}}" style="left: {{item*30}}rpx" src="{{key > item ?(key-item == 0?normalSrc:selectedSrc) : normalSrc}}">
<view class="item" style="left:0rpx" data-key="{{item+1}}" bindtap="selectRight"></view>
</image>
</block>
</view>
</view>
用数组来存储图片,wx:for来循环图片列表,五星,列表长度就是0-4总共5,10星则是0-9。
两张图片。一张是带颜色的作为点亮状态,一张是默认的作为默认状态。设置选中函数selectRight。点星星一次则将星星图片的位置从left位移多少个单位到点击的对应位置。反之则取消对应的星星选中。
函数:
//点击右边递增,否则递减,评分,商品+商家B
selectRight (e) {
var key = e.currentTarget.dataset.key; //评分
if (this.data.key == 1 && e.currentTarget.dataset.key == 1) {
//只有一颗星的时候,再次点击,变为0颗
key = 0;
}
this.setData({
key: key
})
},
(二)评论区的字数显示和限制。
方法,给textarea一个最大的length.max-length =300.然后给输入域一个获取输入的事件,bindInput。通过获取bindInput的value长度,来限制。
<view class='textarea'>
<textarea id='advice' name="advice" type="text" maxlength="{{max}}" bindinput="inputs" value="{{advice}}" placeholder="请输入评价内容..." placeholder-class='p_s'></textarea>
<view class='fontNum'>{{fontNum}}</view>
</view>
JS中通过最大长度与输入长度的减法来动态改变fontNum剩余字数。
//字数限制 商品+商家B
inputs (e) {
var value = e.detail.value,
len = parseInt(value.length);
//最多字数限制
if (len > this.data.max) return;
this.setData({
fontNum: 300-len //当前字数
});
},
(三)上传多张图片并发送到服务器
默认的API即可,但是图片地址需要转化。wx.chooseImage所给出的图片地址是本地,并没有存到服务器上,还需要保存到服务器上。
使用wx.request的方法。在回调的结果中,取出地址链接,存为数组或者单个url信息。与其他内容一起进行表单提交。
$uploadFile({
filePath: tempFilePaths[0],
formData: {
evaluateType: 'store'
},
name: 'evaluteImage',
url: 'v4/shop/file/uploadBySmall'
}).then((res) => {
if (res.isSuccess) {
let url = res.resultData
that.setData({
imgboxB: [url],
imgboxB: imgboxB,
})
//$toast('图片上传成功')
} else {
//$toast(res.message)
}
})
(四)完整代码
wxml:
<!--pages/addProComment/addProComment.wxml-->
<form bindsubmit="hrSubmit">
<view class='content'>
<view class='form'>
<view class='stores'>
<image src='{{goodsImg}}'></image>
<view class='stor_t'>{{gooodsName}}</view>
</view>
<view class='stars'>
<view class='text'>评分</view>
<view class='star_list'>
<block wx:for="{{stars}}" wx:key>
<image class="star-image" name="defen" value="{{key}}" style="left: {{item*30}}rpx" src="{{key > item ?(key-item == 0?normalSrc:selectedSrc) : normalSrc}}">
<view class="item" style="left:0rpx" data-key="{{item+1}}" bindtap="selectRight"></view>
</image>
</block>
</view>
</view>
<view class='textarea'>
<textarea id='advice' name="advice" type="text" maxlength="{{max}}" bindinput="inputs" value="{{advice}}" placeholder="请输入评价内容..." placeholder-class='p_s'></textarea>
<view class='fontNum'>{{fontNum}}</view>
</view>
<view class='up-pic'>
<view class='flex pic-box'>
<block wx:key="imgbox" wx:for="{{imgbox}}">
<view class='ap-box'>
<view class='add-pic' name="Pics" value="{{item}}">
<image class='add-pic' src='{{item}}'></image>
<view class='img-de' bindtap="clearPic" data-deindex='{{index}}'>
<image class='img' src='/images/error.png'></image>
</view>
</view>
</view>
</block>
<view class='add-pic add-photo' bindtap="uploadPic" wx:if="{{imgbox.length<4}}">
<image src='../../images/add.png' />
</view>
</view>
</view>
</view>
</view>
<!-- 商家信息 -->
<view class='content' wx:if="{{isTrue}}">
<view class='form'>
<view class='stores'>
<image src='{{goodsImg}}'></image>
<view class='stor_t'>{{storeName}}</view>
</view>
<view class='stars'>
<view class='text'>评分</view>
<view class='star_list'>
<block wx:for="{{starsB}}" wx:key>
<image class="star-image" style="left: {{item*30}}rpx" src="{{keyB > item ?(keyB-item == 0?normalSrc:selectedSrc) : normalSrc}}">
<view class="item" style="left:0rpx" data-key="{{item+1}}" bindtap="selectRightB"></view>
</image>
</block>
</view>
</view>
<view class='textarea'>
<textarea id='advice' name="adviceB" type="text" maxlength="{{max}}" bindinput="inputsB" value="{{adviceB}}" placeholder="请输入评价内容..." placeholder-class='p_s'></textarea>
<view class='fontNum'>{{fontNumB}}</view>
</view>
<view class='up-pic'>
<view class='flex pic-box'>
<block wx:key="imgboxB" wx:for="{{imgboxB}}">
<view class='ap-box'>
<view class='add-pic'>
<image class='add-pic' src='{{item}}'></image>
<view class='img-de' bindtap="clearPicB" data-deindex='{{index}}'>
<image class='img' src='/images/error.png'></image>
</view>
</view>
</view>
</block>
<view class='add-pic add-photo' bindtap="uploadPicB" wx:if="{{imgbox.length<4}}">
<image src='../../images/add.png' />
</view>
</view>
</view>
</view>
</view>
<button class='submit' formType="submit"> 发布 </button>
</form>
WXSS:
page{
background:#F5F5F2;
}
button::after{
border:none;
}
.content{
width:100%;
margin:20rpx 0 0 0;
background:#ffffff;
}
.form{
width:95%;
margin:0 auto;
padding:0 20rpx 0 20rpx;
}
.stores{
width:100%;
display:flex;
align-items: center;
padding-top:30rpx;
padding-bottom:30rpx;
}
.stores image{
width:45px;
height:45px;
border:1px solid #EBEBEB;
}
.stores .stor_t{
font-size:28rpx;
color:#000;
margin-left:30rpx;
}
.stars{
width:100%;
height:40px;
display:flex;
align-items: center;
border-top:1px solid #EBEBEB;
border-bottom:1px solid #EBEBEB;
}
.stars .text{
font-size:30rpx;
flex:1;
}
.stars .star_list{
flex:1;
position:relative;
margin-left:100rpx;
}
.textarea{
width: 100%;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
padding-top:20rpx;
}
.textarea .fontNum{
font-size:30rpx;
line-height:40rpx;
color:#333;
}
.textarea textarea{
-webkit-flex: 1;
flex: 1;
height:240rpx;
font-size:26rpx;
line-height: 42rpx;
text-align: left;
}
.p_s{
font-size:30rpx;
line-height:40rpx;
color:#CCCCCC;
}
.submit {
width: 100%;
height:45px;
margin:0 auto;
margin-top: 25rpx;
background:#00DF8C;
color:#fff;
font-size:32rpx;
line-height:45px;
border-radius:0;
}
.star-image {
position: relative;
width: 30rpx;
height: 30rpx;
}
.item {
position: absolute;
top:0;
width: 30rpx;
height: 30rpx;
}
.flex{
display: flex;
}
.up-pic{
width: 100%;
justify-content: center;
}
.pic-box{
flex-flow:wrap;
width:100%;
}
.ap-box{
position: relative;
width: 150rpx;
height: 150rpx;
margin:0 15rpx 20rpx 10rpx;
}
.add-pic{
width: 150rpx;
height: 150rpx;
position: relative;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5rpx;
}
.add-photo{ margin-bottom:20rpx;border: 1px solid #DDDDDD;}
.add-photo image{
width:100rpx;
height:100rpx;
}
.img-de{
width:45rpx;
height:45rpx;
border-radius:50%;
position:absolute;
right:-30rpx;
top:-15rpx;
z-index:999;
}
.img-de .img {
width:30rpx;
height:30rpx;
}
JS:
// pages/addProComment/addProComment.js
const app = getApp()
const $http = app.$http
const $toast = app.$toast
const $getLocation = app.$getLocation
const setStorage = app.setStorage
const getStorage = app.getStorage
const cdnPath = app.cdnPath
const makePhoneCall = app.makePhoneCall
const $uploadFile = app.$uploadFile
import wxx from '../../utils/wx.js'
import { parseParam } from '../../utils/index.js'
const baseUrl = app.baseUrl
Page({
data: {
cdnPath: cdnPath,
goodsId: '',
gooodsName: '',
storeName: '',
goodsImg: '',
orderSn:'',
openId: '',
memberId: '',
fontNum:300,
fontNumB: 300,
stars: [0, 1, 2, 3, 4],
starsB: [0, 1, 2, 3, 4],
normalSrc: cdnPath+'img/addProcoment/nostar.png',
selectedSrc: cdnPath +'img/addProcoment/star.png',
key: 0,//评分
keyB: 0,//评分
isTrue:true, //是否多个商家
imgbox: '',
imgboxB: ''
},
onLoad (opt) {
if (opt.length == 2){
that.setData({
isTrue: true,
})
}
this.setData({
src: '',
gooodsName: opt.gooodsName,
storeName: opt.storeName,
goodsImg: opt.goodsImage,
goodsId: opt.goodsId,
orderSn: opt.orderSn,
openId: wx.getStorageSync('openId') || '',
memberId: 1000000000243316 //wx.getStorageSync('memberId') || ''
})
},
//点击右边递增,否则递减,评分,商品+商家B
selectRight (e) {
var key = e.currentTarget.dataset.key; //评分
if (this.data.key == 1 && e.currentTarget.dataset.key == 1) {
//只有一颗星的时候,再次点击,变为0颗
key = 0;
}
this.setData({
key: key
})
},
selectRightB (e) {
var keyB = e.currentTarget.dataset.key;
if (this.data.keyB == 1 && e.currentTarget.dataset.keyB == 1) {
keyB = 0;
}
this.setData({
keyB: keyB
})
},
//字数限制 商品+商家B
inputs (e) {
var value = e.detail.value,
len = parseInt(value.length);
//最多字数限制
if (len > this.data.max) return;
this.setData({
fontNum: 300-len //当前字数
});
},
inputsB (e) {
var value = e.detail.value,
len = parseInt(value.length);
if (len > this.data.max) return;
this.setData({
fontNumB: 300 - len
});
},
//发布评论不验证图片
hrSubmit (t) { //提交发布,商品+商家
var d = t.detail.value,
orderSn = this.data.orderSn,
memberId = this.data.memberId,
evaG = JSON.stringify({ evaGoodsInfo: [{ goodsId: this.data.goodsId, evaGoodsGrade: this.data.key, evaGoodsContent: d.advice, evaGoodsImage: this.data.imgbox }]}),
evaS = JSON.stringify({ evaStoreInfo: { evaServiceGrade: this.data.keyB, evaServiceContent: d.adviceB, evaStoreImage: this.data.imgboxB }});
$http({
url: `v4/shop/evaluate/goodsOrStore/${orderSn}/${memberId}`, //{orderSn}/{memberId}
method: 'POST',
data: {
evaGoodsInfo:evaG, //商品评价
evaStoreInfo: evaS, //商家评价
inway:2
}
}).then(response => {
if (response.isSuccess === true) {
$toast('评价成功!')
setTimeout(() => {
wx.navigateTo({ url: '/pages/myOrder/myOrder'})
}, 1000)
}
}).catch((error) => {
console.log(error)
})
},
//上传图片,商品+商家B
uploadPic: function (e) {
var that = this;
var imgbox = this.data.imgbox;
var picid = e.currentTarget.dataset.pic;
var n = 4;
if (4 > imgbox.length > 0) {
n = 4 - imgbox.length;
} else if (imgbox.length == 4) {
n = 1;
}
wx.chooseImage({
count: n, // 默认数量
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
var tempFilePaths = res.tempFilePaths;
if (imgbox.length == 0) {
imgbox = tempFilePaths
} else if (4 > imgbox.length) {
imgbox = imgbox.concat(tempFilePaths);
} else {
imgbox[picid] = tempFilePaths[0];
}
$uploadFile({
filePath: tempFilePaths[0],
formData: {
evaluateType: 'store'
},
name: 'evaluteImage',
url: 'v4/shop/file/uploadBySmall'
}).then((res) => {
if (res.isSuccess) {
let url = res.resultData
that.setData({
imgbox: [url],
imgbox: imgbox,
})
//$toast('图片上传成功')
} else {
//$toast(res.message)
}
})
}
})
},
uploadPicB: function (e) {
var that = this;
var imgboxB = this.data.imgboxB;
var picid = e.currentTarget.dataset.pic;
var n = 4;
if (4 > imgboxB.length > 0) {
n = 4 - imgboxB.length;
} else if (imgboxB.length == 4) {
n = 1;
}
wx.chooseImage({
count: n, // 默认图片数量
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
var tempFilePaths = res.tempFilePaths;
if (imgboxB.length == 0) {
imgboxB = tempFilePaths;
} else if (4 > imgboxB.length) {
imgboxB = imgboxB.concat(tempFilePaths);
} else {
imgboxB[picid] = tempFilePaths[0];
}
$uploadFile({
filePath: tempFilePaths[0],
formData: {
evaluateType: 'store'
},
name: 'evaluteImage',
url: 'v4/shop/file/uploadBySmall'
}).then((res) => {
if (res.isSuccess) {
let url = res.resultData
that.setData({
imgboxB: [url],
imgboxB: imgboxB,
})
//$toast('图片上传成功')
} else {
//$toast(res.message)
}
})
}
})
},
// 上传图片
uploadImgSuccess(res, file, fileList) {
if (res.isSuccess) {
let arr = res.resultData.split('/')
this.data.imageListHD.push(arr[arr.length - 1])
} else {
fileList.splice(-1, 1)
$toast(res.message)
return
}
},
//删除图片
clearPic: function (e) {//删除图片
let that = this;
let index = e.currentTarget.dataset.deindex;
let imgbox = this.data.imgbox;
imgbox.splice(index, 1)
that.setData({
imgbox: imgbox
});
},
clearPicB: function (e) {//删除图片
let that = this;
let index = e.currentTarget.dataset.deindex;
let imgboxB = this.data.imgboxB;
imgboxB.splice(index, 1)
that.setData({
imgboxB: imgboxB
});
},
onShareAppMessage: function () {
}
})
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。