feat: repley
This commit is contained in:
@@ -50,8 +50,10 @@
|
||||
ref="attitudePanelRef"
|
||||
:initial-action="currentAction"
|
||||
:sending="isSendingComment"
|
||||
:reply-target="replyTarget"
|
||||
@action-change="handleActionChange"
|
||||
@send-comment="handleSendComment"
|
||||
@cancel-reply="clearReplyTarget"
|
||||
/>
|
||||
|
||||
<!-- 大家都在 PK -->
|
||||
@@ -121,6 +123,7 @@
|
||||
:comment="comment"
|
||||
@need-login="openLoginPopup"
|
||||
@like-change="handleCommentLikeChange"
|
||||
@reply="handleReplyComment"
|
||||
/>
|
||||
</view>
|
||||
|
||||
@@ -198,12 +201,57 @@ const detailData = ref({
|
||||
|
||||
const comments = ref([]);
|
||||
const itemId = ref('');
|
||||
const replyTarget = ref(null);
|
||||
|
||||
const buildAvatarUrl = (avatar) => {
|
||||
if (!avatar) return 'https://api.dicebear.com/7.x/avataaars/svg?seed=fallback';
|
||||
return String(avatar).startsWith('http') ? avatar : `${FILE_BASE_URL}${avatar}`;
|
||||
};
|
||||
|
||||
const normalizeCommentItem = (item = {}, rootComment = null) => {
|
||||
const user = item.user || {};
|
||||
const replyToUser = item.replyToUser || {};
|
||||
return {
|
||||
id: item.id,
|
||||
rootCommentId: item.rootCommentId || rootComment?.id || null,
|
||||
parentCommentId: item.parentCommentId || rootComment?.id || null,
|
||||
replyToCommentId: item.replyToCommentId || null,
|
||||
name: user.nickname || '匿名用户',
|
||||
avatar: buildAvatarUrl(user.avatar),
|
||||
time: formatDate(item.createdAt) || '刚刚',
|
||||
content: item.content || '',
|
||||
likes: Number(item.likeCount || 0),
|
||||
isLiked: !!item.isLiked,
|
||||
badge: '',
|
||||
badgeIcon: '',
|
||||
userAction: item.userAction || '',
|
||||
replyCount: Number(item.replyCount || 0),
|
||||
replyToName: replyToUser.nickname || '',
|
||||
replies: rootComment
|
||||
? []
|
||||
: (Array.isArray(item.replies) ? item.replies.map((reply) => normalizeCommentItem(reply, item)) : [])
|
||||
};
|
||||
};
|
||||
|
||||
const clearReplyTarget = () => {
|
||||
replyTarget.value = null;
|
||||
};
|
||||
|
||||
const handleReplyComment = (payload) => {
|
||||
if (!isLoggedIn.value) {
|
||||
openLoginPopup();
|
||||
return;
|
||||
}
|
||||
|
||||
replyTarget.value = {
|
||||
rootCommentId: payload.rootCommentId,
|
||||
parentCommentId: payload.parentCommentId,
|
||||
replyToCommentId: payload.replyToCommentId,
|
||||
replyToName: payload.replyToName || '',
|
||||
content: payload.content || ''
|
||||
};
|
||||
};
|
||||
|
||||
const calcPkPercent = (leftScore, rightScore) => {
|
||||
const left = Number(leftScore) || 0;
|
||||
const right = Number(rightScore) || 0;
|
||||
@@ -333,7 +381,9 @@ const handleSendComment = async (payload) => {
|
||||
await topicItemComment({
|
||||
topicId: detailData.value.topicId,
|
||||
itemId: itemId.value,
|
||||
content: payload.content
|
||||
content: payload.content,
|
||||
parentCommentId: replyTarget.value?.parentCommentId || undefined,
|
||||
replyToCommentId: replyTarget.value?.replyToCommentId || undefined
|
||||
});
|
||||
uni.hideLoading();
|
||||
|
||||
@@ -355,10 +405,12 @@ const handleSendComment = async (payload) => {
|
||||
elementContent: `评论项_${detailData.value.name}`,
|
||||
customParams: {
|
||||
comment: payload.content,
|
||||
replyToCommentId: replyTarget.value?.replyToCommentId || '',
|
||||
page: 'rating_detail'
|
||||
}
|
||||
});
|
||||
attitudePanelRef.value?.resetComment?.();
|
||||
clearReplyTarget();
|
||||
await getCommentsData({ replace: true });
|
||||
} catch (error) {
|
||||
uni.hideLoading();
|
||||
@@ -377,6 +429,7 @@ const switchTab = (tab) => {
|
||||
currentPage.value = 1;
|
||||
hasMore.value = true;
|
||||
commentError.value = '';
|
||||
clearReplyTarget();
|
||||
getCommentsData({ replace: true });
|
||||
};
|
||||
|
||||
@@ -413,20 +466,7 @@ const getCommentsData = async ({ replace = false } = {}) => {
|
||||
(Array.isArray(res?.data) ? res.data : []);
|
||||
const list = Array.isArray(rawList) ? rawList : [];
|
||||
|
||||
const formattedList = list.map(item => ({
|
||||
id: item.id,
|
||||
name: item.user?.nickname || '匿名用户',
|
||||
avatar: item.user?.avatar
|
||||
? (String(item.user.avatar).startsWith('http') ? item.user.avatar : `${FILE_BASE_URL}${item.user.avatar}`)
|
||||
: 'https://api.dicebear.com/7.x/avataaars/svg?seed=fallback',
|
||||
time: formatDate(item.createdAt) || '刚刚', // 如果后端返回了时间字段可以替换
|
||||
content: item.content,
|
||||
likes: item.likeCount || 0,
|
||||
isLiked: item.isLiked || false,
|
||||
badge: '', // 预留徽章字段
|
||||
badgeIcon: '',
|
||||
userAction: item.userAction || "" // 夯/顶级/人上人/NPC/拉
|
||||
}));
|
||||
const formattedList = list.map((item) => normalizeCommentItem(item));
|
||||
|
||||
if (currentPage.value === 1 || replace) {
|
||||
comments.value = formattedList;
|
||||
@@ -450,12 +490,29 @@ const retryLoadComments = () => {
|
||||
if (!comments.value.length) {
|
||||
currentPage.value = 1;
|
||||
}
|
||||
clearReplyTarget();
|
||||
getCommentsData({ replace: currentPage.value === 1 });
|
||||
};
|
||||
|
||||
const handleCommentLikeChange = ({ id, isLiked, likes }) => {
|
||||
const handleCommentLikeChange = ({ id, parentId, isReply, isLiked, likes }) => {
|
||||
comments.value = comments.value.map((item) => {
|
||||
if (item.id !== id) return item;
|
||||
if (!isReply && item.id !== id) return item;
|
||||
if (isReply && item.id !== parentId) return item;
|
||||
|
||||
if (isReply) {
|
||||
return {
|
||||
...item,
|
||||
replies: (item.replies || []).map((reply) => {
|
||||
if (reply.id !== id) return reply;
|
||||
return {
|
||||
...reply,
|
||||
isLiked,
|
||||
likes
|
||||
};
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
isLiked,
|
||||
@@ -531,6 +588,7 @@ const handleLoginSuccess = () => {
|
||||
hasMore.value = true;
|
||||
comments.value = [];
|
||||
commentError.value = '';
|
||||
clearReplyTarget();
|
||||
getDetailData();
|
||||
};
|
||||
|
||||
@@ -560,6 +618,7 @@ onPullDownRefresh(() => {
|
||||
hasMore.value = true;
|
||||
comments.value = [];
|
||||
commentError.value = '';
|
||||
clearReplyTarget();
|
||||
getDetailData();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user