jiuyiUniapp/jiuyi2/components/index/commentArea.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>