Files
tra-app/src/pages/courseDetail/components/comment.vue
T
2025-07-10 21:32:22 +08:00

414 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="comment_div">
<view class="empty_message_div" v-if="message_list.length == 0">
<image class="img" src="@/static/images/courseDetail/empty_message.png"></image>
</view>
<!-- message_list -->
<view class="message_div" v-for="(item,index) in message_list">
<view class="head_div">
<image-preview v-if="item.userIconImgId" class="img-box img" :src="item.userIconImgId"></image-preview>
<image v-else src="/static/images/me/default_user_avatar.png" class="img"></image>
</view>
<view class="msg_content">
<view class="title_div">
<view class="name">{{item.userName}}</view>
<view class="title_tip">{{item.bbsTagDesc}}</view>
</view>
<view class="title">
{{item.bbsContent}}
</view>
<view class="img_div pic-cell">
<image-preview v-for="img in item.imgIdList" :imgId="img" class="pic-item"></image-preview>
</view>
<view class="time_and_reply">
<view class="time">{{item.bbsTm.substr(0,16)}}</view>
<view class="reply" @click="click_reply(item, item.bbsId, index)">回复</view>
</view>
<view class="show_close_div" v-if="item.children?.length" @click="item.show = !item.show">
<template v-if="item.show">
<view>收起</view>
<view class="back_div">
<view class="back-icon"></view>
</view>
</template>
<template v-else>
<view>展开{{item.children?.length}}条回复</view>
<view class="back_div">
<view class="back-icon"></view>
</view>
</template>
</view>
<view class="children" v-if="item.show">
<view class="message_div" v-for="childrenItem in item.children">
<view class="head_div">
<image-preview v-if="childrenItem.userIconImgId" class="img-box img"
:src="childrenItem.userIconImgId"></image-preview>
<image v-else src="/static/images/me/default_user_avatar.png" class="img"></image>
</view>
<view class="msg_content">
<view class="title_div">
<view class="name">{{childrenItem.userName}}</view>
<view class="arrow"></view>
<view class="name">{{childrenItem.rtnUName}}</view>
</view>
<view class="title">
{{childrenItem.bbsContent}}
</view>
<view class="img_div">
</view>
<view class="time_and_reply">
<view class="time">{{childrenItem.bbsTm.substr(0,16)}}</view>
<view class="reply" @click="click_reply(childrenItem, childrenItem.parentId, index)">回复
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="send_evaluate_div">
<uv-button type="primary" class="send_evaluate"
@click="common.navigateTo('/pages/courseDetail/submit?crsNum='+props.crsNum+'&imgId='+props.imgId)">发布评价</uv-button>
</view>
<uni-popup ref="popup" background-color="red">
<view class="bottom_reply_input_div">
<uv-input v-model="reply_data.bbsContent" placeholderStyle='color:#999999;font-size:26rpx'
:placeholder="reply_data.placeholder" :focus="true" :maxlength="160">
</uv-input>
<view class="" style="display: flex;flex-direction: column; margin:10rpx 20rpx;">
<view class="fl1"></view>
<uv-button class="bottom_reply_button" type="primary" :throttleTime="500"
@click="reply_send">回复</uv-button>
<view class="fl1"></view>
</view>
</view>
</uni-popup>
</view>
</template>
<script setup>
import {
ref,
reactive,
onMounted
} from 'vue'
import {
qryTraCrsBbsDataByCrsNum,
replyTraCrsBbsInfo,
qryChildTraCrsBbsInfo
} from '@/api/courseDetail.js';
import common from '@/common/common.js'
const popup = ref(null)
const inputValue = ref('')
const placeholder = ref('')
const message_list = reactive([])
const reply_data_init = {
"index": null,
"parentBbsId": null,
"bbsId": null,
"bbsContent": '',
"placeholder": '',
}
const reply_data = reactive({
...reply_data_init
})
const props = defineProps({
crsNum: String,
imgId: String
})
const click_reply = ({
userName,
bbsId
}, parentBbsId, index) => {
popup.value.open('bottom')
reply_data.placeholder = '回复 ' + userName + ""
reply_data.parentBbsId = parentBbsId
reply_data.bbsId = bbsId
reply_data.index = index
}
const reply_send = async () => {
try {
popup.value.close()
common.loading('发送中...')
await replyTraCrsBbsInfo({
parentBbsId: reply_data.parentBbsId,
bbsId: reply_data.bbsId,
bbsContent: reply_data.bbsContent,
imgIdList: []
})
common.msg('发送成功')
const res = await qryChildTraCrsBbsInfo({
bbsId: reply_data.parentBbsId
})
message_list[reply_data.index]['children'] = res.body
Object.assign(reply_data, reply_data_init)
} catch (e) {
common.msg('发送失败')
} finally {
common.hideLoading()
}
}
const getData = () => {
qryTraCrsBbsDataByCrsNum({
crsNum: props.crsNum
}).then(({
body
}) => {
Object.assign(message_list, body)
})
}
defineExpose({
getData
})
onMounted(() => {
getData()
})
</script>
<style lang="scss" scoped>
.empty_message_div{
display: flex;
justify-content: center;
padding: 80rpx 0;
.img{
width: 288rpx;
height: 276rpx;
}
}
.pic-cell {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.pic-item {
margin-right: 16rpx;
width: 170rpx;
height: 170rpx;
border-radius: 8rpx;
// background-color: red;
margin-bottom: 24rpx;
}
.send_evaluate_div_height {
height: 170rpx;
}
.send_evaluate_div {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 10rpx 20rpx 30rpx 20rpx;
// padding-top: 10rpx;
// padding-bottom: 30rpx;
background-color: #ffffff;
// background-color: red;
:deep(.uv-button-wrapper) {
.uv-button {
border-radius: 14rpx;
height: 92rpx;
}
}
}
// 顶部随着输入法弹出的框
.bottom_reply_input_div {
width: 100%;
height: 100%;
background-color: #FFFFFF;
display: flex;
align-items: center;
padding: 10rpx 10rpx;
.bottom_reply_button {
border: none;
border-radius: 4rpx;
background-color: #0066FF;
color: #FFFFFF;
overflow: hidden;
:deep(.uv-button) {
height: 60rpx;
}
}
}
.back_div {
margin-left: 6rpx;
.back-icon {
position: relative;
width: 30rpx;
height: 30rpx;
cursor: pointer;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::after {
top: 2%;
left: 25%;
width: 50%;
height: 50%;
border-top: 3rpx solid #0066FF;
border-left: 3rpx solid #0066FF;
transform: rotate(-135deg);
}
}
.message_div:not(:first-child) {
margin-top: 30rpx;
}
.message_div {
// margin-top: 30rpx;
display: flex;
margin-left: 20rpx;
margin-right: 20rpx;
.head_div {
.img {
border-radius: 100%;
width: 78rpx;
height: 78rpx;
overflow: hidden;
}
}
.msg_content {
margin-left: 22rpx;
flex: 1;
overflow: hidden;
.title_div {
display: flex;
align-items: center;
.name {
height: 35rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 25rpx;
color: #666666;
line-height: 35rpx;
text-align: left;
font-style: normal;
}
.title_tip {
margin-left: 16rpx;
width: 76rpx;
height: 34rpx;
background: #FFFFFF;
border-radius: 8rpx;
border: 2rpx solid #999999;
font-family: PingFangSC;
font-weight: 400;
font-size: 23rpx;
color: #666666;
line-height: 36rpx;
text-align: center;
}
.arrow {
margin: 0 12rpx 0 14rpx;
position: relative;
width: 12rpx;
height: 20rpx;
overflow: hidden;
}
.arrow::after {
content: "";
position: absolute;
background-color: #666666;
right: 4rpx;
width: 18rpx;
height: 12rpx;
transform: rotate(45deg);
}
}
.title {
margin: 4rpx 0;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #333333;
text-align: left;
line-height: 48rpx;
text-overflow: ellipsis;
white-space: wrap;
overflow-wrap: anywhere;
}
.time_and_reply {
display: flex;
align-items: center;
height: 28rpx;
.time {
font-family: ArialMT;
font-size: 24rpx;
color: #666666;
line-height: 27rpx;
text-align: left;
font-style: normal;
}
.reply {
margin-left: 16rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 24rpx;
color: #0066FF;
line-height: 33rpx;
text-align: left;
font-style: normal;
}
}
.show_close_div {
margin-top: 12rpx;
margin-bottom: 20rpx;
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #456A8E;
line-height: 30rpx;
text-align: left;
font-style: normal;
display: flex;
align-items: center;
}
}
}
.comment_div {
padding: 20rpx 0 20rpx 0;
background-color: #ffffff;
border-radius: 24rpx;
position: relative;
// height: calc(100vh - 88rpx - 162rpx - 256rpx - 70rpx);
// overflow: hidden;
}
</style>