feat: use community categories for topic navigation
This commit is contained in:
@@ -57,6 +57,11 @@ export function getTagLists() {
|
||||
return request.get({ url: '/community/tagLists' })
|
||||
}
|
||||
|
||||
// 社区分类列表
|
||||
export function getCommunityCategoryLists() {
|
||||
return request.get({ url: '/community/categoryLists' })
|
||||
}
|
||||
|
||||
// 社区用户统计(积分、关注等)
|
||||
export function getCommunityUserStats() {
|
||||
return request.get({ url: '/community/userStats' })
|
||||
|
||||
@@ -31,11 +31,12 @@
|
||||
<view class="community-topics">
|
||||
<scroll-view scroll-x class="community-topics__scroll" :show-scrollbar="false">
|
||||
<view class="community-topics__list">
|
||||
<view v-for="tag in displayTags" :key="tag.id" class="community-topic"
|
||||
:class="{ 'community-topic--active': activeTagId === tag.id }" @tap="selectTag(tag)">
|
||||
<image class="community-topic__icon-image" :src="tag.icon || DEFAULT_TOPIC_ICON" mode="aspectFill"
|
||||
@error="handleTopicIconError(tag)" />
|
||||
<text>{{ tag.name }}</text>
|
||||
<view v-for="category in displayCategories" :key="category.id" class="community-topic"
|
||||
:class="{ 'community-topic--active': activeCategoryId === category.id }"
|
||||
@tap="selectCategory(category)">
|
||||
<image class="community-topic__icon-image" :src="category.icon || DEFAULT_TOPIC_ICON"
|
||||
mode="aspectFill" @error="handleTopicIconError(category)" />
|
||||
<text>{{ category.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -47,7 +48,7 @@
|
||||
<text class="community-list__eyebrow">SPORTS COMMUNITY</text>
|
||||
<text class="community-list__title">{{ feedTitle }}</text>
|
||||
</view>
|
||||
<text v-if="activeTagName" class="community-list__selected"># {{ activeTagName }}</text>
|
||||
<text v-if="activeCategoryName" class="community-list__selected">{{ activeCategoryName }}</text>
|
||||
</view>
|
||||
|
||||
<view v-if="loading && postList.length === 0" class="community-loading">
|
||||
@@ -83,7 +84,13 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { getCommunityPosts, getCommunityUserStats, getTagLists, purchasePost, toggleLike } from '@/api/community'
|
||||
import {
|
||||
getCommunityCategoryLists,
|
||||
getCommunityPosts,
|
||||
getCommunityUserStats,
|
||||
purchasePost,
|
||||
toggleLike
|
||||
} from '@/api/community'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import AiAssistantEntry from '@/components/ai-assistant-entry/ai-assistant-entry.vue'
|
||||
@@ -92,11 +99,12 @@ import PostCard from '@/packages_community/components/post-card.vue'
|
||||
type FeedKey = 'recommend' | 'follow' | 'hot' | 'topic'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const COMMUNITY_ACTIVE_TAG_KEY = 'community_active_tag'
|
||||
const COMMUNITY_ACTIVE_CATEGORY_KEY = 'community_active_category'
|
||||
const LEGACY_COMMUNITY_ACTIVE_TAG_KEY = 'community_active_tag'
|
||||
const statusBarHeight = ref(0)
|
||||
const activeFeed = ref<FeedKey>('recommend')
|
||||
const activeTagId = ref(0)
|
||||
const tagList = ref<any[]>([])
|
||||
const activeCategoryId = ref(0)
|
||||
const categoryList = ref<any[]>([])
|
||||
const postList = ref<any[]>([])
|
||||
const userPoints = ref<number | null>(null)
|
||||
const loading = ref(false)
|
||||
@@ -118,22 +126,26 @@ const feedTabs: Array<{ key: FeedKey; label: string }> = [
|
||||
const isLogin = computed(() => userStore.isLogin)
|
||||
const userPointsText = computed(() => (isLogin.value ? String(userPoints.value ?? 0) : '登录'))
|
||||
const feedTitle = computed(() => ({ recommend: '精选讨论', follow: '关注动态', hot: '热门话题', topic: '话题广场' }[activeFeed.value]))
|
||||
const activeTagName = computed(() => tagList.value.find((tag) => tag.id === activeTagId.value)?.name || '')
|
||||
const activeCategoryName = computed(() => categoryList.value.find(
|
||||
(category) => category.id === activeCategoryId.value
|
||||
)?.name || '')
|
||||
|
||||
const displayTags = computed(() => {
|
||||
return tagList.value.map((tag) => ({
|
||||
...tag,
|
||||
icon: typeof tag.icon === 'string' ? tag.icon.trim() : ''
|
||||
const displayCategories = computed(() => {
|
||||
return categoryList.value.map((category) => ({
|
||||
...category,
|
||||
icon: typeof category.icon === 'string' ? category.icon.trim() : ''
|
||||
}))
|
||||
})
|
||||
|
||||
const handleTopicIconError = (tag: any) => {
|
||||
tag.icon = DEFAULT_TOPIC_ICON
|
||||
const handleTopicIconError = (category: any) => {
|
||||
category.icon = DEFAULT_TOPIC_ICON
|
||||
}
|
||||
|
||||
const getSavedActiveTag = () => {
|
||||
const tagId = Number(uni.getStorageSync(COMMUNITY_ACTIVE_TAG_KEY))
|
||||
return Number.isFinite(tagId) && tagId > 0 ? tagId : 0
|
||||
const getSavedActiveCategory = () => {
|
||||
const savedValue = uni.getStorageSync(COMMUNITY_ACTIVE_CATEGORY_KEY)
|
||||
|| uni.getStorageSync(LEGACY_COMMUNITY_ACTIVE_TAG_KEY)
|
||||
const categoryId = Number(savedValue)
|
||||
return Number.isFinite(categoryId) && categoryId > 0 ? categoryId : 0
|
||||
}
|
||||
|
||||
const goSearch = () => uni.navigateTo({ url: '/pages/search/search' })
|
||||
@@ -159,14 +171,22 @@ const loadUserPoints = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const fetchTags = async () => {
|
||||
const fetchCategories = async () => {
|
||||
try {
|
||||
tagList.value = (await getTagLists()) || []
|
||||
if (activeTagId.value && !tagList.value.some((tag) => tag.id === activeTagId.value)) {
|
||||
activeTagId.value = 0
|
||||
categoryList.value = (await getCommunityCategoryLists()) || []
|
||||
if (activeCategoryId.value && !categoryList.value.some(
|
||||
(category) => category.id === activeCategoryId.value
|
||||
)) {
|
||||
activeCategoryId.value = 0
|
||||
uni.removeStorageSync(COMMUNITY_ACTIVE_CATEGORY_KEY)
|
||||
uni.removeStorageSync(LEGACY_COMMUNITY_ACTIVE_TAG_KEY)
|
||||
if (activeFeed.value === 'topic') fetchPosts(true)
|
||||
} else if (activeCategoryId.value) {
|
||||
uni.setStorageSync(COMMUNITY_ACTIVE_CATEGORY_KEY, activeCategoryId.value)
|
||||
uni.removeStorageSync(LEGACY_COMMUNITY_ACTIVE_TAG_KEY)
|
||||
}
|
||||
} catch (_error) {
|
||||
tagList.value = []
|
||||
categoryList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +216,7 @@ const fetchPosts = async (reset = false) => {
|
||||
if (activeFeed.value === 'follow') params.follow = 1
|
||||
if (activeFeed.value === 'hot') params.is_hot = 1
|
||||
if (activeFeed.value === 'topic') params.is_topic = 1
|
||||
if (activeTagId.value > 0) params.tag_id = activeTagId.value
|
||||
if (activeCategoryId.value > 0) params.category_id = activeCategoryId.value
|
||||
const response = await getCommunityPosts(params)
|
||||
const rawList = response?.lists || []
|
||||
if (requestId !== fetchRequestId.value) return
|
||||
@@ -226,16 +246,16 @@ const switchFeed = (feed: FeedKey) => {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (activeFeed.value === feed && (feed !== 'topic' || activeTagId.value === 0)) return
|
||||
if (activeFeed.value === feed && (feed !== 'topic' || activeCategoryId.value === 0)) return
|
||||
activeFeed.value = feed
|
||||
if (feed !== 'topic') activeTagId.value = 0
|
||||
if (feed !== 'topic') activeCategoryId.value = 0
|
||||
fetchPosts(true)
|
||||
}
|
||||
|
||||
const selectTag = (tag: any) => {
|
||||
const selectCategory = (category: any) => {
|
||||
activeFeed.value = 'topic'
|
||||
activeTagId.value = tag.id
|
||||
uni.setStorageSync(COMMUNITY_ACTIVE_TAG_KEY, tag.id)
|
||||
activeCategoryId.value = category.id
|
||||
uni.setStorageSync(COMMUNITY_ACTIVE_CATEGORY_KEY, category.id)
|
||||
fetchPosts(true)
|
||||
}
|
||||
|
||||
@@ -328,9 +348,9 @@ onMounted(() => {
|
||||
// #ifdef APP-PLUS || MP
|
||||
statusBarHeight.value = systemInfo.statusBarHeight || 44
|
||||
// #endif
|
||||
activeTagId.value = getSavedActiveTag()
|
||||
if (activeTagId.value) activeFeed.value = 'topic'
|
||||
fetchTags()
|
||||
activeCategoryId.value = getSavedActiveCategory()
|
||||
if (activeCategoryId.value) activeFeed.value = 'topic'
|
||||
fetchCategories()
|
||||
fetchPosts(true)
|
||||
loadUserPoints()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user