Browse Source

feat(page): add tag recommendations to search page

main
Mohan 1 month ago
parent
commit
60c23e7680
  1. 67
      src/views/SearchView.vue

67
src/views/SearchView.vue

@ -1,8 +1,8 @@
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { searchApi } from '@/api/client'
import type { ArticleListItem } from '@/generated/api'
import { searchApi, tagApi } from '@/api/client'
import type { ArticleListItem, Tag } from '@/generated/api'
import ArticleCard from '@/components/ArticleCard.vue'
import Pagination from '@/components/Pagination.vue'
@ -17,6 +17,23 @@ const totalPages = ref(0)
const loading = ref(false)
const error = ref<string | null>(null)
const recommendedTags = ref<Tag[]>([])
async function loadRecommendedTags() {
try {
const resp = await tagApi.apiTagsGet()
const tags = resp.data.data ?? []
recommendedTags.value = [...tags].sort((a, b) => b.articleCount - a.articleCount).slice(0, 8)
} catch (e) {
console.error(e)
recommendedTags.value = []
}
}
function goTag(tag: Tag) {
router.push({ name: 'Home', query: { tag: tag.slug } })
}
async function doSearch() {
const q = keyword.value.trim()
if (!q) {
@ -61,6 +78,7 @@ watch(
)
onMounted(() => {
loadRecommendedTags()
if (keyword.value) doSearch()
})
</script>
@ -72,6 +90,15 @@ onMounted(() => {
<button class="search-btn" type="submit">搜索</button>
</form>
<div v-if="recommendedTags.length" class="search-recommend">
<span class="section-label">标签推荐</span>
<div class="tag-chips">
<button v-for="tag in recommendedTags" :key="tag.id" class="tag-chip" @click="goTag(tag)">
{{ tag.name }}
</button>
</div>
</div>
<p v-if="error" class="error-text">{{ error }}</p>
<p v-else-if="loading" class="hint-text">搜索中...</p>
<template v-else>
@ -92,6 +119,42 @@ onMounted(() => {
margin-bottom: 20px;
}
.search-recommend {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 20px;
}
.section-label {
color: var(--ac-text-secondary);
font-size: 13px;
letter-spacing: 0.1em;
}
.tag-chips {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tag-chip {
height: 26px;
padding: 0 12px;
background: var(--ac-primary-bg);
color: var(--ac-primary-ink);
border: 1px solid var(--ac-primary);
border-radius: var(--song-radius-s);
font-size: 13px;
cursor: pointer;
transition: background var(--song-dur-1) var(--song-ease);
}
.tag-chip:hover {
background: var(--ac-active);
}
.search-input {
flex: 1;
padding: 10px 14px;

Loading…
Cancel
Save