fix: youhua

This commit is contained in:
zzc
2026-06-10 01:24:41 +08:00
parent 1e5bbbbf9e
commit aa88eef08e
3 changed files with 164 additions and 26 deletions

View File

@@ -47,7 +47,9 @@
<!-- 你的态度 -->
<AttitudePanel
ref="attitudePanelRef"
:initial-action="currentAction"
:sending="isSendingComment"
@action-change="handleActionChange"
@send-comment="handleSendComment"
/>
@@ -89,18 +91,32 @@
<!-- <text class="filter-icon"></text> -->
</view>
<view class="comment-list" style="min-height: 400rpx;">
<view class="comment-list">
<view v-if="commentLoading && !comments.length" class="comment-state">
<text class="comment-state-title">评论加载中...</text>
<text class="comment-state-desc">正在拉取大家的锐评</text>
</view>
<view v-else-if="commentError && !comments.length" class="comment-state">
<text class="comment-state-title">评论加载失败</text>
<text class="comment-state-desc">{{ commentError }}</text>
<button class="comment-state-btn" @tap="retryLoadComments">重新加载</button>
</view>
<view v-else-if="!comments.length" class="comment-state">
<text class="comment-state-title">还没有评论</text>
<text class="comment-state-desc">来发第一条锐评带动一下讨论气氛</text>
</view>
<CommentItem
v-for="(comment, index) in comments"
:key="comment.id"
:comment="comment"
@need-login="openLoginPopup"
@like-change="handleCommentLikeChange"
/>
</view>
<!-- 加载更多 -->
<view class="load-more">
<text>{{ loading ? '加载中...' : (hasMore ? '上拉加载更多' : '没有更多了') }}</text>
<view v-if="comments.length" class="load-more">
<text>{{ commentLoadText }}</text>
</view>
</view>
</view>
@@ -127,14 +143,22 @@ import { getShareReward } from "@/api/system";
import { useUserStore } from "@/stores/user";
const userStore = useUserStore();
const statusBarHeight = ref(getStatusBarHeight() || 44);
const loading = ref(false);
const hasMore = ref(true);
const currentPage = ref(1);
const currentAction = ref('');
const successPopupRef = ref(null);
const loginPopupRef = ref(null);
const attitudePanelRef = ref(null);
const currentTab = ref('hot'); // 'hot' 或 'new'
const isLoggedIn = computed(() => !!userStore.token || !!userStore.userInfo?.nickName);
const commentLoading = ref(false);
const isSendingComment = ref(false);
const commentError = ref('');
const commentLoadText = computed(() => {
if (commentLoading.value && comments.value.length) return '加载中...';
if (!hasMore.value) return '没有更多了';
return '上拉加载更多';
});
const goBack = () => {
uni.navigateBack();
@@ -215,9 +239,10 @@ const handleSendComment = async (payload) => {
return;
}
if (!detailData.value.topicId || !itemId.value) return;
if (!detailData.value.topicId || !itemId.value || isSendingComment.value) return;
try {
isSendingComment.value = true;
uni.showLoading({ title: '发送中...' });
await topicItemComment({
topicId: detailData.value.topicId,
@@ -237,7 +262,6 @@ const handleSendComment = async (payload) => {
// 刷新页面数据以获取最新评论
currentPage.value = 1;
hasMore.value = true;
comments.value = [];
uni.$trackRecord({
eventName: 'comment',
eventType: 'comment',
@@ -248,13 +272,16 @@ const handleSendComment = async (payload) => {
page: 'rating_detail'
}
});
getCommentsData();
attitudePanelRef.value?.resetComment?.();
await getCommentsData({ replace: true });
} catch (error) {
uni.hideLoading();
uni.showToast({
title: '发送失败',
icon: 'none'
});
} finally {
isSendingComment.value = false;
}
};
@@ -263,16 +290,34 @@ const switchTab = (tab) => {
currentTab.value = tab;
currentPage.value = 1;
hasMore.value = true;
// comments.value = []; // 移除这行,避免数据清空导致高度塌陷
getCommentsData(true); // 传入标识表示是切换榜单
commentError.value = '';
getCommentsData({ replace: true });
};
const getCommentsData = async (isSwitchTab = false) => {
if (!detailData.value.topicId || !itemId.value || loading.value) return;
const resolveCommentHasMore = (res, list) => {
const data = res?.data || res || {};
const hasNext = data?.hasNext ?? res?.hasNext;
if (typeof hasNext === 'boolean') return hasNext;
const pages = Number(data?.pages ?? res?.pages ?? 0);
if (pages > 0) return currentPage.value < pages;
const total = Number(data?.total ?? res?.total ?? 0);
if (total > 0) {
const size = Number(data?.size ?? data?.pageSize ?? res?.size ?? res?.pageSize ?? list.length || 1);
return currentPage.value * size < total;
}
return list.length > 0;
};
const getCommentsData = async ({ replace = false } = {}) => {
if (!detailData.value.topicId || !itemId.value || commentLoading.value) return;
try {
loading.value = true;
const orderBy = currentTab.value;
commentLoading.value = true;
commentError.value = '';
const orderBy = currentTab.value === 'hot' ? 1 : 2;
const res = await topicItemCommentList(detailData.value.topicId, itemId.value, currentPage.value, orderBy);
const rawList =
res?.data?.records ||
@@ -297,21 +342,42 @@ const getCommentsData = async (isSwitchTab = false) => {
userAction: item.userAction || "" // 夯/顶级/人上人/NPC/拉
}));
if (currentPage.value === 1 || isSwitchTab) {
if (currentPage.value === 1 || replace) {
comments.value = formattedList;
} else {
comments.value = [...comments.value, ...formattedList];
}
// 假设每页10条如果返回的少于10条则没有更多了
hasMore.value = list.length >= 6;
hasMore.value = resolveCommentHasMore(res, list);
} catch (error) {
console.error('获取评论列表失败:', error);
commentError.value = '请检查网络后重试';
if (currentPage.value > 1) {
currentPage.value -= 1;
}
} finally {
loading.value = false;
commentLoading.value = false;
}
};
const retryLoadComments = () => {
if (!comments.value.length) {
currentPage.value = 1;
}
getCommentsData({ replace: currentPage.value === 1 });
};
const handleCommentLikeChange = ({ id, isLiked, likes }) => {
comments.value = comments.value.map((item) => {
if (item.id !== id) return item;
return {
...item,
isLiked,
likes
};
});
};
const getDetailData = async () => {
if (!itemId.value) return;
try {
@@ -344,7 +410,7 @@ const getDetailData = async () => {
// 拉取真实的评论列表
if (currentPage.value === 1) {
getCommentsData();
getCommentsData({ replace: true });
}
} catch (error) {
console.error('获取详情失败:', error);
@@ -377,6 +443,7 @@ const handleLoginSuccess = () => {
currentPage.value = 1;
hasMore.value = true;
comments.value = [];
commentError.value = '';
getDetailData();
};
@@ -405,11 +472,12 @@ onPullDownRefresh(() => {
currentPage.value = 1;
hasMore.value = true;
comments.value = [];
commentError.value = '';
getDetailData();
});
onReachBottom(() => {
if (!hasMore.value || loading.value) return;
if (!hasMore.value || commentLoading.value) return;
currentPage.value += 1;
getCommentsData();
});
@@ -749,6 +817,47 @@ onReachBottom(() => {
.comment-list {
display: flex;
flex-direction: column;
min-height: 400rpx;
}
.comment-state {
min-height: 400rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
color: #999;
padding: 40rpx 32rpx;
box-sizing: border-box;
}
.comment-state-title {
font-size: 30rpx;
color: #222;
font-weight: 700;
margin-bottom: 12rpx;
}
.comment-state-desc {
font-size: 24rpx;
color: #9aa0ae;
line-height: 1.6;
}
.comment-state-btn {
margin-top: 24rpx;
height: 72rpx;
line-height: 72rpx;
padding: 0 32rpx;
border-radius: 999rpx;
background: #4d44f1;
color: #fff;
font-size: 26rpx;
}
.comment-state-btn::after {
border: none;
}
.load-more {