Commit fe3ee7f9 authored by June's avatar June

feat:商品评价

parent 3f3dae48
......@@ -8,6 +8,7 @@
>
<video
v-if="e.type === 'video'"
id="commentVideo"
class="item r-8"
:key="i"
:style="itemSize"
......@@ -62,10 +63,18 @@
},
media: {
type: Array,
default: () => []
required: true
},
controls: {
type: Boolean,
default: false
}
},
mounted() {
this.videoContext = uni.createVideoContext('commentVideo', this) || null
},
computed: {
itemSize() {
const size = this.size
......@@ -75,7 +84,7 @@
methods: {
handlePreview(idx) {
console.log(idx)
this.videoContext && this.videoContext.pause()
uni.previewMedia({
sources: this.media,
current: idx,
......@@ -93,6 +102,7 @@
font-size: 28rpx;
.item {
margin-right: 30rpx;
background-color: $mainBg;
}
}
</style>
......@@ -373,7 +373,6 @@ export default {
.cart-icon {
width: 34rpx;
height: 32rpx;
padding: 0 20rpx;
}
}
}
......
......@@ -22,15 +22,24 @@
<media-view :media="item.media" />
<view
v-if="item.reply.length > 0"
class="reply mt-2"
v-for="(replyItem, index) in item.reply"
:key="index"
>
<view class="mb-2 font-32 font-bold">商家回复:</view>
<view>{{replyItem.content}}</view>
</view>
<template v-if="item.reply.length > 0">
<view
v-for="(replyItem, idx) in item.reply"
:key="idx"
>
<view
class="reply mt-2"
>
<view class="mb-2 font-32 font-bold">商家回复:</view>
<view>{{replyItem.content}}</view>
</view>
<view class="mt-2">
<media-view :media="replyItem.media" />
</view>
</view>
</template>
<view class="descColor font-24 mt-2">{{item.goods_attr}}</view>
</navigator>
......@@ -81,11 +90,12 @@
const { detail, skuData } = data
this.detail = detail
this.skuData = skuData
console.log()
this.getData()
})
this.getData()
},
beforeCreate() {
beforeDestroy() {
this.eventChannel.off('acceptDataFromOpenerPage')
},
......
......@@ -105,24 +105,35 @@
</view>
<!-- 评论 -->
<view class="w-100 comment-wrap mb-2" v-if="firstComment">
<view class="w-100 comment-wrap mb-2">
<view class="mb-4 flex j-between a-center">
<view class="font-bold">商品评论</view>
<view class="font-24 primaryColor flex j-end a-center" @click="handleComment">
<view
v-if="firstComment"
class="font-24 primaryColor flex j-end a-center"
@click="handleComment"
>
<text>查看更多</text>
<i class="ml-2"></i>
<i class="ml-1"></i>
</view>
</view>
<view class="mb-2">
<user :user="firstComment.user" />
</view>
<view class="mb-2">
<words :content="firstComment.content" />
</view>
<media-view :media="firstComment.media" />
<view class="font-24 descColor overtext-1 mt-2">{{firstComment.goods_attr}}</view>
<navigator
hover-class="none"
:url="'/subPages/comments/detail?id=' + firstComment.id"
v-if="firstComment"
>
<view class="mb-2">
<user :user="firstComment.user" />
</view>
<view class="mb-2">
<words :content="firstComment.content" />
</view>
<media-view :media="firstComment.media" />
<view class="font-24 descColor overtext-1 mt-2">{{firstComment.goods_attr}}</view>
</navigator>
<view v-else class="text-center font-28 descColor">暂无用户评论...</view>
</view>
<!-- 详情 -->
<view class="detail-wrap" v-if="detail.goods_desc && detail.goods_desc !== '<p><br></p>'">
<view class="font-28 font-bold text-center py-3" style="background-color: #fff;">商品详情</view>
......
......@@ -117,7 +117,9 @@
@purchase="purchase"
/>
</template>
</block>
<block v-else>
<!-- 综合商品 -->
<template v-if="searchList.length > 0">
<view class="w-100">
......@@ -126,43 +128,45 @@
v-for="(item, index) in searchList"
:key="index"
>
<navigator
class="list-item mb-3 ml-3"
hover-class="none"
v-for="good in item"
:key="good.goods_id"
:url="'/pages/goods/detail?goods_id=' + good.goods_id"
<template
v-for="(search, searchidx) in item"
>
<image
lazy-load
class="goods_cover w-100"
:src="baseUrl + '/' + good.goods_thumb"
mode="aspectFit"
/>
<view class="goods-info flex flex-column j-between">
<view class="title font-28 my-1">{{good.goods_name}}</view>
<view class="flex j-between a-center mt-1 mb-2">
<price
:is_inquiry="good.is_inquiry"
:price="good.shop_price"
/>
<image
class="cart-btn"
@click.stop="handlePop(good)"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
/>
<navigator
class="list-item mb-3 ml-3"
hover-class="none"
v-for="good in item"
:key="good.goods_id"
:url="'/pages/goods/detail?goods_id=' + good.goods_id"
>
<image
lazy-load
class="goods_cover w-100"
:src="baseUrl + '/' + good.goods_thumb"
mode="aspectFit"
/>
<view class="goods-info flex flex-column j-between">
<view class="title font-28 my-1">{{good.goods_name}}</view>
<view class="flex j-between a-center mt-1 mb-2">
<price
:is_inquiry="good.is_inquiry"
:price="good.shop_price"
/>
<image
class="cart-btn"
@click.stop="handlePop(good)"
src="/static/images/common/icon-cart.png"
mode="aspectFit"
/>
</view>
</view>
</view>
</navigator>
</navigator>
</template>
</block>
</view>
</view>
</template>
</block>
<block v-else>
<empty-view
v-else
iconSrc="/static/images/common/noGoods.png"
text="店铺尚未上架商品"
/>
......@@ -241,15 +245,15 @@ export default {
}
},
mounted() {
const storeInfo = this.storeInfo
if(storeInfo.shop_name) {
// 获取店铺信息
// uni.setNavigationBarTitle({
// title: storeInfo.shop_name
// })
}
},
// mounted() {
// const storeInfo = this.storeInfo
// if(storeInfo.shop_name) {
// // 获取店铺信息
// // uni.setNavigationBarTitle({
// // title: storeInfo.shop_name
// // })
// }
// },
// 下拉刷新
onPullDownRefresh() {
......@@ -428,7 +432,7 @@ export default {
.goods-info {
@include borderBox(0, 20rpx);
height: 180rpx;
background-color: red;
.title {
@include text-ellipsis(2)
}
......
......@@ -40,43 +40,36 @@ image {
.flex-5{ flex: 5; }
/* -- 内外边距 -- */
.m-0 { margin: 0; }
.m-1 { margin: 10rpx; }
.m-2 { margin: 20rpx; }
.m-3 { margin: 30rpx; }
.m-4 { margin: 40rpx; }
.m-5 { margin: 50rpx; }
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 10rpx; }
.mt-2 { margin-top: 20rpx; }
.mt-3 { margin-top: 30rpx; }
.mt-4 { margin-top: 40rpx; }
.mt-5 { margin-top: 50rpx; }
.mb-0 { margin-bottom: 0; }
.mb-1 { margin-bottom: 10rpx; }
.mb-2 { margin-bottom: 20rpx; }
.mb-3 { margin-bottom: 30rpx; }
.mb-4 { margin-bottom: 40rpx; }
.mb-5 { margin-bottom: 50rpx; }
.ml-0 { margin-left: 0; }
.ml-1 { margin-left: 10rpx; }
.ml-2 { margin-left: 20rpx; }
.ml-3 { margin-left: 30rpx; }
.ml-4 { margin-left: 40rpx; }
.ml-5 { margin-left: 50rpx; }
.mr-0 { margin-right: 0; }
.mr-1 { margin-right: 10rpx; }
.mr-2 { margin-right: 20rpx; }
.mr-3 { margin-right: 30rpx; }
.mr-4 { margin-right: 40rpx; }
.mr-5 { margin-right: 50rpx; }
.my-0 { margin-top: 0; margin-bottom: 0; }
.my-1 { margin-top: 10rpx; margin-bottom: 10rpx; }
.my-2 { margin-top: 20rpx; margin-bottom: 20rpx; }
.my-3 { margin-top: 30rpx; margin-bottom: 30rpx; }
.my-4 { margin-top: 40rpx; margin-bottom: 40rpx; }
.my-5 { margin-top: 50rpx; margin-bottom: 50rpx; }
.mx-0 { margin-left: 0; margin-right: 0; }
.mx-1 { margin-left: 10rpx; margin-right: 10rpx; }
.mx-2 { margin-left: 20rpx; margin-right: 20rpx; }
.mx-3 { margin-left: 30rpx; margin-right: 30rpx; }
......
......@@ -28,18 +28,19 @@
<view
v-for="(temp, tidx) in unCommentList"
:key="tidx"
@click="handleComment"
>
<view
class="list-item w-100 p-2 r-8"
v-for="(unComment, i) in temp"
:key="i"
>
<view class="font-32 font-bold mb-2">{{unComment.shop_name}}</view>
<!-- 专属无多店铺 -->
<!-- <view class="font-32 font-bold mb-2">{{unComment.shop_name}}</view> -->
<view
class="w-100 flex j-start a-center"
class="goodsItem w-100 flex j-start a-center"
v-for="(goods, goods_idx) in unComment.goods"
:key="goods_idx"
@click="nav('goods', goods.goods_id)"
>
<image
class="cover mr-2 r-8"
......@@ -48,12 +49,12 @@
/>
<view class="info flex-1 flex j-between a-start flex-column">
<view class="title font-bold">{{goods.goods_name}}</view>
<rate
<!-- <rate
readonly
size="0"
margin="2"
value="0"
/>
/> -->
<view class="w-100 flex j-between a-center">
<view class="descColor font-24">{{goods.goods_attr}}</view>
<view
......@@ -61,6 +62,7 @@
:data-listidx="tidx"
:data-commentdix="i"
:data-goodsidx="goods_idx"
@click.stop="handleComment"
>评价</view>
</view>
</view>
......@@ -83,19 +85,19 @@
<view
v-for="(temp, tidx) in hadCommentList"
:key="tidx"
@click="handleAddComment"
>
<view
class="list-item w-100 p-2 r-8"
v-for="(hadComment, i) in temp"
:key="i"
>
<view class="font-32 font-bold mb-2">{{hadComment.shop_name}}</view>
<!-- <view class="font-32 font-bold mb-2">{{hadComment.shop_name}}</view> -->
<view
v-for="(goods, goods_idx) in hadComment.goods"
:key="goods_idx"
@click.stop="nav('goods', goods.goods_id)"
>
<view class="w-100 flex j-start a-center">
<view class="goodsItem w-100 flex j-start a-center">
<image
class="cover mr-2 r-8"
:src="baseUrl + '/' + goods.goods_thumb"
......@@ -107,7 +109,7 @@
readonly
size="12"
margin="2"
:value="goods.grade"
:value="goods.com_grade"
/>
<view class="descColor font-24">{{goods.goods_attr}}</view>
</view>
......@@ -118,11 +120,12 @@
<view class="mt-2"
v-for="(replyItem, r_idx) in goods.goods_comment"
:key="r_idx"
@click.stop="nav('comment', replyItem.id)"
>
<view class="mb-2">
<words :content="replyItem.content" />
</view>
<view class="mb-2">
<view class="mb-2" v-if="replyItem.media && replyItem.media.length > 0">
<media-view :media="replyItem.media" />
</view>
<view class="font-24 descColor mb-2" v-if="goods.comment_type === '2'">
......@@ -135,7 +138,7 @@
<view class="reply-content">
<words :content="'商家回复:' + b_reply.content" />
</view>
<view class="mt-2" v-if="b_reply.img_url.length > 0">
<view class="mt-2" v-if="b_reply.media.length > 0">
<media-view :media="b_reply.media" />
</view>
</view>
......@@ -147,6 +150,7 @@
:data-listidx="tidx"
:data-commentdix="i"
:data-goodsidx="goods_idx"
@click.stop="handleAddComment"
>追评</view>
</view>
<view class="font-24 descColor" v-if="goods.comment_type === '3'">感谢您的用心评价!</view>
......@@ -167,9 +171,10 @@
import rate from '@/components/rate/index.vue'
import mediaView from '@/components/comments/media-view.vue'
import words from '@/components/comments/words.vue'
import { unCommentList, hadCommentList } from '@/apis/comment.js'
import { unCommentList, hadCommentList, uncommentNum } from '@/apis/comment.js'
import LoadMore from '@/utils/load-more.js'
import { resetCommentData, debounce } from '@/utils/common.js'
// 1可追评 2已评论已追评 3已超时
export default {
data() {
......@@ -188,31 +193,37 @@
words
},
onLoad(ops) {
const { unCommentCounts } = ops
this.unCommentCounts = unCommentCounts || 0
},
created() {
this.unCommendLoad = new LoadMore()
this.hadCommendLoad = new LoadMore()
},
onShow() {
const cur_tab = this.cur_tab
if(cur_tab === 0) {
this.unCommendLoad.resetParams()
this.unCommentList = []
} else if(cur_tab === 1){
this.hadCommendLoad.resetParams()
this.hadCommentList = []
}
this.getList()
this.pageShowRefresh()
},
methods: {
pageShowRefresh() {
const cur_tab = this.cur_tab
if(cur_tab === 0) {
this.unCommendLoad.resetParams()
this.unCommentList = []
} else if(cur_tab === 1){
this.hadCommendLoad.resetParams()
this.hadCommentList = []
}
this.getList()
this.getCommentNum()
},
async getList() {
try{
const { cur_tab } = this
if(cur_tab === 0) {
const { status, data } = await this.unCommendLoad.getList({}, unCommentList)
if(status && data && data.length > 0) {
this.unCommentCounts = this.unCommendLoad.total
this.$set(this.unCommentList, this.unCommentList.length, data)
}
} else {
......@@ -261,6 +272,24 @@
this.hadCommentList = []
}
this.getList()
this.getCommentNum()
},
nav(type, id) {
switch(type) {
case 'goods':
uni.navigateTo({
url: `/pages/goods/detail?goods_id=${id}`
})
break;
case 'comment':
uni.navigateTo({
url: `/subPages/comments/detail?id=${id}`
})
break;
default:
break;
}
},
// 评价
......@@ -285,7 +314,16 @@
res.eventChannel.emit('comment_event', { item, type: 'add' })
}
})
}, 1000)
}, 1000),
// 获取待评论数量
getCommentNum() {
uncommentNum()
.then(res => {
this.unCommentCounts = res.data.count
})
.catch(err => console.log(err))
}
}
}
</script>
......@@ -337,10 +375,17 @@
box-sizing: border-box;
background-color: #fff;
margin-bottom: 20rpx;
.goodsItem {
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
.cover {
flex: 0 0 180rpx;
width: 180rpx;
height: 180rpx;
background-color: $mainBg;
}
.info {
height: 180rpx;
......
......@@ -17,7 +17,7 @@
<view class="font-32 font-bold mr-2">商品评分</view>
<rate
:readonly="type === 'add'"
:value.sync="form.com_grade || 1"
:value.sync="form.com_grade"
size="17"
margin="15"
/>
......@@ -67,8 +67,8 @@
<view class="w-100 mb-4">
<view class="w-100 flex j-between a-center">
<view class="font-32 font-bold">服务评价</view>
<view class="flex a-center" @click="form.anonymity = ~~!form.anonymity">
<view class="font-32 font-bold">{{type === 'add' ? '' : '服务评价'}}</view>
<view class="flex a-center as-end" @click="form.anonymity = ~~!form.anonymity">
<view :class="form.anonymity ? 'icon-unSelect' : 'icon-select'"></view>
<text class="ml-2 font-24 descColor">匿名评价</text>
</view>
......@@ -177,6 +177,8 @@
from: 1,
anonymity: 0 // 1 不匿名 0匿名
}
this.imgTemp = []
this.videoTemp = ''
const form = this.form
this.commentData = {...item}
form.og_id = item.og_id
......@@ -211,7 +213,7 @@
const result = res.map(item => item.data.path)
const fullPathResult = result.map(item => (`${this.baseUrl}/${item}`))
this.imgTemp = [...this.imgTemp, ...fullPathResult]
this.form.img_url = [...this.imgTemp, ...result]
this.form.img_url = [...this.form.img_url, ...result]
})
.catch((err) => console.log(err) && this.$toast({title: '上传失败'}))
.finally(() => {
......@@ -255,16 +257,18 @@
}
},
validateForm() {
validateForm(valiteData) {
const formValidator = new Validator()
const form = this.form
formValidator.add(form.og_id, [{strategy: 'notEmpty', errorMsg: '商品id不能为空'}])
formValidator.add(form.content, [{strategy: 'notEmpty', errorMsg: '评论内容不能为空'}])
formValidator.add(valiteData.og_id, [{strategy: 'notEmpty', errorMsg: '商品id不能为空'}])
formValidator.add(valiteData.content, [{strategy: 'notEmpty', errorMsg: '评论内容不能为空'}])
return formValidator.validate()
},
handleSubmit: debounce(function() {
const validateErr = this.validateForm()
const form = this.form
form.content = form.content.replace(/\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff]/ig, "[表情]")
// console.log(form.content)
const validateErr = this.validateForm(form)
if(validateErr) return this.$toast({title: validateErr})
this.$modal({
content: '提交后无法修改,请确认不含隐私信息再提交噢~',
......@@ -282,10 +286,10 @@
case 'add':
const { status: addStatus, data: addData } = await addComment(this.form)
if(!addStatus) return this.$toast({title: '评论失败'})
// uni.navigateTo({
// url: '/subPages/comments/success?id=' + addData.id
// })
this.$toast({title: '追评成功', cb: () => uni.navigateBack()})
uni.navigateTo({
url: '/subPages/comments/success?id=' + addData.id
})
// this.$toast({title: '追评成功', cb: () => uni.navigateBack()})
break;
default:
break;
......@@ -310,6 +314,7 @@
.cover {
width: 110rpx;
height: 110rpx;
background-color: $mainBg;
}
.goods {
height: 110rpx;
......
......@@ -14,7 +14,7 @@
</view>
<!-- 评论 -->
<view class="comment mt-4">{{detail[0].goods.content}}</view>
<view class="comment mt-4">{{detail[0].content}}</view>
<template v-for="(media, idx) in detail[0].media">
<!-- video -->
......@@ -38,14 +38,14 @@
/>
</template>
<template v-if="detail[0].add_data.past_day > 0">
<view class="primaryColor font-32 font-bold">{{detail[0].add_data.past_day}}天后追</view>
<template v-if="detail[0].add_data.content">
<view class="primaryColor font-32 font-bold mt-2">{{detail[0].add_data.past_day}}天后追评</view>
<view class="comment-add my-2">{{detail[0].add_data.content}}</view>
<!-- video -->
<video
v-if="detail[0].add_data.video_url"
v-if="detail[0].add_data.video_url.url"
class="comment-video mt-4 mb-2 r-8"
:src="detail[0].add_data.video_url"
:src="detail[0].add_data.video_url.url"
:controls="controls"
:autoplay="false"
:show-play-btn="false"
......@@ -53,10 +53,10 @@
<!-- imgs -->
<image
v-for="(img, idx) in detail[0].add_data.img_url"
:key="item"
v-for="(addimg, add_idx) in detail[0].add_data.img_url"
:key="add_idx"
class="comment-img r-8"
:src="img.url"
:src="addimg.url"
mode="widthFix"
/>
</template>
......@@ -64,7 +64,7 @@
<view class="merchant-comment" v-if="detail[0].reply.length > 0">
<template v-for="(reply, ridx) in detail[0].reply">
<view class="comment" :key="ridx">
<view class="comment mb-2" :key="ridx">
<view class="font-bold font-32 mb-2">商家回复:</view>
<view>{{reply.content}}</view>
</view>
......@@ -73,7 +73,7 @@
<video
v-if="reply.video_url"
class="w-100 mt-2 r-8"
:src="reply.video_url"
:src="reply.video_url.url"
:controls="controls"
:autoplay="false"
:show-play-btn="false"
......@@ -88,6 +88,35 @@
mode="widthFix"
/>
</template>
<template v-if="detail[0].add_data.reply.length > 0">
<template v-for="(reply, ridx) in detail[0].add_data.reply">
<view class="comment my-2" :key="ridx">
<view class="font-bold font-32 mb-2">商家回复追评:</view>
<view>{{reply.content}}</view>
</view>
<!-- video -->
<video
v-if="reply.video_url"
class="w-100 mt-2 r-8"
:src="reply.video_url.url"
:controls="controls"
:autoplay="false"
:show-play-btn="false"
/>
<!-- imgs -->
<image
v-for="(img, idx) in reply.img_url"
:key="item"
class="w-100 mt-2 r-8"
:src="img.url"
mode="widthFix"
/>
</template>
</template>
</view>
</view>
</template>
......@@ -99,6 +128,7 @@
export default {
data() {
return {
controls: true,
detail: []
}
},
......
......@@ -8,7 +8,7 @@
</view>
<!-- title -->
<view class="my-2 ml-3">心情不错,继续评价</view>
<view class="my-2 ml-3" v-if="list.length > 0">心情不错,继续评价</view>
<!-- list -->
<view class="wrap-list" @click="handleComment">
......
......@@ -140,7 +140,7 @@ export function cWx(wxapi, ops = {}, cops = {}) {
})
}
// 初始化评论的数据格式
// 初始化评论的数据格式 评论详情,评论中心和评论页面都用到这个方法 我日
export function resetCommentData(data) {
if(isObeject(data)) {
data = [{
......@@ -151,13 +151,13 @@ export function resetCommentData(data) {
let media = []
let reply = null
let add_data = null
if(item.img_url) {
if(item.img_url && item.img_url !== 'null') {
media = [...item.img_url.split(',').map(item => ({
url: `${baseUrl}/${item}`,
tpye: 'image'
type: 'image'
}))]
}
if(item.video_url) {
if(item.video_url && item.video_url !== 'null') {
media.unshift({
url: `${baseUrl}/${item.video_url}`,
type: 'video'
......@@ -166,13 +166,12 @@ export function resetCommentData(data) {
reply = item.reply ? item.reply.map(r => {
const videos = r.video_url && {
url: `${baseUrl}/${r.video_url}`,
tpye: 'video'
type: 'video'
} || null
const imgs = r.img_url && r.img_url.split(',').map(url => ({
const imgs = (r.img_url && r.img_url !== 'null' ) ? r.img_url.split(',').map(url => ({
url: `${baseUrl}/${url}`,
tpye: 'image'
})) || null
console.log(imgs)
type: 'image'
})) : []
let r_media = []
r_media = [...imgs]
if(videos) {
......@@ -192,12 +191,35 @@ export function resetCommentData(data) {
past_day: item.past_day,
video_url: item.add_data.video_url && {
url: `${baseUrl}/${item.add_data.video_url}`,
tpye: 'video'
type: 'video'
},
img_url: item.add_data.img_url && item.add_data.img_url.split(',').map(url => ({
reply: item.add_data.reply ? item.add_data.reply.map(r => {
const videos = r.video_url && {
url: `${baseUrl}/${r.video_url}`,
type: 'video'
} || null
const imgs = (r.img_url && r.img_url !== 'null') ? r.img_url.split(',').map(url => ({
url: `${baseUrl}/${url}`,
type: 'image'
})) : []
let r_media = []
r_media = [...imgs]
if(videos) {
r_media.unshift(videos)
}
return {
content: r.content,
user_name: r.user_name,
video_url: videos,
img_url: imgs,
// ri
media: r_media
}
}) : null,
img_url: (item.add_data.img_url && item.add_data.img_url !== 'null') ? item.add_data.img_url.split(',').map(url => ({
url: `${baseUrl}/${url}`,
tpye: 'image'
}))
type: 'image'
})) : []
} : null
return {
user: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment