Files
dvcp_v2_wxcp_app/src/apps/AppInfotainment/newsDetail.vue

698 lines
17 KiB
Vue
Raw Normal View History

2022-04-24 14:19:20 +08:00
<template>
<div class="news-detail" v-if="pageShow">
<div class="video" v-if="info.videoFile">
<video :src="info.videoFile.url" :poster="info.coverFile.url"></video>
</div>
<div class="detail-top" :class="[info.videoFile ? 'detail-top__active' : '']">
<h2>{{ info.title }}</h2>
<div class="detail-info">
<div class="left">{{ info.areaName }} {{ info.createTime ? info.createTime.split(' ')[0] : '' }} </div>
<div class="right">
<div class="right-item">
<i class="iconfont">{{ info.videoFile ? '&#xe6f9;' : '&#xe6fc;'}}</i>
<span>{{ info.viewCount }}</span>
</div>
<div class="right-item">
<i class="iconfont" :style="{color: info.nowUserStatus === '0' ? '#C41C19' : '#666'}">&#xe698;</i>
<span :style="{color: info.nowUserStatus === '0' ? '#C41C19' : '#666'}">{{ info.upCount }}</span>
</div>
</div>
</div>
<div class="detail-content" v-if="!info.videoFile">
<!-- <div v-html="info.content" class="articalContent"></div> -->
<!-- <image :src="info.coverFile.url" mode="widthFix" /> -->
<!-- <AiWxparse :imageProp="imageProp" className="articalContent" :content="info.content"/> -->
<!-- <u-parse className="articalContent" :html="info.content"/> -->
</div>
</div>
<div class="detail-comments">
<h2>全部评论({{ commentsTotal }})</h2>
<div class="comments-list">
<div class="item" v-for="(item, index) in commentList" :key="index">
<image :src="item.avatar" />
<div class="item-right">
<div class="item-right__top">
<h2>{{ item.name || '-' }}</h2>
<div class="item-right__top--right" @click="replySuport(item.id, index)">
<i class="iconfont" :style="{color: item.status === '0' ? '#C41C19' : '#666'}">&#xe698;</i>
<span :style="{color: item.status === '0' ? '#C41C19' : '#666'}">{{ item.supportedQuantity }}</span>
</div>
</div>
<div class="item-right__content">{{ item.content }}</div>
<div class="item-right__info">
<span>{{ item.name }} {{ item.commentTime.substring(0, 10)}} </span>
<i @click="reply(item.id, item.name)">回复TA</i>
</div>
<div class="item-replay" v-if="item.secondComments.length">
<div class="item-replay__item" v-for="(reply, i) in item.secondComments" :key="i" v-if="i < 2 || item.isShow === '1'">
<h3>{{ reply.name }}: </h3>
<span>{{ reply.content }}</span>
</div>
<div class="item-replay__more" v-if="item.secondComments.length > 2 && item.isShow !== '1'" @click="showMore(index)">
查看全部{{ item.secondComments.length }}条回复 >
</div>
</div>
</div>
</div>
<div class="no-more" v-if="!commentList.length">
<image src="https://cdn.cunwuyun.cn/img/Empty.png" />
<p>暂无评论</p>
</div>
</div>
</div>
<AiTransSpeech :src="info.speech"></AiTransSpeech>
<div class="footer-bar">
<input
:cursor-spacing="10"
:placeholder="focus ? '' : '我来说两句…'"
@confirm="onConfirm"
confirm-type="send"
:focus="focus"
:disabled="true"
@click="showComments"
@blur="focus = false, placeholder = '', commentId = ''">
<div class="footer-bar__right flex1">
<div class="count flex1" v-if="info.type === '0'">
<img src="https://cdn.cunwuyun.cn/components/comment/pinglun.png" alt="" class="icon-img">
<span>{{ commentsTotal }}</span>
</div>
<div class="flex1" v-if="info.type === '0'">
<img src="https://cdn.cunwuyun.cn/components/comment/tabdz.png" alt="" class="icon-img" @click="suport">
</div>
<button class="flex1" v-if="info.type === '0'" open-type="share" style="text-align: center">
<img src="https://cdn.cunwuyun.cn/components/comment/tabfx.png" alt="" class="icon-img">
</button>
<div class="video-item" v-if="info.type === '1'" @click="suport" :style="{color: info.nowUserStatus === '0' ? '#C41C19' : '#666'}">
<img src="https://cdn.cunwuyun.cn/components/comment/tabdz.png" alt="" class="icon-img">
<span></span>
</div>
<button open-type="share" class="video-item" v-if="info.type === '1'">
<img src="https://cdn.cunwuyun.cn/components/comment/tabfx.png" alt="" class="icon-img">
<span>分享</span>
</button>
</div>
</div>
<div class="comments" v-if="isShowComment" mode="bottom" @close="focus = false" :closeable="false">
<div class="mask" @click="isShowComment = false"></div>
<div class="comments-wrapper" :style="{bottom: bottom + 'px'}">
<div class="textarea">
<textarea
placeholder="我来说两句…"
:focus="focus"
:maxlength="1000"
fixed
@keyboardheightchange="keyboardheightchange"
:adjust-position="false"
:show-confirm-bar="false"
v-model="commnet">
</textarea>
<div class="textarea-bottom">
<span></span>
<div>字数{{ commnet.length }}/1000</div>
</div>
</div>
<div class="comments-bottom">
<span @click="commnet = ''">清空内容</span>
<div @click="onConfirm">发表</div>
</div>
</div>
</div>
<ai-login ref="login"></ai-login>
</div>
</template>
<script>
import {mapState} from 'vuex'
// import AiLogin from '@/components/AiLogin/AiLogin'
export default {
name: 'newsDetail',
computed: {
...mapState(['token'])
},
components: {
// AiLogin
},
data () {
return {
isShowComment: false,
info: {},
imageProp: {
mode: 'widthFix',
padding: 0,
lazyLoad: false,
domain: ''
},
bottom: 0,
placeholder: '',
pageShow: false,
commnet: '',
commentList: [],
commnetId: '',
areaId: '',
focus: false,
current: 0,
isMore: false,
commentsTotal: 0
}
},
onLoad (params) {
this.$loading()
this.id = params.id
this.areaId = params.areaId
this.type = params.type
this.$nextTick(() => {
this.getDetail()
this.getComments()
})
},
methods: {
login() {
this.$refs.login.show()
},
keyboardheightchange (e) {
this.bottom = e.detail.height
},
showComments () {
if(!this.token) {
this.login()
return false
}
this.commnetId = ''
this.isShowComment = true
setTimeout(() => {
this.focus = true
}, 500)
},
reply (id, name) {
if(!this.token) {
this.login()
return false
}
this.isShowComment = true
this.commentId = id
setTimeout(() => {
this.focus = true
}, 800)
},
showMore (index) {
this.$set(this.commentList[index], 'isShow', '1')
},
suport() {
this.$loading()
this.$instance.post('/app/appnewscenterinfo/suportFree?id=' + this.id).then(res => {
this.$hideLoading()
if (res.code === 0) {
this.$set(this.info, 'upCount', this.info.upCount + 1)
this.$set(this.info, 'nowUserStatus', '0')
this.$toast('点赞成功')
}
})
},
replySuport (id, index) {
this.$loading()
this.$instance.post('/app/appnewscentercommenthot/suportFree', {
commentId: id,
status: this.commentList[index].status === '0' ? '1' : '0'
}).then(res => {
this.$hideLoading()
if (res.code === 0) {
this.$set(this.commentList[index], 'supportedQuantity', this.commentList[index].supportedQuantity + 1)
this.$set(this.commentList[index], 'status', '0')
this.$toast('点赞成功')
}
})
},
getDetail() {
var url = '/app/appnewscenterinfo/queryDetailByIdForWx?id=' + this.id
if(this.type == 5) { //旅游故事
url = '/app/appcountrysidetourism/queryDetailByIdForWX?id=' + this.id
}
this.$instance.post(url).then(res => {
this.$hideLoading()
if (res.code === 0) {
this.info = res.data
this.$hideLoading()
this.$nextTick(() => {
this.pageShow = true
})
}
})
},
onConfirm () {
if (!this.commnet) {
return this.$toast('评论不能为空')
}
this.$loading()
this.$instance.post('/app/appnewscentercomment/addOrUpdateForWX', {
circleId: this.id,
content: this.commnet,
type: this.commentId ? 2 : 1,
commentId: this.commentId,
name: uni.getStorageSync('userInfo').nickName,
areaId: this.areaId
}).then(res => {
this.$hideLoading()
if (res.code === 0) {
this.commnet = ''
this.$toast(this.commentId ? '回复成功' : '评论成功')
this.current = 0
this.isMore = false
this.getComments()
this.commentId = ''
this.placeholder = ''
} else {
this.commentId = ''
this.placeholder = ''
this.$toast(res.msg)
}
this.isShowComment = false
}).catch(() => {
this.commentId = ''
this.placeholder = ''
this.$hideLoading()
})
},
getComments() {
this.$instance.post('/app/appnewscentercomment/listForWX?size=5&circleId=' + this.id + '&current=' + (this.current + 1)).then(res => {
if (res.code === 0) {
this.commentsTotal = res.data.total
if (this.current === 0) {
this.commentList = []
}
if (!res.data.records.length) {
this.isMore = true
this.isLoading = false
this.$nextTick(() => {
this.pageShow = true
})
return false
}
const data = res.data.records.map(item => {
item.isShow = '0'
return item
})
this.commentList.push(...data)
this.current = this.current + 1
}
})
}
},
onReachBottom () {
this.getComments()
},
onShareAppMessage () {
return {
title: this.info.title,
imageUrl: this.info.coverFile.url,
path: `/subPages/live/newsDetail?id=${this.id}&areaId=${this.$areaId}`
}
}
}
</script>
<style lang="scss">
.news-detail {
padding-bottom: 120rpx;
div {
box-sizing: border-box;
}
.comments {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1111;
.mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
}
}
.comments-wrapper {
position: absolute;
bottom: 0;
z-index: 1;
width: 100%;
padding: 32rpx 32rpx 16rpx;
background: #FFFFFF;
.textarea {
position: relative;
width: 100%;
margin-bottom: 24rpx;
padding: 16rpx;
background: #F7F7F7;
border-radius: 8px;
textarea {
width: 100%;
height: 94rpx;
color: #666;
font-size: 26rpx;
}
.textarea-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx;
color: #999999;
font-size: 26rpx;
}
}
.comments-bottom {
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 16rpx;
span {
color: #666666;
font-size: 26rpx;
}
div {
width: 144rpx;
height: 64rpx;
line-height: 64rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
background: #135AB8;
border-radius: 32rpx;
}
}
}
.icon-img{
width: 32rpx;
height: 32rpx;
margin-right: 8rpx;
}
.video-item {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
color: #666;
font-size: 28rpx;
i {
padding-right: 4rpx;
}
}
.detail-top__active {
padding-top: 30rpx;
h2 {
margin-bottom: 28rpx;
}
}
.video {
width: 100%;
height: 396rpx;
video {
display: block;
width: 100%;
height: 396rpx;
}
}
}
.no-more {
margin-top: 20rpx;
text-align: center;
color: #999;
image {
width: 400rpx;
height: 240rpx;
}
p {
text-align: center;
color: #999;
font-size: 28rpx;
}
}
.detail-top {
padding: 10rpx 30rpx 26rpx;
background: #fff;
& > h2 {
margin-bottom: 40rpx;
color: #333333;
font-size: 40rpx;
}
.detail-info {
display: flex;
align-items: center;
justify-content: space-between;
color: #333333;
font-size: 24rpx;
.right {
display: flex;
align-items: center;
& > div {
display: flex;
align-items: center;
&:first-child {
margin-right: 60rpx;
}
}
i {
margin-right: 10rpx;
font-size: 32rpx;
}
}
}
.detail-content {
margin-top: 46rpx;
image {
display: block;
width: 100%;
height: 400rpx;
margin: 0 auto;
}
}
}
.detail-comments {
margin-top: 20rpx;
padding: 0 30rpx 20rpx;
background: #fff;
& > h2 {
padding-top: 16rpx;
font-size: 30rpx;
color: #333333;
}
.comments-list {
.item {
display: flex;
margin-top: 35px;
image {
flex-shrink: 1;
width: 50rpx;
height: 50rpx;
border-radius: 50%;
margin-right: 22rpx;
}
.item-right {
flex: 1;
.item-right__top {
display: flex;
justify-content: space-between;
height: 50rpx;
.item-right__top--right {
display: flex;
align-items: center;
padding-left: 20rpx;
i {
margin-right: 10rpx;
color: #666;
font-size: 28rpx;
}
span {
color: #333333;
font-size: 24rpx;
}
}
}
.item-right__content {
line-height: 46rpx;
color: #333333;
font-size: 28rpx;
text-align: justify;
}
.item-right__info {
display: flex;
align-items: center;
margin: 10rpx 0;
span {
margin-right: 20rpx;
color: #999999;
font-size: 24rpx;
}
i {
color: #333333;
font-size: 24rpx;
}
}
.item-replay {
padding: 30rpx;
background: #F0F0F0;
.item-replay__item {
display: flex;
line-height: 1.3;
margin-bottom: 10rpx;
h3 {
color: #333333;
font-size: 26rpx;
font-weight: 600;
}
span {
font-size: 26rpx;
}
}
.item-replay__more {
color: #999999;
font-size: 26rpx;
}
}
}
}
}
}
.footer-bar {
display: flex;
position: fixed;
align-items: center;
justify-content: space-between;
bottom: 0;
left: 0;
width: 100%;
height: 100rpx;
padding: 0 30rpx;
box-sizing: border-box;
border-top: 1rpx solid rgba(0, 0, 0, 0.2);
background: #fff;
input {
width: 460rpx;
height: 58rpx;
background: #F0F0F0;
border-radius: 30rpx;
font-size: 26rpx;
text-align: center;
}
.footer-bar__right {
display: flex;
align-items: center;
i {
font-size: 30rpx;
color: #666;
}
.count {
position: relative;
text-align: right;
span {
position: absolute;
top: -18rpx;
right: -11rpx;
z-index: 21;
padding: 3rpx 7rpx;
font-size: 20rpx;
color: #fff;
border-radius: 12rpx;
background: #C41C19;
}
}
.count, & > i {
margin-right: 40rpx;
}
button {
padding: 0!important;
font-size: 26rpx!important;
color: #666!important;
line-height: 1!important;
background: transparent!important;
&::after {
border: none;
}
&:last-child {
border-right: none;
}
}
}
}
</style>