feat: 当月热门笑话 + 统计面板,删除首页清除筛选按钮
- 后端新增 GET /api/jokes/hot-monthly(当月浏览量 top 10) - 后端新增 GET /api/jokes/stats(公开统计:总数/审核/待审/浏览等) - 右侧栏热门改为当月热门笑话 - 右侧栏新增网站统计区(笑话总数/已审核/待审核/总浏览) - 首页删除清除筛选按钮
This commit is contained in:
+13
-5
@@ -58,6 +58,7 @@
|
||||
:hot-jokes="hotJokes"
|
||||
:types="allTypes"
|
||||
:crowds="allCrowds"
|
||||
:stats="stats"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -75,7 +76,7 @@ import AppSubNav from '@/components/AppSubNav.vue'
|
||||
import AppRightbar from '@/components/AppRightbar.vue'
|
||||
import Footer from '@/components/Footer.vue'
|
||||
import { getTypes, getCrowds } from '@/api/category'
|
||||
import { getJokes } from '@/api/joke'
|
||||
import { getJokes, getHotMonthly, getStats } from '@/api/joke'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
|
||||
const themeStore = useThemeStore()
|
||||
@@ -98,6 +99,8 @@ const filterCrowdIds = ref([])
|
||||
|
||||
// 热门笑话(右侧栏)
|
||||
const hotJokes = ref([])
|
||||
// 网站统计
|
||||
const stats = ref(null)
|
||||
|
||||
|
||||
// 右侧栏:仅首页显示
|
||||
@@ -180,14 +183,19 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getJokes({ page: 1, page_size: 30 })
|
||||
console.log('[APP] jokes loaded:', res.items?.length, 'total:', res.total)
|
||||
const sorted = ((res.items || []).sort((a, b) => (b.view_count || 0) - (a.view_count || 0)))
|
||||
hotJokes.value = sorted.slice(0, 5)
|
||||
hotJokes.value = await getHotMonthly()
|
||||
console.log('[APP] monthly hot jokes loaded:', hotJokes.value.length)
|
||||
} catch (e) {
|
||||
console.warn('[APP] Failed to load hot jokes:', e)
|
||||
hotJokes.value = []
|
||||
}
|
||||
|
||||
try {
|
||||
stats.value = await getStats()
|
||||
console.log('[APP] stats loaded:', stats.value)
|
||||
} catch (e) {
|
||||
console.warn('[APP] Failed to load stats:', e)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -6,3 +6,5 @@ export const getRandomJoke = () => request.get('/jokes/random')
|
||||
export const likeJoke = id => request.post(`/jokes/${id}/like`)
|
||||
export const dislikeJoke = id => request.post(`/jokes/${id}/dislike`)
|
||||
export const searchJokes = params => request.get('/jokes/', { params })
|
||||
export const getHotMonthly = () => request.get('/jokes/hot-monthly')
|
||||
export const getStats = () => request.get('/jokes/stats')
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<aside class="rightbar">
|
||||
<!-- 热门笑话 -->
|
||||
<!-- 当月热门笑话 -->
|
||||
<div class="rightbar-section">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">🔥</span>
|
||||
热门笑话
|
||||
当月热门笑话
|
||||
</div>
|
||||
<div class="hot-list" v-if="hotJokes.length">
|
||||
<div
|
||||
@@ -23,6 +23,32 @@
|
||||
<div v-else class="empty-hint">暂无数据</div>
|
||||
</div>
|
||||
|
||||
<!-- 网站统计 -->
|
||||
<div class="rightbar-section stats-section" v-if="stats">
|
||||
<div class="section-title">
|
||||
<span class="title-icon">📊</span>
|
||||
网站统计
|
||||
</div>
|
||||
<div class="stats-grid">
|
||||
<div class="stat-item">
|
||||
<span class="stat-num">{{ stats.total_jokes || 0 }}</span>
|
||||
<span class="stat-label">笑话总数</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-num">{{ stats.approved_jokes || 0 }}</span>
|
||||
<span class="stat-label">已审核</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-num">{{ stats.pending_jokes || 0 }}</span>
|
||||
<span class="stat-label">待审核</span>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<span class="stat-num">{{ stats.total_views || 0 }}</span>
|
||||
<span class="stat-label">总浏览</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 类型快捷 -->
|
||||
<div class="rightbar-section">
|
||||
<div class="section-title">
|
||||
@@ -74,7 +100,8 @@
|
||||
defineProps({
|
||||
hotJokes: { type: Array, default: () => [] },
|
||||
types: { type: Array, default: () => [] },
|
||||
crowds: { type: Array, default: () => [] }
|
||||
crowds: { type: Array, default: () => [] },
|
||||
stats: { type: Object, default: null }
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -157,6 +184,32 @@ defineProps({
|
||||
}
|
||||
.quick-tag.crowd:hover { background: #2196F3; color: white; }
|
||||
|
||||
/* 统计区域 */
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
.stat-item {
|
||||
text-align: center;
|
||||
padding: 10px 6px;
|
||||
background: var(--bg-page);
|
||||
border-radius: 8px;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
.stat-num {
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
color: var(--primary);
|
||||
line-height: 1.2;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* 每日一笑 */
|
||||
.daily-section { background: var(--tag-type-bg); }
|
||||
.daily-text {
|
||||
@@ -166,4 +219,11 @@ defineProps({
|
||||
font-style: italic;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
/* 移动端隐藏右侧栏 */
|
||||
@media (max-width: 1199px) {
|
||||
.rightbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,6 @@
|
||||
<div class="filter-bar" v-if="filterText">
|
||||
<span class="filter-text">{{ filterText }}</span>
|
||||
<span class="filter-count">共 {{ jokeStore.total }} 条</span>
|
||||
<el-button link type="primary" @click="clearFilter" v-if="jokeStore.total > 0">清除筛选</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 笑话网格 -->
|
||||
@@ -84,11 +83,6 @@ const loadJokes = async (p = 1) => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
const clearFilter = () => {
|
||||
window.history.pushState({}, '', '/')
|
||||
loadJokes(1)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
types.value = allTypes.value?.length ? allTypes.value : await getTypes()
|
||||
crowds.value = allCrowds.value?.length ? allCrowds.value : await getCrowds()
|
||||
|
||||
Reference in New Issue
Block a user