Files
sbnews/uniapp/src/pages/my_comments/my_comments.vue
T

258 lines
6.9 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>
<z-paging
ref="paging"
v-model="commentList"
:fixed="false"
height="100%"
use-page-scroll
@query="queryList"
>
<view class="my-comments-page">
<view v-for="item in commentList" :key="item.id" class="comment-card" @tap="goPost(item)">
<view class="comment-card__head">
<view class="comment-card__author">
<image class="comment-card__avatar" :src="getCommentAvatar(item)" mode="aspectFill"
@error="handleAvatarError" />
<text class="comment-card__name">{{ formatNickname(item.user?.nickname) }}</text>
<text class="comment-card__label">{{ item.reply_to ? '回复了评论' : '评论了帖子' }}</text>
</view>
<text class="comment-card__time">{{ formatTime(item.create_time) }}</text>
</view>
<view v-if="item.reply_to" class="comment-card__reply">
<text class="comment-card__reply-prefix">回复 </text>
<text class="comment-card__reply-name">{{ formatNickname(item.reply_to.user?.nickname || '该用户') }}</text>
<text></text>
<text class="comment-card__reply-content">{{ item.reply_to.content }}</text>
</view>
<text class="comment-card__content">{{ item.content }}</text>
<view v-if="item.post" class="comment-card__post">
<text class="comment-card__post-label">原帖</text>
<text class="comment-card__post-content">查看帖子详情</text>
<u-icon name="arrow-right" color="#9aa4b2" size="24" />
</view>
<view v-else class="comment-card__post comment-card__post--unavailable">
<text>原帖已不可查看</text>
</view>
<view class="comment-card__footer">
<text class="comment-card__delete" @tap.stop="confirmDelete(item)">删除评论</text>
</view>
</view>
</view>
</z-paging>
</template>
<script lang="ts" setup>
import { ref, shallowRef } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { deleteComment, getMyCommentLists } from '@/api/community'
const paging = shallowRef()
const commentList = ref<any[]>([])
const avatarLoadFailed = ref(false)
onShow(() => {
paging.value?.reload()
})
const queryList = async (pageNo: number, pageSize: number) => {
try {
const { lists = [] } = await getMyCommentLists({ page_no: pageNo, page_size: pageSize })
paging.value.complete(lists)
} catch {
paging.value.complete(false)
}
}
const goPost = (item: any) => {
if (!item.post?.id) {
uni.showToast({ title: '原帖已不可查看', icon: 'none' })
return
}
uni.navigateTo({ url: `/packages_community/pages/post_detail?id=${item.post.id}` })
}
const confirmDelete = (item: any) => {
uni.showModal({
title: '删除评论',
content: '删除后无法恢复,确定要删除吗?',
success: async (res) => {
if (!res.confirm) return
try {
await deleteComment({ comment_id: item.id })
uni.showToast({ title: '评论已删除', icon: 'success' })
paging.value.reload()
} catch {
uni.showToast({ title: '删除失败,请稍后重试', icon: 'none' })
}
}
})
}
const getCommentAvatar = (item: any) => {
return avatarLoadFailed.value ? '/static/images/avatar.png' : (item.user?.avatar || '/static/images/avatar.png')
}
const handleAvatarError = () => {
avatarLoadFailed.value = true
}
const formatNickname = (value?: string) => {
const name = String(value || '我')
const characters = Array.from(name)
return characters.length > 4 ? `${characters.slice(0, 4).join('')}…` : name
}
const parseTimestamp = (value: string | number) => {
if (typeof value === 'number') return value
return new Date(String(value).replace(/-/g, '/')).getTime() / 1000
}
const formatTime = (value: string | number) => {
const timestamp = parseTimestamp(value)
if (!Number.isFinite(timestamp)) return ''
const diff = Date.now() / 1000 - timestamp
if (diff < 60) return '刚刚'
if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`
if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`
if (diff < 604800) return `${Math.floor(diff / 86400)}天前`
const date = new Date(timestamp * 1000)
return `${date.getMonth() + 1}-${date.getDate()}`
}
</script>
<style lang="scss" scoped>
.my-comments-page {
min-height: 100vh;
padding: 20rpx 24rpx 40rpx;
box-sizing: border-box;
background: #f6f8fb;
}
.comment-card {
margin-bottom: 20rpx;
padding: 24rpx;
border: 1rpx solid #e7ebf1;
border-radius: 18rpx;
background: #fff;
}
.comment-card__head,
.comment-card__footer,
.comment-card__post {
display: flex;
align-items: center;
}
.comment-card__head {
justify-content: space-between;
margin-bottom: 16rpx;
}
.comment-card__author {
min-width: 0;
display: flex;
align-items: center;
}
.comment-card__avatar {
width: 40rpx;
height: 40rpx;
flex-shrink: 0;
margin-right: 10rpx;
border-radius: 50%;
background: #eef2f7;
}
.comment-card__name {
max-width: 180rpx;
overflow: hidden;
color: #344055;
font-size: 24rpx;
font-weight: 500;
text-overflow: ellipsis;
white-space: nowrap;
}
.comment-card__label {
margin-left: 10rpx;
color: #687385;
font-size: 24rpx;
}
.comment-card__time {
flex-shrink: 0;
margin-left: 20rpx;
color: #9aa4b2;
font-size: 22rpx;
}
.comment-card__reply {
margin-bottom: 14rpx;
padding: 14rpx 16rpx;
border-radius: 10rpx;
background: #f6f8fb;
color: #7c8798;
font-size: 24rpx;
line-height: 36rpx;
}
.comment-card__reply-prefix {
color: #4d78d9;
}
.comment-card__reply-name {
color: #344055;
font-weight: 500;
}
.comment-card__content {
display: block;
color: #1f2937;
font-size: 30rpx;
font-weight: 500;
line-height: 46rpx;
word-break: break-all;
}
.comment-card__post {
margin-top: 20rpx;
padding: 16rpx;
border-radius: 12rpx;
background: #f6f8fb;
color: #687385;
font-size: 24rpx;
}
.comment-card__post-label {
flex-shrink: 0;
margin-right: 12rpx;
color: #4d78d9;
}
.comment-card__post-content {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.comment-card__post--unavailable {
color: #9aa4b2;
}
.comment-card__footer {
justify-content: flex-end;
margin-top: 18rpx;
}
.comment-card__delete {
padding: 8rpx 0 8rpx 24rpx;
color: #9aa4b2;
font-size: 24rpx;
}
</style>