Files
jczxw-pc/app/pages/reference/index.vue
2026-04-23 17:14:29 +08:00

211 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="reference-page">
<div class="page-header">
<h1 class="page-title">决策参考</h1>
<p class="page-desc">政策原文深度解读研究成果及专题研究报告</p>
</div>
<!-- 分类标签 -->
<div class="category-tabs">
<a-radio-group v-model:value="activeType" button-style="solid" @change="handleTypeChange">
<a-radio-button value="">全部</a-radio-button>
<a-radio-button value="policy">政策原文</a-radio-button>
<a-radio-button value="analysis">深度解读</a-radio-button>
<a-radio-button value="research">研究成果</a-radio-button>
<a-radio-button value="special">专题研究</a-radio-button>
<a-radio-button value="asean">东盟研究</a-radio-button>
<a-radio-button value="data">数据服务</a-radio-button>
</a-radio-group>
</div>
<!-- 文章列表 -->
<div class="article-list">
<div v-for="article in articles" :key="article.id" class="article-item" @click="handleView(article)">
<div class="article-tag" v-if="article.isVip">
<a-tag color="gold">VIP</a-tag>
</div>
<h3 class="article-title">{{ article.title }}</h3>
<p class="article-overview">{{ article.overview }}</p>
<div class="article-meta">
<span class="meta-item">{{ article.source }}</span>
<span class="meta-item">{{ article.publishTime }}</span>
</div>
</div>
<div v-if="loading" class="loading-placeholder">
<a-spin size="large" />
</div>
<div v-if="!loading && articles.length === 0" class="empty-placeholder">
<a-empty description="暂无文章" />
</div>
</div>
<!-- 分页 -->
<div class="pagination-wrap" v-if="total > pageSize">
<a-pagination
v-model:current="currentPage"
:total="total"
:page-size="pageSize"
@change="handlePageChange"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue'
useHead({ title: '决策参考 - 决策咨询网' })
const router = useRouter()
const activeType = ref((useRoute().query.type as string) || '')
const currentPage = ref(1)
const pageSize = ref(12)
const total = ref(0)
const loading = ref(false)
const articles = ref<any[]>([])
async function loadArticles() {
loading.value = true
try {
// TODO: 接入实际API
} catch (e: any) {
message.error('加载失败')
} finally {
loading.value = false
}
}
function handleTypeChange() {
currentPage.value = 1
loadArticles()
}
function handlePageChange(page: number) {
currentPage.value = page
loadArticles()
}
function handleView(article: any) {
// 如果是VIP内容需要登录
if (article.isVip) {
// TODO: 检查登录状态
}
router.push(`/reference/${article.id}`)
}
onMounted(() => {
loadArticles()
})
</script>
<style scoped>
.reference-page {
max-width: 1200px;
margin: 0 auto;
padding: 40px 20px;
}
.page-header {
text-align: center;
margin-bottom: 40px;
}
.page-title {
font-size: 32px;
font-weight: 700;
color: #1f2937;
margin: 0 0 12px;
}
.page-desc {
font-size: 16px;
color: #6b7280;
margin: 0;
}
.category-tabs {
margin-bottom: 32px;
text-align: center;
}
.article-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.article-item {
position: relative;
padding: 20px;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
cursor: pointer;
transition: all 0.2s;
}
.article-item:hover {
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
.article-tag {
position: absolute;
top: 16px;
right: 16px;
}
.article-title {
font-size: 16px;
font-weight: 600;
color: #1f2937;
margin: 0 0 8px;
line-height: 1.4;
}
.article-overview {
font-size: 13px;
color: #6b7280;
margin: 0 0 12px;
line-height: 1.6;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.article-meta {
display: flex;
gap: 12px;
font-size: 12px;
color: #9ca3af;
}
.loading-placeholder,
.empty-placeholder {
grid-column: 1 / -1;
padding: 60px 0;
text-align: center;
}
.pagination-wrap {
margin-top: 40px;
text-align: center;
}
@media (max-width: 1024px) {
.article-list {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.article-list {
grid-template-columns: 1fr;
}
}
</style>