From b778216afbed5a467f1869336e53a2b463ce2fae Mon Sep 17 00:00:00 2001 From: zzc <1761997216@qq.com> Date: Thu, 21 May 2026 18:00:07 +0800 Subject: [PATCH] feat: release --- api/topic.js | 19 +++ components/TopicCard/TopicCard.vue | 247 ++++++++++++++++++++++++++++ pages/index/index.vue | 250 ++--------------------------- 3 files changed, 275 insertions(+), 241 deletions(-) create mode 100644 components/TopicCard/TopicCard.vue diff --git a/api/topic.js b/api/topic.js index 38c9889..84723fd 100644 --- a/api/topic.js +++ b/api/topic.js @@ -1,5 +1,6 @@ import { request } from "@/utils/request.js"; +// 发布主题 export const releaseTopic = async (data) => { return request({ url: "/api/rating/topic/release", @@ -8,6 +9,7 @@ export const releaseTopic = async (data) => { }); }; +// 获取主题分类列表 export const fetchTopicCategories = async (data) => { return request({ url: "/api/rating/topic/category/list", @@ -15,9 +17,26 @@ export const fetchTopicCategories = async (data) => { }); }; +// 根据分类ID获取主题列表 export const fetchTopicList = async (categoryId, page = 1) => { return request({ url: `/api/rating/topic/list/${categoryId}?page=${page}`, method: "GET", }); }; + +// 获取主题详情 +export const fetchTopicDetail = async (topicId) => { + return request({ + url: `/api/rating/topic/detail/${topicId}`, + method: "GET", + }); +}; + +// 获取主题下的评分项 +export const fetchTopicRatingItems = async (topicId, page = 1) => { + return request({ + url: `/api/rating/topic/item/list/${topicId}?page=${page}`, + method: "GET", + }); +}; diff --git a/components/TopicCard/TopicCard.vue b/components/TopicCard/TopicCard.vue new file mode 100644 index 0000000..74d1db8 --- /dev/null +++ b/components/TopicCard/TopicCard.vue @@ -0,0 +1,247 @@ + + + + + \ No newline at end of file diff --git a/pages/index/index.vue b/pages/index/index.vue index cb54ddc..6f76ee0 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -37,53 +37,12 @@ - - - - {{ topic.title }} - - - - {{ topic.participants }}人参与 - - - - 热度 {{ topic.heat }} - - - - - - - - {{ index + 1 }} - - {{ item.name }} - {{ item.score }} - - - - - - - - AI总结: - {{ topic.aiSummary }} - - - - - - - #{{ tag }} - - - + @@ -112,6 +71,7 @@ import { getShareReward } from "@/api/system"; import { fetchTopicList, fetchTopicCategories } from "@/api/topic"; import { getShareToken, saveViewRequest } from "@/utils/common.js"; import LoginPopup from "@/components/LoginPopup/LoginPopup.vue"; +import TopicCard from "@/components/TopicCard/TopicCard.vue"; import adManager from "@/utils/adManager.js"; const userStore = useUserStore(); @@ -131,7 +91,7 @@ const loadCategories = async () => { const list = res?.data?.list || res?.list || res || []; // 增加一个“全部”的默认选项,id 置空 - categories.value = [{ id: '', title: '全部' }, ...list]; + categories.value = [{ id: 'recommend', title: '推荐' }, ...list]; // 初始化选中的ID为“全部” if (!currentCategoryId.value && categories.value.length > 0) { @@ -139,7 +99,7 @@ const loadCategories = async () => { } // 加载初始列表 - loadTopicList(currentCategoryId.value, currentPage.value); + // loadTopicList(currentCategoryId.value, currentPage.value); } catch (error) { console.error("获取分类失败:", error); // 兜底数据 @@ -162,7 +122,6 @@ const loadTopicList = async (categoryId, page = 1) => { const res = await fetchTopicList(categoryId, page); // 提取真实数据数组 const list = res?.list || []; - // 合并数据 topicList.value = [...topicList.value, ...list]; hasMore.value = list.length >= 5; @@ -407,197 +366,6 @@ onShareTimeline(async () => { padding: 24rpx 32rpx; } -.topic-card { - background-color: #ffffff; - border-radius: 40rpx; /* 增加圆角,更圆润 */ - padding: 36rpx; /* 稍微增加内边距,让内容更呼吸 */ - margin-bottom: 36rpx; - box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.04); /* 更柔和、扩散的阴影 */ - transition: transform 0.3s ease, box-shadow 0.3s ease; /* 增加过渡动画 */ -} - -.topic-card:active { - transform: scale(0.98); /* 点击时微缩放效果 */ - box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.02); -} - -.topic-header { - margin-bottom: 32rpx; -} - -.topic-title { - font-size: 38rpx; /* 稍微调大标题 */ - font-weight: 800; /* 加粗标题 */ - color: #1a1a1a; - margin-bottom: 16rpx; - display: block; - letter-spacing: 1rpx; /* 增加字间距 */ -} - -.topic-stats { - display: flex; - align-items: center; -} - -.stat-item { - display: flex; - align-items: center; - font-size: 24rpx; - color: #888; /* 稍微调浅次要文本颜色 */ - margin-right: 32rpx; - background-color: #f8f9fa; /* 增加极浅的背景色块 */ - padding: 6rpx 16rpx; - border-radius: 100rpx; /* 完全圆角的统计标签 */ -} - -.stat-item.heat { - color: #ff4d4f; - background-color: #fff1f0; /* 热度专属浅红背景 */ -} - -.stat-icon { - width: 24rpx; - height: 24rpx; - margin-right: 8rpx; - display: inline-block; - background-size: cover; -} - -.icon-group { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23999999'%3E%3Cpath d='M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z'/%3E%3C/svg%3E"); -} - -.icon-fire { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ff4d4f'%3E%3Cpath d='M19.48 13.03c-.02-.19-.13-.36-.29-.46-.17-.11-.38-.13-.56-.05-.98.42-2.12.3-2.92-.31-1.07-.81-1.55-2.22-1.28-3.75.12-.66.1-1.32-.06-1.97-.24-.95-1.1-1.6-2.09-1.58-1 .02-1.83.74-2 1.72-.25 1.55-.95 2.94-2 4.02-1.38 1.41-2.05 3.39-1.85 5.4.2 2.05 1.42 3.86 3.25 4.82 1.37.72 2.94 1.01 4.5.83 2.74-.32 5.06-2.28 5.86-4.95.23-.75.29-1.52.19-2.28-.06-.5-.21-.99-.41-1.45l-.34-.99zm-4.98 6.47c-1.37 0-2.5-1.13-2.5-2.5s1.13-2.5 2.5-2.5 2.5 1.13 2.5 2.5-1.13 2.5-2.5 2.5z'/%3E%3C/svg%3E"); -} - -.rank-list { - margin-bottom: 32rpx; - background-color: #fafbfc; /* 增加极浅的灰底色作为容器 */ - border-radius: 32rpx; - padding: 16rpx 24rpx; -} - -.rank-item { - display: flex; - align-items: center; - padding: 16rpx 0; - border-bottom: 2rpx dashed rgba(0, 0, 0, 0.03); /* 柔和的虚线分割 */ -} - -.rank-item:last-child { - border-bottom: none; -} - -.rank-num { - width: 44rpx; - font-size: 32rpx; - font-weight: 800; - text-align: center; - margin-right: 16rpx; - font-style: italic; /* 数字增加倾斜感,更动感 */ -} - -.rank-1 { - color: #2953ff; - font-size: 36rpx; /* 第一名数字更大 */ -} - -.rank-2 { - color: #ff8f00; /* 第二名橘色 */ -} - -.rank-3 { - color: #ffc107; /* 第三名黄色 */ -} - -.item-avatar { - width: 76rpx; - height: 76rpx; - border-radius: 50%; - margin-right: 24rpx; - background-color: #f0f0f0; - box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.06); /* 头像增加微阴影 */ - border: 4rpx solid #fff; /* 头像增加白边 */ -} - -.item-name { - flex: 1; - font-size: 32rpx; - color: #2c2c2c; - font-weight: 500; -} - -.item-score { - font-size: 36rpx; - font-weight: 800; - font-family: 'DIN Alternate', sans-serif; /* 推荐使用数字字体,如果没有则回退到 sans-serif */ -} - -.score-1 { - color: #2953ff; -} - -.score-2 { - color: #ff8f00; -} - -.score-3 { - color: #ffc107; -} - -.ai-summary { - display: flex; - align-items: flex-start; - padding: 24rpx 32rpx; - background: linear-gradient(135deg, #f8f6ff 0%, #ffffff 100%); /* 增加极浅的渐变背景 */ - border: 2rpx solid rgba(157, 91, 254, 0.15); /* 边框更加柔和透明 */ - border-radius: 24rpx; - margin-bottom: 24rpx; - box-shadow: 0 4rpx 16rpx rgba(157, 91, 254, 0.04); /* 增加紫色的微光阴影 */ -} - -.ai-icon { - width: 36rpx; - height: 36rpx; - margin-right: 16rpx; - margin-top: 2rpx; - flex-shrink: 0; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%237B46F1'%3E%3Cpath d='M12 2a2 2 0 0 1 2 2c0 .74-.4 1.39-1 1.73V7h5a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h5V5.73A2 2 0 0 1 10 4a2 2 0 0 1 2-2zm-3 8a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm6 0a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z'/%3E%3C/svg%3E"); -} - -.summary-text { - flex: 1; - font-size: 28rpx; - line-height: 1.6; -} - -.summary-label { - color: #7b46f1; /* 柔和一点的紫色 */ - font-weight: 800; -} - -.summary-content { - color: #4a4a4a; -} - -.tag-list { - display: flex; - flex-wrap: wrap; - gap: 16rpx; -} - -.tag { - background-color: #f4eaff; - padding: 6rpx 20rpx; - border-radius: 100rpx; -} - -.tag text { - color: #9d5bfe; - font-size: 22rpx; -} - .load-more { text-align: center; padding: 30rpx 0;