useredirectto
This commit is contained in:
484
src/pages/comments/comments.vue
Normal file
484
src/pages/comments/comments.vue
Normal file
@@ -0,0 +1,484 @@
|
||||
<template>
|
||||
<!-- 评论区域 -->
|
||||
<view v-if="comments" class="comment">
|
||||
<!-- 评论头部信息 -->
|
||||
<view class="commenthead">
|
||||
<text class="commentcount">{{ totalCommentCount }}条评论</text>
|
||||
<view class="headswitch">
|
||||
<text class="inact" @tap="handleOpenApp">默认</text>
|
||||
<view class="act" @tap="handleOpenApp">最新</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 评论主体 -->
|
||||
<view v-for="commentItem in highlightedList" :key="commentItem.id" class="commentdetail" @tap="onDelegateTap">
|
||||
<!-- 头像 -->
|
||||
<view class="commentdetailleft">
|
||||
<image src="/static/logo.png" mode="aspectFill" alt="用户头像"></image>
|
||||
</view>
|
||||
|
||||
<!-- 右侧主评论 + 子评论 + 展开条 -->
|
||||
<view class="commentdetailright">
|
||||
<!-- 父评论 -->
|
||||
<view class="maincomment">
|
||||
<view class="commentdetailcontent">
|
||||
<text class="commentusername">{{ commentItem.userName }}</text>
|
||||
<rich-text class="commentusercontent" :nodes="commentItem.renderNodes" />
|
||||
<view class="date-reply">
|
||||
<uni-dateformat :date="Date.parse(commentItem.date.replace(/-/g, '/'))" :threshold="[0, 0]"
|
||||
format="yyyy-MM-dd" class="date-text" />
|
||||
<text class="replytext" @tap.stop="handleOpenApp">回复</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="spacerview"></view>
|
||||
<view class="commentlike">
|
||||
<uni-icons type="heart" size="16" color="#999" @tap.stop="handleOpenApp"></uni-icons>
|
||||
<text class="commentlikecount">{{ formatCount(commentItem.likeCount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 子评论列表(仅展开时显示) -->
|
||||
<view v-if="commentItem.showChild" class="commentchildcontainer">
|
||||
<view v-for="child in commentItem.children" :key="child.id" class="commentchild">
|
||||
<view class="commentchildleft">
|
||||
<image src="/static/logo.png" mode="aspectFill" alt="用户头像"></image>
|
||||
</view>
|
||||
<view class="commentchildright">
|
||||
<text class="commentusername">{{ child.userName }}</text>
|
||||
<rich-text class="commentusercontent" :nodes="child.renderNodes" />
|
||||
<view class="date-reply">
|
||||
<uni-dateformat :date="Date.parse(child.date.replace(/-/g, '/'))" :threshold="[0, 0]"
|
||||
format="yyyy-MM-dd" class="date-text" />
|
||||
<text class="replytext" @tap.stop="handleOpenApp">回复</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="commentlike">
|
||||
<uni-icons type="heart" size="16" color="#999" @tap.stop="handleOpenApp"></uni-icons>
|
||||
<text class="commentlikecount">{{ formatCount(child.likeCount) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 展开/收起按钮 -->
|
||||
<view v-if="commentItem.children.length" class="expandcomment">
|
||||
<view style="width:20px;height:1px;background:rgba(65,60,67,.2)"></view>
|
||||
<text class="expandcommenttext" :data-cid="commentItem.id">
|
||||
{{ commentItem.showChild ? '收起' : `展开${commentItem.children.length}条回复` }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 占位 -->
|
||||
<view class="spacerview"></view>
|
||||
|
||||
<!-- 互动区域 -->
|
||||
<view v-if="showInteraction" class="interaction">
|
||||
<view class="editarea" @tap="handleOpenApp">
|
||||
<image src="/static/imgs/editicon/icon@2x.webp" mode="aspectFit" class="editicon" alt="编辑标签"></image>
|
||||
<text class="edittext">快来互动吧…</text>
|
||||
</view>
|
||||
<view class="spacerview"></view>
|
||||
<view class="collection" @tap="handleOpenApp">
|
||||
<image src="@/static/imgs/staricon/icon@3x.webp" mode="aspectFit" class="collectionicon" alt="收藏标签"></image>
|
||||
<text class="collectioncount">{{ formatCount(collectsum) }}</text>
|
||||
</view>
|
||||
<view class="spacerview"></view>
|
||||
<view class="like" @tap="handleOpenApp">
|
||||
<image src="@/static/imgs/likeicon/icon@3x.webp" mode="aspectFit" class="likeicon" alt="点赞标签"></image>
|
||||
<text class="likecount">{{ formatCount(likesum) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { useCommonStore } from '@/stores/common.js'
|
||||
|
||||
const props = defineProps({
|
||||
comments: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
showInteraction: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
collectsum: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
likesum: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
|
||||
const common = useCommonStore()
|
||||
|
||||
// 处理评论点击事件
|
||||
function onDelegateTap(e) {
|
||||
const cid = e.target?.dataset?.cid
|
||||
if (!cid || !props.comments) return
|
||||
const item = props.comments.find(v => v.id == cid)
|
||||
if (!item || !item.children || !item.children.length) return
|
||||
item.showChild = !item.showChild
|
||||
}
|
||||
|
||||
// 处理打开应用事件
|
||||
function handleOpenApp() {
|
||||
common.openapp()
|
||||
}
|
||||
|
||||
// 格式化数字显示
|
||||
function formatCount(count) {
|
||||
return common.formatCount(count)
|
||||
}
|
||||
|
||||
// 处理评论数据,添加渲染节点
|
||||
const highlightedList = computed(() =>
|
||||
props.comments ? props.comments.map(c => ({
|
||||
...c,
|
||||
renderNodes: [
|
||||
...common.atUsersToNodes(c.atUsers),
|
||||
{ type: 'text', text: c.content }
|
||||
],
|
||||
children: c.children ? c.children.map(child => ({
|
||||
...child,
|
||||
renderNodes: [
|
||||
...common.atUsersToNodes(child.atUsers),
|
||||
{ type: 'text', text: child.content }
|
||||
]
|
||||
})) : []
|
||||
})) : []
|
||||
)
|
||||
|
||||
// 总评论数 = 主评论条数 + 所有子评论条数
|
||||
const totalCommentCount = computed(() =>
|
||||
props.comments ? props.comments.reduce(
|
||||
(sum, c) => sum + 1 + (c.children ? c.children.length : 0),
|
||||
0
|
||||
) : 0
|
||||
)
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.spacerview {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
pointer-events: none
|
||||
}
|
||||
|
||||
.comment {
|
||||
width: 100%;
|
||||
max-width: 430px;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.commenthead {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
height: 29px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.commentcount {
|
||||
width: fit-content;
|
||||
height: 100%;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
color: #333;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.headswitch {
|
||||
width: 102px;
|
||||
height: 100%;
|
||||
flex-grow: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
border-radius: 24px;
|
||||
padding: 2px;
|
||||
box-sizing: border-box;
|
||||
background-color: #f0eef1;
|
||||
}
|
||||
|
||||
.headswitch .inact,
|
||||
.act {
|
||||
width: 48px;
|
||||
height: 23px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
color: #110c13;
|
||||
}
|
||||
|
||||
.headswitch .inact {
|
||||
border-radius: 24px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.commentdetail {
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.commentdetailleft {
|
||||
width: 31.7px;
|
||||
height: 31.7px;
|
||||
margin-right: 12.2px;
|
||||
}
|
||||
|
||||
.commentdetailleft image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.commentdetailright {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.maincomment {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.commentdetailcontent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.commentusername {
|
||||
width: fit-content;
|
||||
height: 18px;
|
||||
font-family: 'SFPro';
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
color: #b1aeb2;
|
||||
}
|
||||
|
||||
.commentusercontent {
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
margin: 4px 0 10px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.date-reply {
|
||||
height: 17px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.date-text,
|
||||
.replytext {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 17px;
|
||||
line-height: 17px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.date-text {
|
||||
color: #b1aeb2;
|
||||
}
|
||||
|
||||
.replytext {
|
||||
color: #918e93;
|
||||
}
|
||||
|
||||
.commentlike {
|
||||
height: 43px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6.7px;
|
||||
padding: 2px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.commentlikecount {
|
||||
min-width: 40px;
|
||||
height: 17px;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: 17px;
|
||||
letter-spacing: normal;
|
||||
text-align: center;
|
||||
padding: 0 4px;
|
||||
color: #918e93;
|
||||
}
|
||||
|
||||
.commentchildcontainer {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 14px 0 0;
|
||||
}
|
||||
|
||||
.commentchild {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.commentchildleft {
|
||||
width: 23.5px;
|
||||
height: 23.5px;
|
||||
margin-right: 8.2px;
|
||||
}
|
||||
|
||||
.commentchildleft image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.commentchildright {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.expandcomment {
|
||||
width: 96px;
|
||||
height: 17px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.expandcommenttext {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
color: #110c13;
|
||||
}
|
||||
|
||||
.interaction {
|
||||
width: 100%;
|
||||
max-width: 430px;
|
||||
border: solid 1px #faf9fb;
|
||||
background-color: #faf9fb;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 11.5px 16px;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.editarea {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
background-color: #fff;
|
||||
border-radius: 24px;
|
||||
gap: 12px;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editicon {
|
||||
width: 13.3px;
|
||||
height: 14.6px;
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.edittext {
|
||||
flex: 1;
|
||||
flex-grow: 0;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: 40px;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
color: #918e93;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.collection,
|
||||
.like {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.collectionicon,
|
||||
.likeicon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.collectioncount,
|
||||
.likecount {
|
||||
height: 17px;
|
||||
font-family: 'SFPro';
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
font-stretch: normal;
|
||||
font-style: normal;
|
||||
line-height: normal;
|
||||
letter-spacing: normal;
|
||||
text-align: left;
|
||||
color: #000;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user