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

194 lines
3.6 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="hanmo-page">
<div class="page-header">
<h1 class="page-title">翰墨文谈</h1>
<p class="page-desc">以文会友汇聚文化精品传承智慧结晶</p>
</div>
<!-- 文章列表 -->
<div class="article-grid">
<div v-for="article in articles" :key="article.id" class="article-card" @click="handleView(article)">
<div class="card-image" v-if="article.image">
<img :src="article.image" :alt="article.title" />
</div>
<div class="card-body">
<h3 class="card-title">{{ article.title }}</h3>
<p class="card-overview">{{ article.overview }}</p>
<div class="card-meta">
<span>{{ article.author }}</span>
<span>{{ article.publishTime }}</span>
</div>
</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 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 handlePageChange(page: number) {
currentPage.value = page
loadArticles()
}
function handleView(article: any) {
router.push(`/hanmo/${article.id}`)
}
onMounted(() => {
loadArticles()
})
</script>
<style scoped>
.hanmo-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;
}
.article-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24px;
}
.article-card {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
cursor: pointer;
transition: all 0.2s;
}
.article-card:hover {
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
transform: translateY(-4px);
}
.card-image {
width: 100%;
height: 200px;
overflow: hidden;
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.card-body {
padding: 16px;
}
.card-title {
font-size: 16px;
font-weight: 600;
color: #1f2937;
margin: 0 0 8px;
line-height: 1.4;
}
.card-overview {
font-size: 13px;
color: #6b7280;
margin: 0 0 12px;
line-height: 1.6;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.card-meta {
display: flex;
justify-content: space-between;
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-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 640px) {
.article-grid {
grid-template-columns: 1fr;
}
}
</style>