516 lines
11 KiB
Vue
516 lines
11 KiB
Vue
<template>
|
||
<view class="page">
|
||
<u-navbar title="店铺点评" :border-bottom="false" :background="bgc" back-icon-color="#262B37" title-color='#262B37'
|
||
title-size='36' height='46' id="navbar">
|
||
</u-navbar>
|
||
<view class="top">
|
||
<view class="search-container">
|
||
<view class="search-bar" style="padding-left: 30rpx;">
|
||
<u-icon name="search" size="28" color="#999"></u-icon>
|
||
<input class="search-input" placeholder="搜索关键词,搜索相关点评" v-model="searchKeyword" @confirm="sendReply"/>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="paixu">
|
||
<view class="lt">
|
||
<view class="px">
|
||
<text :class="pxindex == 0 ? 'active' : ''" @click="btnpx(0)">默认排序</text>
|
||
</view>
|
||
<view class="px" style="border: none;">
|
||
<text :class="pxindex == 1 ? 'active' : ''" @click="btnpx(1)">最新评论</text>
|
||
</view>
|
||
</view>
|
||
<view class="rt" v-if="bqname">
|
||
共{{total}}条
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view class="listpl" @scrolltolower="handqixing" scroll-y>
|
||
<view class="yonghu" v-for="(item,index) in plarr" :key="index">
|
||
<view class="top">
|
||
<view class="lt">
|
||
<image :src="item.userAvatar" mode="aspectFill"></image>
|
||
<view class="info">
|
||
<view class="name">
|
||
{{item.nickName}}
|
||
</view>
|
||
<u-rate :count="count" active-color="#E7322C" size="24" inactive-color="#b2b2b2" v-model="item.rating"></u-rate>
|
||
</view>
|
||
</view>
|
||
<view class="rts">
|
||
{{item.createTime}}
|
||
</view>
|
||
</view>
|
||
<view class="contxt">
|
||
{{item.content}}
|
||
</view>
|
||
<view class="imglist" v-if="item.mediaUrl">
|
||
<view class="" v-for="(val,index2) in getMediaList(item.mediaUrl)" :key="index2">
|
||
<image v-if="!isVideoItem(val)" :src="val" mode="aspectFill" @click="previewImage(item.mediaUrl, index2)" />
|
||
<video v-else :src="val" :controls="true" @click="playVideo(val)"></video>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="" style="width: 100%;text-align: center;margin-top: 20rpx;color: #ccc;">
|
||
暂时没有更多评论了...
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 视频全屏播放弹窗 -->
|
||
<view class="video-modal" v-if="showVideoModal" @click="closeVideoModal">
|
||
<view class="video-container" @click.stop>
|
||
<video :src="currentVideoUrl" :controls="true" :show-center-play-btn="true" class="fullscreen-video"></video>
|
||
<view class="close-btn" @click="closeVideoModal">×</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
bgc: {
|
||
backgroundColor: "#fff",
|
||
},
|
||
rating:3,
|
||
count:5,
|
||
obj:{},
|
||
pageNum:1,
|
||
id:'',
|
||
havePicOrVideo:false,
|
||
plarr:[],
|
||
tabindex:0,
|
||
pxindex:0,
|
||
maxRating:'',
|
||
searchKeyword:'',
|
||
bqlist:[],
|
||
bqindex:-1,
|
||
bqname:'',
|
||
total:0,
|
||
time_desc:'',
|
||
showVideoModal: false,
|
||
currentVideoUrl: ''
|
||
}
|
||
},
|
||
onLoad(e) {
|
||
this.id = e.id
|
||
this.getxq()
|
||
this.getpinlun()
|
||
this.getbiaoqian()
|
||
},
|
||
methods: {
|
||
// 请求店铺详情(用于评分汇总)
|
||
getxq(){
|
||
this.$u.get(`/app/store/detail/${this.id}`).then(res =>{
|
||
if(res.code == 200){
|
||
this.obj = res.data
|
||
}
|
||
})
|
||
},
|
||
// 上拉加载更多
|
||
handqixing() {
|
||
if (this.plarr.length < this.total) {
|
||
this.getpinlun()
|
||
}
|
||
},
|
||
// 点击切换标签
|
||
btnbq(item,index){
|
||
if(item.name == this.bqname){
|
||
this.bqname = ''
|
||
this.bqindex = -1
|
||
this.pageNum = 1
|
||
this.getpinlun()
|
||
}else{
|
||
this.bqname = item.name
|
||
this.bqindex = index
|
||
this.pageNum = 1
|
||
this.getpinlun()
|
||
}
|
||
},
|
||
// 请求店铺评价标签(bstType=2)
|
||
getbiaoqian(){
|
||
this.$u.get(`/app/comment/labelList?bstId=${this.id}&bstType=2`).then(res =>{
|
||
if(res.code == 200){
|
||
this.bqlist = res.data
|
||
}
|
||
})
|
||
},
|
||
// 点击回车进行搜索
|
||
sendReply(){
|
||
this.pageNum = 1
|
||
this.getpinlun()
|
||
},
|
||
// 获取媒体列表(过滤空值)
|
||
getMediaList(mediaUrl) {
|
||
if (!mediaUrl) return []
|
||
return mediaUrl.split(',').map(url => url.trim()).filter(url => url)
|
||
},
|
||
// 判断图片还是视频
|
||
isVideoItem(item) {
|
||
if (!item) return false
|
||
const url = String(item).trim()
|
||
return /\.(mp4|m4v|mov|avi|wmv|flv|m3u8)(\?|#|$)/i.test(url)
|
||
},
|
||
// 预览图片
|
||
previewImage(mediaUrl, currentIndex) {
|
||
if (!mediaUrl) {
|
||
uni.showToast({
|
||
title: '图片加载失败',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
const allUrls = mediaUrl.split(',').map(url => url.trim()).filter(url => url)
|
||
if (allUrls.length === 0) {
|
||
uni.showToast({
|
||
title: '没有可预览的图片',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
const urls = allUrls.filter(url => !this.isVideoItem(url)).map(url => url.trim())
|
||
if (urls.length === 0) {
|
||
uni.showToast({
|
||
title: '没有可预览的图片',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
// 计算当前点击的图片在过滤后的图片数组中的索引
|
||
let imageIndex = 0
|
||
for (let i = 0; i < currentIndex && i < allUrls.length; i++) {
|
||
if (!this.isVideoItem(allUrls[i])) {
|
||
imageIndex++
|
||
}
|
||
}
|
||
const current = urls[imageIndex] || urls[0]
|
||
uni.previewImage({
|
||
urls: urls,
|
||
current: current || urls[0],
|
||
fail: (err) => {
|
||
console.error('预览图片失败:', err)
|
||
uni.showToast({
|
||
title: '图片预览失败',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
})
|
||
},
|
||
// 播放视频
|
||
playVideo(videoUrl) {
|
||
if (!videoUrl) {
|
||
uni.showToast({
|
||
title: '视频加载失败',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
this.currentVideoUrl = videoUrl
|
||
this.showVideoModal = true
|
||
},
|
||
// 关闭视频弹窗
|
||
closeVideoModal() {
|
||
this.showVideoModal = false
|
||
this.currentVideoUrl = ''
|
||
},
|
||
// 点击切换排序
|
||
btnpx(num){
|
||
this.pxindex = num
|
||
if(num == 1){
|
||
this.time_desc = 'time_desc'
|
||
this.pageNum = 1
|
||
this.getpinlun()
|
||
}else{
|
||
this.time_desc = ''
|
||
this.pageNum = 1
|
||
this.getpinlun()
|
||
}
|
||
},
|
||
// 点击切换tab
|
||
btntab(num){
|
||
this.tabindex = num
|
||
this.pageNum = 1
|
||
this.bqname = ''
|
||
this.bqindex = -1
|
||
if(num == 1){
|
||
this.havePicOrVideo = true
|
||
this.maxRating = ''
|
||
this.getpinlun()
|
||
}else if(num == 2){
|
||
this.havePicOrVideo = false
|
||
this.maxRating = 3
|
||
this.getpinlun()
|
||
}else{
|
||
this.havePicOrVideo = false
|
||
this.maxRating = ''
|
||
this.getpinlun()
|
||
}
|
||
},
|
||
// 请求店铺评价列表(类型 2)
|
||
getpinlun(){
|
||
this.$u.get(`/app/comment/list?pageNum=${this.pageNum}&pageSize=20&bstTypes=2&bstId=${this.id}&havePicOrVideo=${this.havePicOrVideo}&maxRating=${this.maxRating}&keyword=${this.searchKeyword}&types=${this.bqname}&sortBy=${this.time_desc}`).then(res =>{
|
||
if(res.code == 200){
|
||
this.total = res.total
|
||
if(this.pageNum == 1){
|
||
this.plarr = res.rows
|
||
this.pageNum ++
|
||
}else{
|
||
this.plarr =this.plarr.concat(res.rows)
|
||
this.pageNum ++
|
||
}
|
||
}
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less">
|
||
.active{
|
||
color: #1EC28B !important;
|
||
}
|
||
.actives{
|
||
color: #fff !important;
|
||
background-color: #1EC28B !important;
|
||
}
|
||
page {
|
||
background: #F4F4F4;
|
||
}
|
||
.top{
|
||
background-color: #fff;
|
||
}
|
||
.listpl{
|
||
height: 57vh;
|
||
overflow: scroll;
|
||
padding-bottom: 20rpx;
|
||
box-sizing: border-box;
|
||
.yonghu{
|
||
width: 712rpx;
|
||
max-height: 6458rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||
margin: auto;
|
||
padding: 36rpx 20rpx;
|
||
margin-top: 32rpx;
|
||
.qb{
|
||
font-size: 28rpx;
|
||
color: #3D3D3D;
|
||
margin-top: 28rpx;
|
||
width: 100%;
|
||
text-align: center;
|
||
}
|
||
.imglist{
|
||
margin-top: 28rpx;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10rpx;
|
||
view{
|
||
image{
|
||
width: 210rpx;
|
||
height: 210rpx;
|
||
border-radius: 14rpx 14rpx 14rpx 14rpx;
|
||
}
|
||
video{
|
||
width: 210rpx;
|
||
height: 210rpx;
|
||
border-radius: 14rpx 14rpx 14rpx 14rpx;
|
||
}
|
||
}
|
||
}
|
||
.contxt{
|
||
font-size: 28rpx;
|
||
color: #3D3D3D;
|
||
margin-top: 22rpx;
|
||
}
|
||
.top{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
.lt{
|
||
display: flex;
|
||
align-items: center;
|
||
image{
|
||
width: 68rpx;
|
||
height: 68rpx;
|
||
border-radius: 50%;
|
||
margin-right: 14rpx;
|
||
}
|
||
.info{
|
||
.name{
|
||
font-weight: 600;
|
||
font-size: 28rpx;
|
||
color: #3D3D3D;
|
||
padding-left: 0;
|
||
}
|
||
}
|
||
}
|
||
.rts{
|
||
font-size: 28rpx;
|
||
color: #606060;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.paixu{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-top: 24rpx;
|
||
padding: 0 32rpx;
|
||
.lt{
|
||
display: flex;
|
||
.px{
|
||
border-right: 1px solid #D8D8D8;
|
||
padding-right: 14rpx;
|
||
margin-right: 14rpx;
|
||
}
|
||
view{
|
||
font-size: 30rpx;
|
||
color: #3D3D3D;
|
||
}
|
||
}
|
||
}
|
||
.shuaixuan{
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
padding: 20rpx 32rpx;
|
||
box-sizing: border-box;
|
||
gap: 10rpx;
|
||
justify-content: space-between;
|
||
view{
|
||
background: #ECEEFA;
|
||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||
padding: 12rpx 32rpx;
|
||
font-size: 24rpx;
|
||
color: #1EC28B;
|
||
}
|
||
}
|
||
.tab{
|
||
margin-top: 36rpx;
|
||
display: flex;
|
||
border-bottom: 1px solid #D8D8D8;
|
||
padding-bottom: 16rpx;
|
||
padding-left: 32rpx;
|
||
view{
|
||
margin-right: 56rpx;
|
||
font-size: 30rpx;
|
||
color: #3D3D3D;
|
||
text{
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
}
|
||
.pinfen {
|
||
width: 710rpx;
|
||
max-height: 3746rpx;
|
||
background: #FFFFFF;
|
||
border-radius: 16rpx 16rpx 16rpx 16rpx;
|
||
padding: 0rpx 32rpx;
|
||
box-sizing: border-box;
|
||
.top {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
.rt {
|
||
display: flex;
|
||
align-items: center;
|
||
border-left: 1px solid #D8D8D8;
|
||
.oen {
|
||
margin-left: 42rpx;
|
||
.fen {
|
||
font-size: 32rpx;
|
||
color: #1EC28B;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
font-size: 20rpx;
|
||
color: #606060;
|
||
}
|
||
}
|
||
.lt {
|
||
display: flex;
|
||
align-items: center;
|
||
.ltfen {
|
||
font-weight: 600;
|
||
font-size: 64rpx;
|
||
color: #1EC28B;
|
||
margin-right: 14rpx;
|
||
}
|
||
.ltbang {
|
||
text {
|
||
font-size: 20rpx;
|
||
color: #606060;
|
||
display: block;
|
||
}
|
||
.bang {
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
color: #1EC28B;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 搜索栏样式
|
||
.search-container {
|
||
padding: 20rpx 30rpx;
|
||
background: #fff;
|
||
}
|
||
.search-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
background: #F5F5F5;
|
||
border-radius: 25rpx;
|
||
height: 68rpx;
|
||
padding: 0 8rpx;
|
||
}
|
||
.search-input {
|
||
flex: 1;
|
||
margin: 0 20rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
// 视频全屏播放弹窗
|
||
.video-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.9);
|
||
z-index: 9999;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
.video-container {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
.fullscreen-video {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
.close-btn {
|
||
position: absolute;
|
||
top: 40rpx;
|
||
right: 40rpx;
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
background-color: rgba(0, 0, 0, 0.6);
|
||
border-radius: 50%;
|
||
color: #fff;
|
||
font-size: 48rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 10000;
|
||
}
|
||
}
|
||
}
|
||
</style>
|
||
|