diff --git a/components/CommentItem/CommentItem.vue b/components/CommentItem/CommentItem.vue index 510afb5..9fb1080 100644 --- a/components/CommentItem/CommentItem.vue +++ b/components/CommentItem/CommentItem.vue @@ -64,6 +64,18 @@ const handleLike = async () => { try { // 调用点赞接口 (点赞和取消点赞为同一个接口) await topicItemCommentLike({ commentId: props.comment.id }); + // 记录点赞事件 + uni.$trackRecord({ + eventName: 'like_comment', + eventType: 'like', + elementId: `comment_${props.comment.id}`, + elementContent: `评论项_${props.comment.name}`, + customParams: { + comment: props.comment.content, + page: 'rating_detail' + } + }); + uni.showToast({ title: '操作成功', icon: 'success' }); } catch (error) { // 接口调用失败,回滚 UI 状态 isLiked.value = !isLiked.value; diff --git a/pages.json b/pages.json index 67d7430..b14ed03 100644 --- a/pages.json +++ b/pages.json @@ -3,7 +3,7 @@ { "path": "pages/index/index", "style": { - "navigationBarTitleText": "全民评分", + "navigationBarTitleText": "夯拉评分", "enablePullDownRefresh": true, "navigationStyle": "custom", "backgroundColor": "#FFFFFF" @@ -67,7 +67,7 @@ { "path": "pages/rating/index", "style": { - "navigationBarTitleText": "全民评分", + "navigationBarTitleText": "夯拉评分", "navigationStyle": "custom", "enablePullDownRefresh": true } diff --git a/pages/index/index.vue b/pages/index/index.vue index 6f76ee0..88c9fa6 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -10,7 +10,7 @@ @tap="handleLogin" /> - 全民评分 + 夯拉评分 看看全国网友怎么评分 @@ -136,58 +136,27 @@ const loadTopicList = async (categoryId, page = 1) => { const switchCategory = (categoryId) => { if (currentCategoryId.value === categoryId) return; currentCategoryId.value = categoryId; - - // 切换分类时重新加载数据 + uni.$trackRecord({ + eventName: 'switch_category', + eventType: 'click', + elementId: `category_${categoryId}`, + elementContent: categories.value.find(c => c.id === categoryId)?.title || '未知分类', + }); + // 切换分类时重新加载数据 currentPage.value = 1; hasMore.value = true; loadTopicList(categoryId, currentPage.value); }; -const mockData = [ - { - id: 1, - title: '你心中的千古一帝', - participants: '23.5万', - heat: '98k', - items: [ - { id: 1, name: '李世民', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=1', score: '9.8' }, - { id: 2, name: '秦始皇', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=2', score: '9.5' }, - { id: 3, name: '康熙', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=3', score: '9.2' }, - ], - aiSummary: '多数用户认为李世民综合能力最强,兼具文治武功。', - tags: ['历史', '皇帝', '争议'] - }, - { - id: 2, - title: '国产手机系统谁最强', - participants: '15万', - heat: '76k', - items: [ - { id: 1, name: 'iOS', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=4', score: '8.5' }, - { id: 2, name: 'HyperOS', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=5', score: '8.2' }, - { id: 3, name: 'OriginOS', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=6', score: '8.0' }, - ], - aiSummary: '系统流畅度与动效是用户关注的核心,底层优化成为评分关键。', - tags: ['数码', '手机', '测评'] - }, - { - id: 3, - title: '最值得定居的城市', - participants: '12.8万', - heat: '62k', - items: [ - { id: 1, name: '成都', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=7', score: '9.2' }, - { id: 2, name: '杭州', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=8', score: '8.9' }, - { id: 3, name: '厦门', avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=9', score: '8.7' }, - ], - aiSummary: '宜居性与就业机会是主要博弈点,慢节奏生活深受青睐。', - tags: ['城市', '生活', '推荐'] - } -]; - -const topicList = ref([...mockData]); +const topicList = ref([]); const goToRating = (topicId, itemId) => { + uni.$trackRecord({ + eventName: 'jumpto_rating', + eventType: 'jump', + elementId: `topic_${topicId}`, + elementContent: `主题${topicId}`, + }); uni.navigateTo({ url: `/pages/rating/index?topicId=${topicId}&itemId=${itemId}` }); @@ -248,7 +217,7 @@ onShareAppMessage(async () => { const shareToken = await getShareToken("index"); getShareReward(); return { - title: "全民评分", + title: "夯拉评分", path: "/pages/index/index?shareToken=" + shareToken, }; }); @@ -257,7 +226,7 @@ onShareTimeline(async () => { const shareToken = await getShareToken("index"); getShareReward(); return { - title: "全民评分", + title: "夯拉评分", query: `shareToken=${shareToken}`, }; }); diff --git a/pages/rating/detail.vue b/pages/rating/detail.vue index 5c22af5..e0cc5be 100644 --- a/pages/rating/detail.vue +++ b/pages/rating/detail.vue @@ -5,7 +5,7 @@ - 全民评分 + 夯拉评分 @@ -50,7 +50,7 @@ /> - + @@ -165,6 +165,20 @@ const handleActionChange = async (action) => { if (!isCancel && successPopupRef.value) { successPopupRef.value.show(action); } + uni.$trackRecord({ + eventName: 'rating', + eventType: 'rating', + elementId: `item_${item.id}`, + elementContent: `评分项_${item.name}`, + customParams: { + scoreType: action.scoreType, + action: action.label, + topicId: currentTopicId.value, + topicTitle: topicData.value.title, + score: item.scoreAvg, + page: 'rating_detail' + } + }); } catch (error) { detailData.value.userAction = originAction; detailData.value.score = originScore; @@ -196,6 +210,16 @@ const handleSendComment = async (payload) => { currentPage.value = 1; hasMore.value = true; comments.value = []; + uni.$trackRecord({ + eventName: 'comment', + eventType: 'comment', + elementId: `item_${item.id}`, + elementContent: `评论项_${item.name}`, + customParams: { + comment: payload.content, + page: 'rating_detail' + } + }); getCommentsData(); } catch (error) { uni.hideLoading(); diff --git a/pages/rating/index.vue b/pages/rating/index.vue index f2d6dfe..b28084d 100644 --- a/pages/rating/index.vue +++ b/pages/rating/index.vue @@ -7,9 +7,9 @@ - + - 全民评分 + 夯拉评分 @@ -273,7 +273,6 @@ const loadItems = async (topicId, page = 1) => { ratingItems.value = [...ratingItems.value, ...list]; hasMore.value = list.length >= 10; // 假设 pageSize 是 10 } catch (error) { - console.error("获取评分项列表失败:", error); hasMore.value = false; } finally { loading.value = false; @@ -330,6 +329,20 @@ const handleAction = async (item, action) => { if (!isCancel && successPopupRef.value) { successPopupRef.value.show(action); } + uni.$trackRecord({ + eventName: 'rating', + eventType: 'rating', + elementId: `item_${item.id}`, + elementContent: `评分项_${item.name}`, + customParams: { + scoreType: action.scoreType, + action: action.label, + topicId: currentTopicId.value, + topicTitle: topicData.value.title, + score: item.scoreAvg, + page: 'rating' + } + }); } catch (error) { item.userAction = originAction; item.scoreAvg = originScore; @@ -337,6 +350,12 @@ const handleAction = async (item, action) => { }; const goToDetail = (itemId) => { + uni.$trackRecord({ + eventName: 'jumpto_detail', + eventType: 'jump', + elementId: `item_${itemId}`, + elementContent: `评分项${itemId}`, + }); uni.navigateTo({ url: `/pages/rating/detail?itemId=${itemId}&topicId=${currentTopicId.value}` }); @@ -417,7 +436,6 @@ onReachBottom(() => { width: 56rpx; height: 56rpx; border-radius: 50%; - background: linear-gradient(135deg, #001f3f, #0088a9); display: flex; align-items: center; justify-content: center; diff --git a/pages/release/index.vue b/pages/release/index.vue index a6b0842..5f0d11f 100644 --- a/pages/release/index.vue +++ b/pages/release/index.vue @@ -151,7 +151,7 @@ - + @@ -321,6 +321,17 @@ const handleSubmit = async () => { participants: participants.value, }; await releaseTopic(payload); + + // 记录发布事件 + uni.$trackRecord({ + eventName: 'release_topic', + eventType: 'release', + elementContent: `话题_${payload.title}`, + customParams: { + title: payload.title, + categoryId: payload.categoryId, + } + }); uni.hideLoading(); uni.showToast({ diff --git a/static/images/logo.jpg b/static/images/logo.jpg new file mode 100644 index 0000000..ede38ec Binary files /dev/null and b/static/images/logo.jpg differ diff --git a/utils/common.js b/utils/common.js index 0a6cfc5..121d409 100644 --- a/utils/common.js +++ b/utils/common.js @@ -154,6 +154,15 @@ export const getShareToken = async (scene, targetId = "") => { return shareTokenRes?.shareToken || ""; }; +/** + * 记录用户行为事件 + * @param {Object} event 事件对象,包含事件名称和参数 + * eventName 事件名称,例如 'switchCategory' + * eventType 事件类型,例如 'click',可选 + * elementId 事件元素 ID,例如 'category_123',可选 + * elementContent 事件元素内容,例如 '分类1',可选 + * customParams 自定义参数,例如 { categoryId: 123 },可选 + */ export const trackRecord = (event) => { const pages = getCurrentPages(); // 核心修复:在小程序刚启动或页面尚未压栈时,pages 可能为空数组