Files
xdd-uniapp-new/pagesShop/shop/GoodsEvaluate/index.vue
T
2026-05-12 15:19:37 +08:00

259 lines
7.4 KiB
Vue

<template>
<view class="evaluate-con">
<view
v-if="isTravelGroup && travelOrderInfo && travelOrderInfo.travelGroupOrderInfo && travelOrderInfo.travelGroupOrderInfo.travelGroupProduct"
class="goodsStyle acea-row row-between"
>
<view class="pictrue">
<image :src="travelOrderInfo.travelGroupOrderInfo.travelGroupProduct.mainImage" class="image"/>
</view>
<view class="text acea-row row-between">
<view class="name line2">{{ travelOrderInfo.travelGroupOrderInfo.travelGroupProduct.name }}</view>
<view class="money">
<view>{{ travelOrderInfo.travelGroupOrderInfo.travelGroupProduct.price }}</view>
<view class="num">x1</view>
</view>
</view>
</view>
<view
v-else-if="orderCon.productInfo"
class="goodsStyle acea-row row-between"
>
<view class="pictrue">
<image :src="orderCon.productInfo.image" class="image"/>
</view>
<view class="text acea-row row-between">
<view class="name line2">{{ orderCon.productInfo.storeName }}</view>
<view class="money">
<view>{{ orderCon.productInfo.price }}</view>
<view class="num">x{{ orderCon.cartNum }}</view>
</view>
</view>
</view>
<view class="score">
<view
v-for="(item, scoreListIndexw) in scoreList"
:key="scoreListIndexw"
class="item acea-row row-middle"
>
<view>{{ item.name }}</view>
<view class="starsList">
<text
v-for="(itemn, starsIndexn) in item.stars"
:key="starsIndexn"
:class="item.index >= starsIndexn ? 'icon-shitixing font-color-red' : 'icon-kongxinxing'"
class="iconfont"
@click="stars(starsIndexn, scoreListIndexw)"
/>
</view>
<text class="evaluate">{{ item.index === -1 ? "" : item.index + 1 + "分" }}</text>
</view>
<view class="textarea">
<textarea
v-model="expect"
placeholder="商品满足你的期待么?说说你的想法,分享给想买的他们吧~"
:maxlength="140"
/>
<view class="v12-px-4 v12-font-24 v12-dark1-text v12-mb-3">{{ expect.length || 0 }} / 140</view>
<view class="upload-title">
添加视频/图片
<text class="txt">
({{ videoArr.length + picArr.length }}/9)
</text>
</view>
<view class="upload-wrapper">
<view v-show="picArr.length < 9" class="video-upload">
<tm-upload
:upload_img_wh="uploadImgWH"
:upload_max="1"
:upload_count="1"
:url="uploadUrl"
:header="uploadHeader"
type='video'
@change="uploadedVideoChange"
/>
</view>
<view class="pic-upload">
<tm-upload
:upload_img_wh="uploadImgWH"
:upload_max="9 - videoArr.length"
:upload_count="9 - videoArr.length"
:url="uploadUrl"
:header="uploadHeader"
:showBlankPlaceholder="picArr.length !== 9"
type='image'
@change="uploadedPicChange"
/>
</view>
</view>
</view>
<view class="evaluateBnt bg-color-red" @click="submit">立即评价</view>
</view>
</view>
</template>
<script>
import { postOrderComment, postOrderProduct } from '@/api/store'
import { fetchSojoumOrderDetail, sojoumOrderComment } from '@/api/sojoumOrder'
import { trim } from '@/utils'
import { required } from '@/utils/validate'
import { validatorDefaultCatch } from '@/utils/dialog'
import tmUpload from '@/components/tm-upload/tm-upload.vue'
import {
VUE_APP_API_URL
} from '@/config'
export default {
name: 'GoodsEvaluate',
components: {
tmUpload
},
props: {},
data: function () {
return {
uploadUrl: VUE_APP_API_URL + '/api/upload',
uploadImgWH: (750 - 3 * 16 - 2 * 32 - 16) / 3.0,
uploadHeader: {
Authorization: "Bearer " + this.$store.getters.token
},
orderCon: {
cartProduct: {
productInfo: {}
}
},
isTravelGroup: false,
travelOrderInfo: null,
scoreList: [
{
name: '商品质量',
stars: ['', '', '', '', ''],
index: -1
},
{
name: '服务态度',
stars: ['', '', '', '', ''],
index: -1
}
],
uploadPictures: [],
expect: '',
unique: '',
picArr: [],
videoArr: []
}
},
mounted() {
this.unique = this.$yroute.query.id
this.isTravelGroup = this.$yroute.query.isTravelGroup === '1'
if (this.isTravelGroup) {
this.getTravelOrderDetail()
} else {
this.getOrderProduct()
}
},
methods: {
getTravelOrderDetail() {
fetchSojoumOrderDetail({ key: this.unique }).then(res => {
this.travelOrderInfo = res.data
})
},
getOrderProduct() {
postOrderProduct(this.unique).then(res => {
this.orderCon = res.data
})
},
stars: function (indexn, indexw) {
this.scoreList[indexw].index = indexn
},
uploadedVideoChange(uploadList) {
this.videoArr = uploadList
},
uploadedPicChange(uploadList) {
this.picArr = uploadList
},
async submit() {
const expect = trim(this.expect).substring(0, 140)
const product_score = this.scoreList[0].index + 1 === 0 ? "" : this.scoreList[0].index + 1
const service_score = this.scoreList[1].index + 1 === 0 ? "" : this.scoreList[1].index + 1
try {
await this.$validator({
product_score: [
required('请选择商品质量分数', {
type: 'number'
})
],
service_score: [
required('请选择服务态度分数', {
type: 'number'
})
]
}).validate({
product_score,
service_score
})
} catch (e) {
return validatorDefaultCatch(e)
}
const pics = this.picArr
const video = this.videoArr[0] || ''
const request = this.isTravelGroup
? sojoumOrderComment({
orderId: this.unique,
comment: expect,
pics,
video,
productScore: product_score,
serviceScore: service_score
})
: postOrderComment({
productScore: product_score,
serviceScore: service_score,
unique: this.unique,
pics: this.picArr.join(','),
comment: expect,
video: this.videoArr.join(',')
})
request.then(() => {
uni.showToast({
title: '评价成功',
icon: 'success',
duration: 2000
})
this.$yrouter.back()
}).catch(err => {
uni.showToast({
title: err.msg || err.response.data.msg || err.response.data.message,
icon: 'none',
duration: 2000
})
})
}
}
};
</script>
<style scoped lang="less">
.upload-title {
padding: 0 0 20rpx 16rpx;
.txt {
color: #999;
font-size: 22rpx;
}
}
.upload-wrapper {
position: relative;
padding: 0 0 0 16rpx;
.video-upload {
position: absolute;
top: 0;
left: 16rpx;
z-index: 5;
}
.pic-upload {
position: relative;
z-index: 2;
}
}
.evaluate-con .score .textarea .list .pictrue.uploadBnt {
border: 1px solid #ddd;
}
</style>