From 3c7e5200624c39a636382ec03bdbe5fd77911cc2 Mon Sep 17 00:00:00 2001 From: zzc <1761997216@qq.com> Date: Mon, 15 Jun 2026 19:59:07 +0800 Subject: [PATCH] fix: pk comment --- api/pk.js | 54 ++ components/CommentItem/CommentItem.vue | 50 +- .../PkCommentSection/PkCommentSection.vue | 825 ++++++++++++++++++ pages/pk/index.vue | 29 +- 4 files changed, 954 insertions(+), 4 deletions(-) create mode 100644 components/PkCommentSection/PkCommentSection.vue diff --git a/api/pk.js b/api/pk.js index fcf2a0a..2fc0ffe 100644 --- a/api/pk.js +++ b/api/pk.js @@ -19,3 +19,57 @@ export const vote = async (data) => { data, }); }; + +/** + * 获取PK 评论列表 + * @param { pkId: string, page: number, orderBy: string } + * @param { orderBy: string } 排序字段,可选值:'hot' | 'new', + */ +export const fetchCommentList = async (data) => { + return request({ + url: "/api/rating/pk/comment/list", + method: "GET", + data, + }); +}; + +/** + * 获取PK 评论回复 + * @param { pkId: string, rootCommentId: string, page: number } + */ +export const fetchCommentReplyList = async (data) => { + return request({ + url: "/api/rating/pk/comment/replies", + method: "GET", + data, + }); +}; + +/** + * 发布PK 评论 + * @param { pkId: string, content: string, parentCommentId?: string, replyToCommentId?: string } + * @param { parentCommentId?: string } 父评论ID,回复时必填 + * @param { replyToCommentId?: string } 回复的评论ID,回复时必填 + */ +export const publishComment = async (data) => { + return request({ + url: "/api/rating/pk/comment", + method: "POST", + data, + }); +}; + +/** + * PK 评论 点赞 + * @param { commentId: string } + */ +export const likeComment = async (data) => { + return request({ + url: "/api/rating/pk/comment/like", + method: "POST", + data, + }); +}; + + + diff --git a/components/CommentItem/CommentItem.vue b/components/CommentItem/CommentItem.vue index 4fdc57b..3729b83 100644 --- a/components/CommentItem/CommentItem.vue +++ b/components/CommentItem/CommentItem.vue @@ -5,6 +5,13 @@ {{ localComment.name }} + + {{ localComment.choiceLabel }} + {{ localComment.badgeIcon }} @@ -89,6 +96,14 @@ const props = defineProps({ type: Object, required: true, default: () => ({}) + }, + likeHandler: { + type: Function, + default: null + }, + pageName: { + type: String, + default: 'rating_detail' } }); @@ -115,6 +130,8 @@ const buildCommentState = (comment = {}) => ({ ...comment, likes: Number(comment.likes || 0), isLiked: !!comment.isLiked, + choiceLabel: comment.choiceLabel || '', + choiceTone: comment.choiceTone || '', replyCount: Number(comment.replyCount || 0), repliesLoading: !!comment.repliesLoading, repliesLoaded: !!comment.repliesLoaded, @@ -200,7 +217,8 @@ const handleLike = async (target = null) => { }); try { - await topicItemCommentLike({ commentId: currentTarget.id }); + const likeRequest = props.likeHandler || topicItemCommentLike; + await likeRequest({ commentId: currentTarget.id }); uni.$trackRecord({ eventName: 'like_comment', eventType: 'like', @@ -209,7 +227,7 @@ const handleLike = async (target = null) => { customParams: { comment: currentTarget.content, isReply: currentTarget.id !== localComment.value.id, - page: 'rating_detail' + page: props.pageName } }); } catch (error) { @@ -303,6 +321,34 @@ const handleLike = async (target = null) => { .b-icon { font-size: 20rpx; margin-right: 6rpx; } .b-text { font-size: 20rpx; color: #666; font-weight: bold; } +.choice-tag { + display: inline-flex; + align-items: center; + height: 42rpx; + padding: 0 16rpx; + border-radius: 999rpx; + background: rgba(79, 70, 229, 0.08); + margin-right: 12rpx; +} + +.choice-tag--left { + background: rgba(92, 67, 245, 0.1); +} + +.choice-tag--right { + background: rgba(255, 141, 95, 0.12); +} + +.choice-tag-text { + font-size: 20rpx; + font-weight: 700; + color: #4f46e5; +} + +.choice-tag--right .choice-tag-text { + color: #ff7a45; +} + .c-like { display: flex; align-items: center; diff --git a/components/PkCommentSection/PkCommentSection.vue b/components/PkCommentSection/PkCommentSection.vue new file mode 100644 index 0000000..07631d9 --- /dev/null +++ b/components/PkCommentSection/PkCommentSection.vue @@ -0,0 +1,825 @@ + + + + + diff --git a/pages/pk/index.vue b/pages/pk/index.vue index a4fe493..4cc76ad 100644 --- a/pages/pk/index.vue +++ b/pages/pk/index.vue @@ -79,7 +79,18 @@ - + + + 暂时没有新的 PK 对局 当前没有可参与的随机对局,稍后再来看看有没有新的组合。 @@ -96,6 +107,7 @@ import { onLoad, onPullDownRefresh, onShareAppMessage, onShareTimeline } from "@ import { getStatusBarHeight } from "@/utils/system"; import { fetchRandomTopicList, vote } from "@/api/pk"; import { FILE_BASE_URL } from "@/utils/constants"; +import PkCommentSection from "@/components/PkCommentSection/PkCommentSection.vue"; import LoginPopup from "@/components/LoginPopup/LoginPopup.vue"; import { useUserStore } from "@/stores/user"; import { getShareReward } from "@/api/system"; @@ -104,6 +116,7 @@ import { getShareToken } from "@/utils/common"; const userStore = useUserStore(); const statusBarHeight = ref(getStatusBarHeight() || 44); const loginPopupRef = ref(null); +const commentSectionRef = ref(null); const loading = ref(false); const voting = ref(false); const currentPair = ref(null); @@ -112,6 +125,14 @@ const voteStats = ref({ leftPercent: 50, rightPercent: 50 }); const isLoggedIn = computed(() => !!userStore.token || !!userStore.userInfo?.nickName); const hasVoted = computed(() => !!selectedSide.value); +const selectedItemId = computed(() => { + if (!currentPair.value || !selectedSide.value) return ""; + return selectedSide.value === "left" ? currentPair.value.left.id : currentPair.value.right.id; +}); +const selectedItemLabel = computed(() => { + if (!currentPair.value || !selectedSide.value) return ""; + return selectedSide.value === "left" ? currentPair.value.left.name : currentPair.value.right.name; +}); const buildAvatarUrl = (avatar) => { if (!avatar) return "https://api.dicebear.com/7.x/avataaars/svg?seed=fallback"; @@ -269,7 +290,11 @@ const refreshPool = () => { loadNextPair(); }; -const handleLoginSuccess = () => {}; +const handleLoginSuccess = async () => { + if (hasVoted.value) { + await commentSectionRef.value?.refreshComments?.(); + } +}; onLoad(() => { loadNextPair();