492 lines
12 KiB
Vue
492 lines
12 KiB
Vue
<script setup>
|
|
/**
|
|
* 视频评论弹窗
|
|
*/
|
|
import {
|
|
onMounted,
|
|
ref,
|
|
reactive,
|
|
getCurrentInstance,
|
|
watch,
|
|
defineExpose,
|
|
computed,
|
|
onBeforeUnmount,
|
|
} from 'vue'
|
|
// util
|
|
import util from '@/common/js/util.js'
|
|
// api
|
|
import api from '@/api/index.js'
|
|
|
|
const {
|
|
proxy
|
|
} = getCurrentInstance()
|
|
// 当前视频对象
|
|
let detail = reactive({})
|
|
// 评论内容
|
|
let content = ref('')
|
|
// 加载
|
|
const showLoad = ref(true)
|
|
// 列表属性
|
|
let listProperty = reactive({
|
|
data: [],
|
|
pageSize: 10,
|
|
pageNum: 1,
|
|
total: 0,
|
|
})
|
|
// 回复的对象
|
|
const reply = reactive({})
|
|
// 输入框为空时占位符
|
|
const placeholder = computed(() => {
|
|
let result = '评论一下吧~'
|
|
if (reply.id) result = `回复 @${reply.nickName}`
|
|
return result
|
|
})
|
|
// 填充高度
|
|
const paddingHeight = ref(0)
|
|
// 用户信息
|
|
const userinfo = computed(() => uni.$store.state.userinfo || {})
|
|
|
|
onMounted(() => {
|
|
//
|
|
uni.onKeyboardHeightChange((rs) => {
|
|
paddingHeight.value = rs.height
|
|
})
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
try {
|
|
uni.offKeyboardHeightChange(() => {});
|
|
} catch (error) {
|
|
console.error('Error onBeforeUnmount', error);
|
|
}
|
|
})
|
|
|
|
// 刷新列表
|
|
function refreshList() {
|
|
console.log('refreshList')
|
|
listProperty.total = 0
|
|
listProperty.pageNum = 1
|
|
getList()
|
|
}
|
|
|
|
// 获取评论列表
|
|
function getList() {
|
|
//
|
|
api.video.getcomment({
|
|
data: {
|
|
videoId: detail.id,
|
|
parentId: 0,
|
|
pageSize: listProperty.pageSize,
|
|
pageNume: listProperty.pageNum,
|
|
}
|
|
}).then(rs => {
|
|
console.log('commentList', rs)
|
|
if (rs.code == 200) {
|
|
if (listProperty.pageNum == 1) listProperty.data.length = 0
|
|
listProperty.data.push(...rs.rows.map(item => {
|
|
// 条数
|
|
item.pageSize = 10
|
|
// 页码
|
|
item.pageNum = 0
|
|
// 子评论
|
|
item.child = []
|
|
// 用户头像
|
|
item.formatUserPortrait = util.format_url(item.userPortrait, 'img')
|
|
// 展开子评论 true展开 false收起
|
|
item.childShow = true
|
|
return item
|
|
}))
|
|
|
|
listProperty.total = rs.total
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
}).finally(() => {
|
|
// 关闭加载
|
|
showLoad.value = false
|
|
})
|
|
}
|
|
|
|
// 发布评论
|
|
function handleSubmit() {
|
|
if (!content.value) {
|
|
util.alert('请输入评论的内容')
|
|
return
|
|
}
|
|
|
|
//
|
|
api.video.savecomment({
|
|
data: {
|
|
// 评论的一级id
|
|
parentId: reply.childrenParentId || 0,
|
|
// 视频id
|
|
videoId: detail.id,
|
|
// 评论内容
|
|
content: content.value,
|
|
// 用户id
|
|
userId: userinfo.value.id,
|
|
// 评论的父id
|
|
childrenParentId: reply.id || 0,
|
|
}
|
|
}).then(rs => {
|
|
console.log('saveComment', rs)
|
|
if (rs.code == 200) {
|
|
proxy.$refs.comment.close()
|
|
// 刷新列表
|
|
refreshList()
|
|
setTimeout(() => {
|
|
// 清空
|
|
content.value = ''
|
|
}, 500)
|
|
// 修改被评论的视频数据
|
|
uni.$emit('updateVideo', {
|
|
...detail,
|
|
...rs.data,
|
|
})
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 打开弹窗
|
|
* @param {Object} item 当前视频对象
|
|
*/
|
|
function open(item) {
|
|
if (detail.id != item.id) {
|
|
Object.assign(detail, {}, item)
|
|
// 刷新列表
|
|
refreshList()
|
|
}
|
|
|
|
proxy.$refs.commentArea.open()
|
|
}
|
|
|
|
// 关闭弹窗
|
|
function close() {
|
|
proxy.$refs.commentArea.close()
|
|
}
|
|
|
|
/**
|
|
* 回复对象
|
|
* @param {Object} item 回复的评论对象
|
|
* @param {Object} childrenParentId 评论的一级id
|
|
*/
|
|
function handleReply(item, childrenParentId) {
|
|
Object.assign(reply, item)
|
|
reply.childrenParentId = childrenParentId
|
|
proxy.$refs.comment.open()
|
|
}
|
|
|
|
// 打开评论对象
|
|
function showComment() {
|
|
reply.id = ''
|
|
proxy.$refs.comment.open()
|
|
}
|
|
|
|
/**
|
|
* 展开剩余评论
|
|
* @param {Object} item 当前项
|
|
* @param {Number} index 当前项下标
|
|
*/
|
|
function handleExpansion(item, index) {
|
|
// 子评论总数
|
|
let childrenCommentCount = item.childrenCommentCount
|
|
// 子评论总长
|
|
let childLength = item.child.length
|
|
// 如果状态为收起 展开全部
|
|
if (item.childShow == false) {
|
|
item.childShow = true
|
|
return
|
|
}
|
|
|
|
// 如果数据全部加载完毕
|
|
if ((childLength >= childrenCommentCount) && item.childShow) {
|
|
item.childShow = false
|
|
return
|
|
}
|
|
|
|
item.pageNum++
|
|
// 获取子评论
|
|
getLevelCommentList(item, index)
|
|
}
|
|
|
|
/**
|
|
* 获取子评论
|
|
* @param {Object} item 当前项
|
|
* @param {Number} index 当前项下标
|
|
*/
|
|
function getLevelCommentList(item, index) {
|
|
//
|
|
api.video.getcomment({
|
|
data: {
|
|
// 视频id
|
|
videoId: item.videoId,
|
|
// 父节点id
|
|
parentId: item.id,
|
|
pageSize: item.pageSize,
|
|
pageNum: item.pageNum,
|
|
}
|
|
}).then(rs => {
|
|
console.log('getcomment', rs)
|
|
if (rs.code == 200) {
|
|
// 追加子列表
|
|
listProperty.data[index].child.push(...rs.rows.map(node => {
|
|
return node
|
|
}))
|
|
// 展示列表
|
|
item.childShow = true
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 评论点赞
|
|
* @param {Object} item 视频对象
|
|
* @param {Object} index 一级下标
|
|
* @param {Object} secIndex 二级下标
|
|
*/
|
|
function handleLike(item, index, secIndex) {
|
|
util.isLogin().then(rs => {
|
|
//
|
|
api.video.likecomment({
|
|
data: {
|
|
// 0取消 1点赞
|
|
likeType: {
|
|
'0': '1',
|
|
'1': '0',
|
|
} [item.likeType],
|
|
// 评论id
|
|
id: item.id,
|
|
// 视频id
|
|
videoId: detail.id,
|
|
}
|
|
}).then(rs => {
|
|
if (rs.code == 200) {
|
|
// 点赞
|
|
let obj = {
|
|
...item,
|
|
...rs.data,
|
|
}
|
|
|
|
// 如果是一级
|
|
if (secIndex == undefined) {
|
|
listProperty.data.splice(index, 1, obj)
|
|
}
|
|
// 如果是二级
|
|
else {
|
|
listProperty.data[index].child.splice(secIndex, 1, obj)
|
|
}
|
|
//
|
|
listProperty.data = JSON.parse(JSON.stringify(listProperty.data))
|
|
return
|
|
}
|
|
util.alert({
|
|
content: rs.msg,
|
|
showCancel: false,
|
|
})
|
|
})
|
|
}).catch(() => {
|
|
uni.navigateTo({
|
|
url: '/pages/login/loginPhone'
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 去用户主页
|
|
* @param {Object} user
|
|
*/
|
|
function toUser(user) {
|
|
uni.navigateTo({
|
|
url: util.setUrl('/pages/index/videoHome', {
|
|
userId: user.userId,
|
|
}),
|
|
})
|
|
}
|
|
|
|
//
|
|
defineExpose({
|
|
open,
|
|
close,
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<!-- 评论区 -->
|
|
<uni-popup ref="commentArea" type="bottom">
|
|
<view class="commentAreaAlt popBot bfff">
|
|
<view class="showLoad fmid ptb30" v-if="showLoad">
|
|
<uni-icons type="spinner-cycle"></uni-icons>
|
|
<text class="c666 f28">加载中...</text>
|
|
</view>
|
|
|
|
<view class="listBox" v-else>
|
|
<scroll-view scroll-y class="scroll plr20" :show-scrollbar="false">
|
|
<view class="list ptb40">
|
|
<view class="item mtb20" v-for="(item,index) in listProperty.data" :key="index">
|
|
<view class="df fdr">
|
|
<!-- 头像 -->
|
|
<image class="wh70 cir" :src="item.headPortrait" mode="aspectFill"
|
|
@click="toUser(item)" />
|
|
|
|
<view class="col ml20 f1">
|
|
<!-- 用户信息和点赞 -->
|
|
<view class="df fdr">
|
|
<view class="f1">
|
|
<text class="c666 f24" @click="toUser(item)">{{item.nickName}}</text>
|
|
<text class="mt5 c333 f28">{{item.content}}</text>
|
|
</view>
|
|
|
|
<view class="like oh aic pl20" @click="handleLike(item,index)">
|
|
<uni-icons type="heart-filled"
|
|
:color="item.likeType == 0 ? '#F84259' : '#b3b3b3'" size="32rpx" />
|
|
<text class="c333 f24">{{item.likeCount}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 发布时间和回复 -->
|
|
<view class="df fdr mt10">
|
|
<text class="c999 f24">{{item.createTime}}</text>
|
|
<view class="ml100" @click="handleReply(item,item.id)">
|
|
<text class="c666 f24">回复</text>
|
|
</view>
|
|
</view>
|
|
|
|
<template v-if="item.childrenCommentCount != 0">
|
|
<!-- 子评论 -->
|
|
<view class="child" v-if="item.childShow">
|
|
<view class="df fdr mt15" v-for="(secItem,secIndex) in item.child"
|
|
:key="secItem.id">
|
|
<!-- 头像 -->
|
|
<image class="wh40 cir" :src="secItem.headPortrait" mode="aspectFill"
|
|
@click="toUser(secItem)" />
|
|
|
|
<view class="col pl20 f1">
|
|
<!-- 用户信息和点赞 -->
|
|
<view class="df fdr">
|
|
<view class="f1">
|
|
<view class="fdr aic">
|
|
<text class="c333 f24"
|
|
@click="toUser(secItem)">{{secItem.nickName}}</text>
|
|
<template
|
|
v-if="secItem.childrenParentId != secItem.parentId">
|
|
<text class="mlr10 c333 f24">回复</text>
|
|
<text
|
|
class="c333 f24">{{secItem.replyUserName}}</text>
|
|
</template>
|
|
</view>
|
|
<text class="mt5 c333 f28">{{secItem.content}}</text>
|
|
</view>
|
|
|
|
<view class="like oh aic pl20"
|
|
@click="handleLike(secItem,index,secIndex)">
|
|
<uni-icons type="heart-filled"
|
|
:color="secItem.likeType == 0 ? '#F84259' : '#b3b3b3'"
|
|
size="32rpx" />
|
|
<text class="c333 f24">{{secItem.likeCount}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 发布时间和回复 -->
|
|
<view class="df fdr mt10">
|
|
<text class="c999 f24">{{secItem.createTime}}</text>
|
|
<text class="ml100 c666 f24"
|
|
@click="handleReply(secItem,item.id)">回复</text>
|
|
</view>
|
|
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="df fdr aic mt20" @click="handleExpansion(item,index)">
|
|
<view class="line mr10"></view>
|
|
|
|
<template v-if="item.childShow">
|
|
<template v-if="item.childrenCommentCount == item.child.length">
|
|
<text class="c666 f24">收起</text>
|
|
<uni-icons type="top" />
|
|
</template>
|
|
<template v-else>
|
|
<text
|
|
class="c666 f24">展开{{item.childrenCommentCount - item.child.length}}条回复</text>
|
|
<uni-icons type="bottom" />
|
|
</template>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<text class="c666 f24">展开{{item.childrenCommentCount}}条回复</text>
|
|
<uni-icons type="bottom" />
|
|
</template>
|
|
</view>
|
|
</template>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="fmid fdr" v-if="!listProperty.data[0]">
|
|
<text class="nomore f32">暂无评论,快来抢沙发吧~</text>
|
|
</view>
|
|
<view class="fmid fdr" v-else>
|
|
<text class="nomore">暂无更多</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="inputArea ptb20 plr20" @click="showComment">
|
|
<view class="inputBox ptb10 plr10">
|
|
<text class="placeholderStyle f28">评论一下吧~</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
|
|
<!-- 回复弹窗 -->
|
|
<uni-popup ref="comment" type="bottom">
|
|
<view class="popBot ptb30 plr30 bfff">
|
|
<textarea v-model="content" :adjust-position="false" class="textarea c333" :placeholder="placeholder" />
|
|
|
|
<view class="df fdr jcr">
|
|
<view class="btn sm black plr20" @click="handleSubmit">
|
|
<text class="cfff f28">发送</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view :style="{height: paddingHeight + 'px',}"></view>
|
|
</view>
|
|
</uni-popup>
|
|
</template>
|
|
.0
|
|
<style lang="scss" scoped>
|
|
// 弹窗
|
|
.commentAreaAlt {
|
|
|
|
.listBox .scroll {
|
|
height: 1000rpx;
|
|
}
|
|
|
|
//
|
|
.line {
|
|
width: 40px;
|
|
border-bottom: 2rpx solid #D8D8D8;
|
|
}
|
|
|
|
// 评论
|
|
.inputArea {
|
|
box-shadow: 0px 8px 20px 0px rgba(0, 0, 0, .3);
|
|
}
|
|
}
|
|
</style> |