useredirectto

This commit is contained in:
WanP
2025-10-20 14:55:15 +08:00
parent c5a7840d43
commit 45ceb9c77d
9 changed files with 78 additions and 116 deletions

View 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>