diff --git a/api/topicItem.js b/api/topicItem.js index 6a0340c..9a9ca12 100644 --- a/api/topicItem.js +++ b/api/topicItem.js @@ -30,13 +30,25 @@ export const topicItemCommentLike = async (data) => { }; // 获取评论列表 -export const topicItemCommentList = async (topicId, itemId, page = 1, orderBy = 1) => { +export const topicItemCommentList = async (topicId, itemId, page = 1, orderBy = 'hot') => { return request({ url: `/api/rating/topic/comment/item/list?topicId=${topicId}&itemId=${itemId}&page=${page}&orderBy=${orderBy}`, method: "GET", }); }; +/* + * 获取评论回复列表 + * @param {rootCommentId: string, page: number} data + */ +export const topicItemCommentReplyList = async (data) => { + return request({ + url: "/api/rating/topic/comment/replies", + method: "GET", + data, + }); +}; + // 获取评分项详情 export const fetchTopicRatingItems = async (itemId) => { return request({ diff --git a/components/AttitudePanel/AttitudePanel.vue b/components/AttitudePanel/AttitudePanel.vue index 33d26e3..906e3bd 100644 --- a/components/AttitudePanel/AttitudePanel.vue +++ b/components/AttitudePanel/AttitudePanel.vue @@ -15,13 +15,6 @@ {{ action.label }} - - - 正在回复 - @{{ replyTarget.replyToName || replyTarget.name }} - - 取消 - props.initialAction, (newVal) => { }); const commentText = ref(''); -const inputPlaceholder = computed(() => { - if (props.replyTarget?.replyToName || props.replyTarget?.name) { - return `回复 @${props.replyTarget.replyToName || props.replyTarget.name}...`; - } - return '说点什么吧...'; -}); +const inputPlaceholder = computed(() => '说点什么吧...'); const actions = [ { label: '拉', value: 'terrible', emoji: '👎', score: 2, scoreType:1 }, @@ -101,10 +85,6 @@ const handleSend = () => { }); }; -const handleCancelReply = () => { - emit('cancel-reply'); -}; - const resetComment = () => { commentText.value = ''; }; @@ -178,42 +158,6 @@ defineExpose({ padding: 8rpx 8rpx 8rpx 32rpx; } -.reply-banner { - margin-bottom: 18rpx; - padding: 16rpx 20rpx; - border-radius: 18rpx; - background: linear-gradient(135deg, rgba(29, 78, 216, 0.08) 0%, rgba(124, 58, 237, 0.08) 100%); - display: flex; - align-items: center; - justify-content: space-between; - gap: 20rpx; -} - -.reply-banner-main { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 10rpx; -} - -.reply-banner-label { - font-size: 22rpx; - color: #6b7280; -} - -.reply-banner-user { - font-size: 24rpx; - font-weight: 700; - color: #4338ca; -} - -.reply-banner-cancel { - flex-shrink: 0; - font-size: 24rpx; - font-weight: 600; - color: #111827; -} - .comment-input { flex: 1; height: 72rpx; diff --git a/components/CommentItem/CommentItem.vue b/components/CommentItem/CommentItem.vue index b46862e..4fdc57b 100644 --- a/components/CommentItem/CommentItem.vue +++ b/components/CommentItem/CommentItem.vue @@ -22,7 +22,15 @@ 回复 - {{ localComment.replyCount }} 条回复 + + 查看 {{ localComment.replyCount }} 条回复 + + 回复加载中... + {{ localComment.replyCount }} 条回复 @@ -54,6 +62,17 @@ + + + + 查看更多回复 + + 加载更多中... + @@ -73,7 +92,7 @@ const props = defineProps({ } }); -const emit = defineEmits(['need-login', 'like-change', 'reply']); +const emit = defineEmits(['need-login', 'like-change', 'reply', 'toggle-replies', 'more-replies']); const userStore = useUserStore(); const isLoggedIn = computed(() => !!userStore.token || !!userStore.userInfo?.nickName); @@ -97,6 +116,10 @@ const buildCommentState = (comment = {}) => ({ likes: Number(comment.likes || 0), isLiked: !!comment.isLiked, replyCount: Number(comment.replyCount || 0), + repliesLoading: !!comment.repliesLoading, + repliesLoaded: !!comment.repliesLoaded, + repliesHasMore: !!comment.repliesHasMore, + repliesPage: Number(comment.repliesPage || 1), replies: Array.isArray(comment.replies) ? comment.replies.map(buildReplyItem) : [] }); @@ -335,13 +358,15 @@ const handleLike = async (target = null) => { .c-action-btn, .reply-btn, -.c-action-count { +.c-action-count, +.c-action-link { font-size: 22rpx; color: #8b8f98; } .c-action-btn, -.reply-btn { +.reply-btn, +.c-action-link { font-weight: 600; } @@ -423,4 +448,19 @@ const handleLike = async (target = null) => { width: 28rpx; height: 28rpx; } + +.reply-panel-footer { + padding: 8rpx 0 10rpx 72rpx; +} + +.reply-more-btn, +.reply-more-loading { + font-size: 22rpx; + color: #4f46e5; + font-weight: 600; +} + +.reply-more-loading { + color: #9ca3af; +} diff --git a/pages/rating/detail.vue b/pages/rating/detail.vue index 17361dc..6ca2533 100644 --- a/pages/rating/detail.vue +++ b/pages/rating/detail.vue @@ -50,10 +50,8 @@ ref="attitudePanelRef" :initial-action="currentAction" :sending="isSendingComment" - :reply-target="replyTarget" @action-change="handleActionChange" @send-comment="handleSendComment" - @cancel-reply="clearReplyTarget" /> @@ -124,6 +122,8 @@ @need-login="openLoginPopup" @like-change="handleCommentLikeChange" @reply="handleReplyComment" + @toggle-replies="handleToggleReplies" + @more-replies="handleLoadMoreReplies" /> @@ -135,22 +135,62 @@ + + + + + 回复 + @{{ replyTarget?.replyToName || 'Ta' }} + + 取消 + + + + + + +