1.先来看需求分析,一个订单下的多个商品的评论说明了在一个订单中点击评论按钮直接跳转到评论页面中,同时渲染订单下的三个商品,如下图所示:
并且要实现在不同的商品评论下输入的评论内容互不影响,这就对第一次做该业务的人来说有点小困难,反正当时我是头都大了。但是别急,没你想象中的那么困难,在我实现了该功能之后其实也就在我原有代码的基础上做了一点点修改。下面来看一下思路:
1.对订单商品信息数据循环并且添加新新的字段,评论内容需要什么类型的字段就添加什么类型的字段。在我的需求中评论需要的是---文字内容和图片,所以就设置了一个字符串类型的字段和一个数组类型的字段用来存储输入的图片。
that.goodsData = res
that.goodsData.forEach((item,index)=>{
that.$set(item,'content','');
that.$set(item,'imgs',[]);
that.$set(item,'upimgs',[])
that.$set(item,'rateValue','')
})
2.循环订单商品信息数据,并将新增的字段作为数据字段绑定给输入的内容和图片
<scroll-view scroll-y="true" >
<view class="" v-for="(items,index) in goodsData" :key="index" @tap="Tap(index)">
<view class="goods-content">
<image class="store-image" :src="items.imgUrl" mode=""></image>
<view class="goods-text">
<text>{{items.goods_name}}</text>
<uni-rate v-model="items.rateValue" @change="onChange" />
</view>
</view>
<textarea name="" v-model="items.content" id="" cols="30" rows="10" class="review-content" placeholder="输入您的感受,可以帮助到其他小伙伴哦~"></textarea>
<view class="uni-uploader-body">
<view class="" style="color: #ccc; font-size: 26rpx;margin-left: 20rpx;">
<text>最多上传3张图片</text>
</view>
<view class="uni-uploader__files">
<block v-for="(image,id) in items.imgs" :key="id">
<view class="uni-uploader__file" style="position: relative;">
<!-- 删除的图标以及删除的 delimage方法传递的参数 -->
<uni-icons @tap="delimage(index,id)" class="del" size="20" type="clear"></uni-icons>
<image ref="files" class="uni-uploader__img" :src="image" :data-src="image" @tap="previewImage(index,id)"></image>
</view>
</block>
<view v-show="imageList.length < 3" class="uni-uploader__input-box">
<view class="uni-uploader__input" @tap="chooseImage(items,index)"></view>
</view>
</view>
</view>
<Lines/>
</view>
</scroll-view>
3.在上传请求上传后端时,循环商品信息数据并且将其内需要上传的数据赋值给一个新对象内的值,最后将这个对象作为数据传递到后端,待后端解析写入数据库
let that = this
let goodsArr = []
this.goodsData.forEach((item)=>{
let good = {
headImg:that.userInfo.imgUrl, //用户头像
userName:that.userInfo.userName,//用户姓名
comment:item.content,//评论内容
goods_id:item.shopId,//商品id
orderId:item.order_id,//订单号
eval_img:JSON.stringify(item.upimgs),//评论图片数组
type:item.type //商品类型
}
goodsArr.push(good)
})
全体代码
<template>
<view class="content">
<scroll-view scroll-y="true" >
<view class="" v-for="(items,index) in goodsData" :key="index" @tap="Tap(index)">
<view class="goods-content">
<image class="store-image" :src="items.imgUrl" mode=""></image>
<view class="goods-text">
<text>{{items.goods_name}}</text>
<uni-rate v-model="items.rateValue" @change="onChange" />
</view>
</view>
<textarea name="" v-model="items.content" id="" cols="30" rows="10" class="review-content" placeholder="输入您的感受,可以帮助到其他小伙伴哦~"></textarea>
<view class="uni-uploader-body">
<view class="" style="color: #ccc; font-size: 26rpx;margin-left: 20rpx;">
<text>最多上传3张图片</text>
</view>
<view class="uni-uploader__files">
<block v-for="(image,id) in items.imgs" :key="id">
<view class="uni-uploader__file" style="position: relative;">
<!-- 删除的图标以及删除的 delimage方法传递的参数 -->
<uni-icons @tap="delimage(index,id)" class="del" size="20" type="clear"></uni-icons>
<image ref="files" class="uni-uploader__img" :src="image" :data-src="image" @tap="previewImage(index,id)"></image>
</view>
</block>
<view v-show="imageList.length < 3" class="uni-uploader__input-box">
<view class="uni-uploader__input" @tap="chooseImage(items,index)"></view>
</view>
</view>
</view>
<Lines/>
</view>
</scroll-view>
<button @tap="addContent">发布评价</button>
</view>
</template>
<script>
import Lines from '@/components/common/Lines.vue'
import {pathToBase64,base64ToPath} from '../../js_sdk/mmmm-image-tools/index.js'
import $http from '../../common/api/request.js'
import {mapState} from 'vuex'
import {v4 as uuidv4} from 'uuid'
export default {
data() {
return {
// 评论内容
content:'',
// 商品信息数据
goodsData:[],
// 订单页传递过来的数据--订单信息
data:[],
//存储图片路径用于图片展示
imageList: [],
//七牛云的外链
qiniuBucketURLPrefix :'放上自己的云存储外链' ,
//存储外链
partImgUrl:[] ,
// 评分
}
},
components:{
Lines
},
computed:{
...mapState({
userInfo:state=>state.user.userInfo
}),
},
onLoad(e) {
this.data = JSON.parse(e.data)
this.getOrderDetialData(this.data)
},
methods: {
Tap(index){
},
onChange(e) {
console.log('rate发生改变:' + JSON.stringify(e))
// console.log(this.rateValue);
},
getOrderDetialData(data){
let that = this
$http.request({
url:'/getOrderDetialData',
method:'POST',
header:{
token:true
},
data:{
orderId:data.order_id
}
}).then((res)=>{
that.goodsData = res
that.goodsData.forEach((item,index)=>{
that.$set(item,'content','');
that.$set(item,'imgs',[]);
that.$set(item,'upimgs',[])
that.$set(item,'rateValue','')
})
})
},
chooseImage(item,index){
let newIndex = index
var that = this
that.goodsData[newIndex].upimgs = []
uni.chooseImage({
count:3,//最多可以选择的图片张数
sizeType:['compressed'],//original原图 compressed压缩图
sourceType:['album','camera'] ,//album 从相册选图,camera 使用相机
// 成功则返回图片的本地文件路径列表 tempFilePaths
success: (chooseImageRes) => {
that.goodsData[index].imgs.push(...chooseImageRes.tempFilePaths)
// this.imageList.push(...chooseImageRes.tempFilePaths)
const tempFilePaths = chooseImageRes.tempFilePaths;
that.goodsData[index].imgs.forEach((item,index)=>{
$http.request({
url:'/storeToken',
method:'POST'
}).then((res)=>{
// 唯一码
const uuid = uuidv4()
let uploadMsg = res;
let uniqueCode = uuid;
let postUrl = 'http://upload-z2.qiniu.com'
uni.uploadFile({
url:postUrl,
fileType: "image",
filePath:item,
name:'file',
formData:{
'key':uniqueCode.slice(0,10),
'token':uploadMsg
},
// 经过escape()转转义之后的文件名和图片链接一部分一致
success: (uploadFileRes) => {
let key = JSON.parse(uploadFileRes.data).key
let partImgUrl = escape(uniqueCode.slice(0,10));
that.goodsData[newIndex].upimgs.push({
imgUrl : 'http://'+this.qiniuBucketURLPrefix + partImgUrl
});
},
fail: (err) => {
console.log('fail',err);
}
})
}).catch((err)=>{
console.log(err);
})
})
}
})
},
// 删除图片
delimage(index,id){
this.goodsData[index].imgs.splice(id,1)
this.goodsData[index].upimgs.splice(id,1)
},
// 预览图片
previewImage(index,id){
uni.previewImage({
urls:this.goodsData[index].imgs,//需要预览的图片连接列表
current:this.goodsData[index].imgs[id]//当前显示的图片连接
})
},
addContent(){
let that = this
let goodsArr = []
this.goodsData.forEach((item)=>{
let good = {
headImg:that.userInfo.imgUrl, //用户头像
userName:that.userInfo.userName,//用户姓名
comment:item.content,//评论内容
goods_id:item.shopId,//商品id
orderId:item.order_id,//订单号
eval_img:JSON.stringify(item.upimgs),//评论图片数组
type:item.type //商品类型
}
goodsArr.push(good)
})
$http.request({
url:'/addContentData',
method:'POST',
header:{
token:true
},
data:{
goods:goodsArr
}
}).then((res)=>{
uni.showToast({
title:"评价提交成功,即将返回上一页",
icon:'none'
})
let timer = setTimeout(()=>{
uni.navigateBack({
delta: 1
});
clearTimeout(timer)
},2000)
}).catch(()=>{
uni.showToast({
title:"请求失败",
icon:'none'
})
})
}
}
}
</script>
<style scoped>
.flex {
display: flex;
justify-content: center;
align-items: center;
}
.content{
padding: 20rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin-top: 14rpx;
margin-bottom: 80rpx;
}
.review-content{
display: flex;
justify-content: center;
align-items: center;
width: 710rpx;
height: 150rpx;
background-color: #f8f8f8;
}
.imgSrc{
width: 220rpx;
height: 220rpx;
border: 1rpx dashed #ccc;
font-size: 20rpx;
color: #ccc;
margin-top: 20rpx;
margin-right: 15rpx;
}
.select{
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
}
button{
position: fixed;
bottom: 0rpx;
left: 0rpx;
width: 100%;
height: 80rpx;
background-color: #00aaff;
display: flex;
justify-content: center;
align-items: center;
color: white;
}
.del{
position: absolute;
top: 0rpx;
right: 0%;
z-index: 999;
}
.goods-content{
display: flex;
justify-content:flex-start;
align-items: center;
margin-bottom: 20rpx;
}
.store-image{
width: 140rpx;
height: 120rpx;
border-radius: 20rpx;
}
.goods-text{
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: 20rpx;
}
.uni-uploader-body {
background-color: #f8f8f8;
}
</style>