boyuehasfj-vue3-html/src/views/LawListView.vue
2025-06-02 21:36:36 +08:00

460 lines
12 KiB
Vue

<script setup lang="ts">
import { ref, onMounted, watch, onActivated } from 'vue'
import { getPageList } from '../services/api'
import TheNavbar from '../components/TheNavbar.vue'
import Pagination from '../components/Pagination.vue'
interface PageItem {
id: number;
formatId: string;
title: string;
content: string;
pageType: string;
pageUrl?: string;
createTime: string;
updateTime: string;
status: number;
sortOrder: number;
viewCount: number;
author?: string;
keywords?: string;
description?: string;
attachmentUrl?: string;
}
interface PageData {
code: number;
rows: PageItem[];
total: number;
msg: string;
}
const laws = ref<PageItem[]>([]);
const loading = ref(true);
const error = ref('');
const total = ref(0);
const currentPage = ref(1);
const pageSize = ref(15);
const fetchLaws = async () => {
try {
loading.value = true;
error.value = '';
const response = await getPageList('law', currentPage.value, pageSize.value);
if (response.code === 200) {
laws.value = response.rows || [];
total.value = response.total || laws.value.length;
// 如果当前页没有数据且不是第一页,尝试请求前一页
if (laws.value.length === 0 && currentPage.value > 1) {
currentPage.value = currentPage.value - 1;
await fetchLaws();
}
} else {
error.value = response.msg || '获取数据失败';
laws.value = [];
}
} catch (err) {
console.error('获取法律规定列表失败:', err);
error.value = '获取数据失败,请稍后重试';
laws.value = [];
} finally {
loading.value = false;
}
};
// 页码或每页数量变化时重新获取数据
watch([currentPage, pageSize], () => {
fetchLaws();
});
// 分页变化处理
const handlePageChange = (page: number, size: number) => {
currentPage.value = page;
pageSize.value = size;
};
// 格式化日期
const formatDate = (dateStr: string | null | undefined): string => {
if (!dateStr) return '未知日期';
try {
const date = new Date(dateStr);
if (isNaN(date.getTime())) {
return '未知日期';
}
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
} catch (e) {
console.error('日期格式化错误:', e);
return '未知日期';
}
}
onMounted(() => {
fetchLaws();
});
// 添加页面激活时重新获取数据的处理函数
onActivated(() => {
console.log('法律规定列表页面被激活,重新获取数据');
fetchLaws();
});
</script>
<template>
<div class="law-list-container">
<TheNavbar />
<div class="page-header">
<div class="container">
<h1>法律规定</h1>
<p class="subtitle">查看并了解最新的法律法规内容</p>
</div>
</div>
<div class="container">
<div class="content-wrapper">
<div class="law-list">
<div v-if="loading" class="loading">
<div class="spinner"></div>
<p>加载中...</p>
</div>
<div v-else-if="error" class="error">
<h3>获取数据失败</h3>
<p>{{ error }}</p>
<button @click="fetchLaws" class="btn-retry">重试</button>
</div>
<div v-else-if="laws.length === 0" class="empty">
<h3>暂无内容</h3>
<p>当前没有法律规定相关内容</p>
<router-link to="/" class="btn-home">返回首页</router-link>
</div>
<div v-else class="list-content">
<div class="law-grid">
<div v-for="law in laws" :key="law.id" class="law-card">
<router-link :to="`/show.html?Id=${law.formatId}`" class="law-link">
<div class="law-icon"></div>
<div class="law-content">
<h3 class="law-title">{{ law.title }}</h3>
<div class="law-meta">
<span class="law-date">{{ formatDate(law.createTime) }}</span>
<!-- <span class="law-views">浏览: {{ law.viewCount }}</span> -->
</div>
<div class="law-footer">
<span class="view-more">查看详情</span>
</div>
</div>
</router-link>
</div>
</div>
<!-- 分页组件 -->
<Pagination
:total="total"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
@change="handlePageChange"
:page-sizes="[8, 16, 24, 32]"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.law-list-container {
min-height: 100vh;
background-color: var(--color-background);
display: flex;
flex-direction: column;
width: 100%;
}
.page-header {
background-color: var(--color-primary);
color: white;
padding: 3rem 0;
margin-bottom: 0;
position: relative;
overflow: hidden;
background-image: linear-gradient(135deg, #0072ff 0%, #00c6ff 100%);
width: 100%;
}
.page-header::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiPjxkZWZzPjxwYXR0ZXJuIGlkPSJwYXR0ZXJuIiB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHBhdHRlcm5UcmFuc2Zvcm09InJvdGF0ZSg0NSkiPjxyZWN0IGlkPSJwYXR0ZXJuLWJhY2tncm91bmQiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InRyYW5zcGFyZW50Ij48L3JlY3Q+PHBhdGggZD0iTSAwIDAgTCAxMCAwIiBzdHJva2U9IiNmZmZmZmYxMCIgc3Ryb2tlLXdpZHRoPSIxIj48L3BhdGg+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI3BhdHRlcm4pIj48L3JlY3Q+PC9zdmc+');
opacity: 0.4;
z-index: 1;
}
.page-header .container {
position: relative;
z-index: 2;
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
}
.page-header h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
font-weight: 700;
letter-spacing: 2px;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
max-width: 700px;
line-height: 1.4;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
width: 100%;
}
.content-wrapper {
padding: 2rem 0;
width: 100%;
}
.law-list {
background-color: white;
border-radius: 12px;
padding: 2rem;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
width: 100%;
}
.loading, .error, .empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem;
text-align: center;
}
.spinner {
width: 40px;
height: 40px;
border: 3px solid rgba(0, 0, 0, 0.1);
border-radius: 50%;
border-top-color: var(--color-primary);
animation: spin 1s ease-in-out infinite;
margin-bottom: 1rem;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.btn-retry, .btn-home {
background-color: var(--color-primary);
color: white;
border: none;
padding: 0.7rem 1.8rem;
border-radius: 4px;
cursor: pointer;
font-size: 0.95rem;
transition: all 0.3s;
margin-top: 1rem;
box-shadow: 0 2px 8px rgba(0, 123, 255, 0.25);
text-decoration: none;
display: inline-block;
}
.btn-retry:hover, .btn-home:hover {
background-color: var(--color-primary-dark);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 123, 255, 0.3);
}
.law-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}
.law-card {
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
overflow: hidden;
border: 1px solid #f0f0f0;
height: 100%;
}
.law-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}
.law-link {
display: flex;
flex-direction: column;
height: 100%;
text-decoration: none;
color: var(--color-text);
padding: 1.2rem;
}
.law-icon {
width: 48px;
height: 48px;
background-color: rgba(0, 123, 255, 0.1);
border-radius: 50%;
margin-bottom: 1.2rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%230072ff' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/%3E%3Cpath d='M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z'/%3E%3C/svg%3E");
background-size: 24px;
background-position: center;
background-repeat: no-repeat;
transition: all 0.3s;
}
.law-card:hover .law-icon {
background-color: var(--color-primary);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='white' viewBox='0 0 16 16'%3E%3Cpath d='M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z'/%3E%3Cpath d='M5.255 5.786a.237.237 0 0 0 .241.247h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286zm1.557 5.763c0 .533.425.927 1.01.927.609 0 1.028-.394 1.028-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94z'/%3E%3C/svg%3E");
}
.law-content {
flex: 1;
display: flex;
flex-direction: column;
}
.law-title {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 1rem;
line-height: 1.4;
color: var(--color-text);
}
.law-meta {
margin-bottom: 1.5rem;
color: var(--color-text-light);
font-size: 0.85rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.law-date, .law-views {
display: flex;
align-items: center;
gap: 0.5rem;
}
.law-date::before, .law-views::before {
content: '';
display: inline-block;
width: 16px;
height: 16px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
opacity: 0.7;
}
.law-date::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M4.684 11.523v-2.3h2.261v-.61H4.684V6.801h2.464v-.61H4v5.332h.684zm3.296 0h.676V8.98c0-.554.227-1.007.953-1.007.125 0 .258.004.329.015v-.613a1.806 1.806 0 0 0-.254-.02c-.582 0-.891.32-1.012.567h-.02v-.504H7.98v4.105zm2.805-5.093c0 .238.192.425.43.425a.428.428 0 1 0 0-.855.426.426 0 0 0-.43.43zm.094 5.093h.672V7.418h-.672v4.105z'/%3E%3Cpath d='M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z'/%3E%3C/svg%3E");
}
.law-views::before {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath d='M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z'/%3E%3Cpath d='M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8zm8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7z'/%3E%3C/svg%3E");
}
.law-footer {
margin-top: auto;
padding-top: 1rem;
border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.view-more {
display: inline-flex;
align-items: center;
color: var(--color-primary);
font-size: 0.9rem;
transition: all 0.3s;
}
.view-more::after {
content: '→';
margin-left: 0.3rem;
transition: transform 0.3s;
}
.law-card:hover .view-more::after {
transform: translateX(3px);
}
@media (max-width: 768px) {
.page-header {
padding: 2.5rem 0;
}
.page-header h1 {
font-size: 2.2rem;
}
.law-grid {
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
.law-list {
padding: 1.5rem;
}
}
@media (max-width: 576px) {
.page-header {
padding: 2rem 0;
}
.page-header h1 {
font-size: 1.8rem;
}
.subtitle {
font-size: 1rem;
}
.law-grid {
grid-template-columns: 1fr;
}
.law-list {
padding: 1rem;
border-radius: 8px;
}
.law-link {
padding: 1.2rem;
}
}
</style>