style: align post detail discussion layout

This commit is contained in:
hajimi
2026-08-03 00:41:44 +08:00
parent fa0593d4ce
commit cae05328a9
3 changed files with 125 additions and 113 deletions
@@ -105,6 +105,7 @@
import { computed, ref, watch } from 'vue'
import { translatePost } from '@/api/community'
import { getToken } from '@/utils/auth'
import { formatCount } from '@/utils/number'
const props = defineProps<{ post: any }>()
defineEmits(['tap', 'unlock', 'like', 'avatar-tap'])
@@ -179,21 +180,6 @@ const formatTime = (value: any) => {
return `${date.getMonth() + 1}-${date.getDate()}`
}
const formatCount = (value: any) => {
const numericValue = Number(value)
if (!Number.isFinite(numericValue) || numericValue <= 0) return '0'
const count = Math.floor(numericValue)
const compact = (divisor: number, unit: string) => {
const formatted = (count / divisor).toFixed(1).replace(/\.0$/, '')
return `${formatted}${unit}`
}
if (count >= 100000000) return compact(100000000, '亿')
if (count >= 10000) return compact(10000, '万')
if (count >= 1000) return compact(1000, 'k')
return String(count)
}
</script>
<style lang="scss" scoped>
@@ -146,79 +146,83 @@
@tap="handleDeletePost">删除帖子</view>
</view>
<view class="detail-interaction">
<view class="detail-interaction__header">
<text class="detail-interaction__title">互动</text>
<view class="detail-interaction__stats">
<view class="detail-interaction__stat" @tap="handleLike">
<u-icon name="thumb-up" size="34" :color="post.is_liked ? '#1468f5' : '#737373'" />
<text :class="{ 'is-active': post.is_liked }">{{ Number(post.like_count || 0) }}</text>
</view>
<view class="detail-interaction__stat">
<u-icon name="chat" size="34" color="#737373" />
<text>{{ Number(post.comment_count || 0) }}</text>
</view>
<view class="detail-interaction__stat">
<u-icon name="eye" size="34" color="#737373" />
<text>{{ Number(post.view_count || 0) }}</text>
</view>
</view>
</view>
</view>
<view class="detail-comments">
<view class="detail-comments__title">
<text>评论 ({{ commentTotal }})</text>
</view>
<view v-if="commentError" class="detail-comments__error">
<text>评论加载失败</text>
<text class="detail-comments__retry" @tap="fetchComments">重新加载</text>
</view>
<view v-else-if="comments.length === 0 && !commentLoading" class="detail-comments__empty">
<text>暂无评论快来抢沙发</text>
</view>
<view v-for="comment in comments" :key="comment.id" class="comment-item">
<image class="comment-item__avatar" :src="getCommentAvatar(comment)" mode="aspectFill"
@error="handleCommentAvatarError(comment)" />
<view class="comment-item__body">
<view class="comment-item__heading">
<text class="comment-item__name">{{ comment.user?.nickname || '匿名' }}</text>
<text v-if="isOwnComment(comment)" class="comment-item__more"
@tap.stop="handleDeleteComment(comment)"></text>
</view>
<text class="comment-item__text">{{ comment.content }}</text>
<view class="comment-item__meta">
<text class="comment-item__time">{{ formatCommentTime(comment.create_time) }}</text>
<view class="comment-item__like" @tap.stop="handleCommentLike(comment)">
<u-icon name="thumb-up" size="25"
:color="comment.is_liked ? '#1468f5' : '#8a8f98'" />
<text :class="{ 'is-active': comment.is_liked }">{{ comment.like_count || '' }}</text>
<view class="detail-discussion">
<view class="detail-interaction">
<view class="detail-interaction__header">
<text class="detail-interaction__title">互动</text>
<view class="detail-interaction__stats">
<view class="detail-interaction__stat" @tap="handleLike">
<u-icon name="thumb-up" size="34" :color="post.is_liked ? '#1468f5' : '#737373'" />
<text :class="{ 'is-active': post.is_liked }">{{ formatCount(post.like_count) }}</text>
</view>
<text class="comment-item__reply-btn" @tap.stop="openReply(comment)">回复</text>
</view>
<view v-if="comment.replies && comment.replies.length > 0" class="comment-replies">
<view v-for="reply in comment.replies" :key="reply.id" class="comment-reply">
<text class="comment-reply__name">{{ reply.user?.nickname || '匿名' }}</text>
<text v-if="reply.reply_user" class="comment-reply__arrow"> 回复 </text>
<text v-if="reply.reply_user" class="comment-reply__name">{{ reply.reply_user.nickname
}}</text>
<text class="comment-reply__text">{{ reply.content }}</text>
<text v-if="isOwnComment(reply)" class="comment-reply__delete"
@tap.stop="handleDeleteComment(reply)"> 删除</text>
<view class="detail-interaction__stat">
<u-icon name="chat" size="34" color="#737373" />
<text>{{ formatCount(post.comment_count) }}</text>
</view>
<view class="detail-interaction__stat">
<u-icon name="eye" size="34" color="#737373" />
<text>{{ formatCount(post.view_count) }}</text>
</view>
<text v-if="comment.reply_count > comment.replies.length" class="comment-replies__more">
还有{{ comment.reply_count - comment.replies.length }}条回复
</text>
</view>
</view>
</view>
<view v-if="commentLoading" class="detail-comments__loading">
<u-loading mode="circle" size="28" />
<view class="detail-comments">
<view v-if="commentError" class="detail-comments__error">
<text>评论加载失败</text>
<text class="detail-comments__retry" @tap="fetchComments">重新加载</text>
</view>
<view v-else-if="comments.length === 0 && !commentLoading" class="detail-comments__empty">
<text>暂无评论快来抢沙发</text>
</view>
<view v-for="comment in comments" :key="comment.id" class="comment-item">
<image class="comment-item__avatar" :src="getCommentAvatar(comment)" mode="aspectFill"
@error="handleCommentAvatarError(comment)" />
<view class="comment-item__body">
<view class="comment-item__heading">
<text class="comment-item__name">{{ comment.user?.nickname || '匿名' }}</text>
<text v-if="isOwnComment(comment)" class="comment-item__more"
@tap.stop="handleDeleteComment(comment)"></text>
</view>
<view class="comment-item__content">
<text class="comment-item__text">{{ comment.content }}</text>
<view class="comment-item__like" @tap.stop="handleCommentLike(comment)">
<u-icon name="thumb-up" size="27"
:color="comment.is_liked ? '#1468f5' : '#8a8f98'" />
<text v-if="Number(comment.like_count) > 0"
:class="{ 'is-active': comment.is_liked }">
{{ formatCount(comment.like_count) }}
</text>
</view>
</view>
<view class="comment-item__meta">
<text class="comment-item__time">{{ formatCommentTime(comment.create_time) }}</text>
<text class="comment-item__reply-btn" @tap.stop="openReply(comment)">回复</text>
</view>
<view v-if="comment.replies && comment.replies.length > 0" class="comment-replies">
<view v-for="reply in comment.replies" :key="reply.id" class="comment-reply">
<text class="comment-reply__name">{{ reply.user?.nickname || '匿名' }}</text>
<text v-if="reply.reply_user" class="comment-reply__arrow"> 回复 </text>
<text v-if="reply.reply_user" class="comment-reply__name">{{ reply.reply_user.nickname
}}</text>
<text class="comment-reply__text">{{ reply.content }}</text>
<text v-if="isOwnComment(reply)" class="comment-reply__delete"
@tap.stop="handleDeleteComment(reply)"> 删除</text>
</view>
<text v-if="comment.reply_count > comment.replies.length" class="comment-replies__more">
还有{{ comment.reply_count - comment.replies.length }}条回复
</text>
</view>
</view>
</view>
</view>
<view v-if="commentLoading" class="detail-comments__loading">
<u-loading mode="circle" size="28" />
</view>
</view>
</view>
</view>
@@ -258,6 +262,7 @@ import { openChat } from '@/api/chat'
import { useAppStore } from '@/stores/app'
import { useUserStore } from '@/stores/user'
import { AgreementEnum } from '@/enums/agreementEnums'
import { formatCount } from '@/utils/number'
import { getToken } from '@/utils/auth'
const LIUHE_TAGS = ['旧澳六合', '新澳六合']
@@ -1419,12 +1424,17 @@ const formatCommentTime = (value: any) => {
}
}
.detail-interaction {
.detail-discussion {
margin-top: 20rpx;
padding: 25rpx 24rpx;
border: 1rpx solid #e8ebf0;
border-radius: 20rpx;
background: #ffffff;
overflow: hidden;
}
.detail-interaction {
padding: 26rpx 24rpx;
border-bottom: 1rpx solid #edf0f4;
&__header {
display: flex;
@@ -1435,14 +1445,14 @@ const formatCommentTime = (value: any) => {
&__title {
color: #111111;
font-size: 31rpx;
font-size: 34rpx;
font-weight: 720;
}
&__stats {
display: flex;
align-items: center;
gap: 36rpx;
gap: 40rpx;
}
&__stat {
@@ -1450,7 +1460,7 @@ const formatCommentTime = (value: any) => {
align-items: center;
gap: 8rpx;
color: #737373;
font-size: 25rpx;
font-size: 26rpx;
.is-active {
color: #1468f5;
@@ -1459,19 +1469,7 @@ const formatCommentTime = (value: any) => {
}
.detail-comments {
margin-top: 16rpx;
padding: 26rpx 24rpx 34rpx;
border: 1rpx solid #e8ebf0;
border-radius: 20rpx;
background: #ffffff;
&__title {
padding-bottom: 20rpx;
border-bottom: 1rpx solid #edf0f4;
color: #191b20;
font-size: 31rpx;
font-weight: 720;
}
padding: 0 24rpx 12rpx;
&__empty,
&__error {
@@ -1496,9 +1494,9 @@ const formatCommentTime = (value: any) => {
}
.comment-item {
padding: 26rpx 0;
padding: 30rpx 0;
display: flex;
gap: 18rpx;
gap: 20rpx;
border-bottom: 1rpx solid #edf0f4;
&:last-of-type {
@@ -1506,8 +1504,8 @@ const formatCommentTime = (value: any) => {
}
&__avatar {
width: 68rpx;
height: 68rpx;
width: 72rpx;
height: 72rpx;
flex-shrink: 0;
border-radius: 50%;
background: #edf2f8;
@@ -1526,8 +1524,8 @@ const formatCommentTime = (value: any) => {
}
&__name {
color: #22252b;
font-size: 27rpx;
color: #17191e;
font-size: 28rpx;
font-weight: 680;
}
@@ -1541,20 +1539,27 @@ const formatCommentTime = (value: any) => {
font-size: 34rpx;
}
&__content {
margin-top: 10rpx;
display: flex;
align-items: center;
gap: 18rpx;
}
&__text {
display: block;
margin-top: 9rpx;
flex: 1;
min-width: 0;
color: #2f333a;
font-size: 28rpx;
line-height: 1.65;
font-size: 29rpx;
line-height: 1.62;
word-break: break-word;
}
&__meta {
margin-top: 12rpx;
margin-top: 14rpx;
display: flex;
align-items: center;
gap: 28rpx;
gap: 30rpx;
}
&__time,
@@ -1565,9 +1570,12 @@ const formatCommentTime = (value: any) => {
}
&__like {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 6rpx;
gap: 8rpx;
color: #737a86;
font-size: 24rpx;
.is-active {
color: #1468f5;
+18
View File
@@ -0,0 +1,18 @@
/**
*
*/
export const formatCount = (value: unknown): string => {
const numericValue = Number(value)
if (!Number.isFinite(numericValue) || numericValue <= 0) return '0'
const count = Math.floor(numericValue)
const compact = (divisor: number, unit: string) => {
const formatted = (count / divisor).toFixed(1).replace(/\.0$/, '')
return `${formatted}${unit}`
}
if (count >= 100000000) return compact(100000000, '亿')
if (count >= 10000) return compact(10000, '万')
if (count >= 1000) return compact(1000, 'k')
return String(count)
}