update. 完成分页显示,清理部分冗余代码

This commit is contained in:
2026-04-01 20:49:04 +08:00
parent 414dc0ee95
commit 43f4bd0165
4 changed files with 198 additions and 324 deletions
+1 -5
View File
@@ -6,16 +6,12 @@ app_name = 'front' # 可选,用于命名空间(如 {% url 'main:index' %}
urlpatterns = [ urlpatterns = [
path('', views.index, name='index'), path('', views.index, name='index'),
path('<str:main>.html', views.info, name='menu'), path('<str:main>.html', views.section, name='section'),
path('<str:main>/list.html', views.main_article_list, name='main_list'), path('<str:main>/list.html', views.main_article_list, name='main_list'),
path('<str:main>/list/<str:sub>.html', views.sub_article_list, name='sub_list'), path('<str:main>/list/<str:sub>.html', views.sub_article_list, name='sub_list'),
path('about/', views.about, name='about'), path('about/', views.about, name='about'),
path('news/', views.news, name='news'), path('news/', views.news, name='news'),
path('info/', views.info, name='info'),
path('news/<str:sub>.html', views.sub_news_list, name='news_list'), path('news/<str:sub>.html', views.sub_news_list, name='news_list'),
path('party/', views.party, name='party'),
path('interaction/', views.interaction, name='interaction'),
path('science/', views.science, name='science'),
path('article/<int:pk>.html/', views.article_detail, name='article_detail'), path('article/<int:pk>.html/', views.article_detail, name='article_detail'),
path('news/<int:pk>.html/', views.news_detail, name='news_detail'), path('news/<int:pk>.html/', views.news_detail, name='news_detail'),
] ]
+78 -278
View File
@@ -2,7 +2,8 @@ import traceback
from typing import Dict, List from typing import Dict, List
from unicodedata import category from unicodedata import category
from django.db.models import Prefetch from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.db.models import Prefetch, Q
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from loguru import logger from loguru import logger
@@ -32,6 +33,7 @@ def article_detail(request, pk: int):
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
return render(request, 'front/error/500.html') return render(request, 'front/error/500.html')
def news_detail(request, pk: int): def news_detail(request, pk: int):
""" """
根据主键 (pk) 获取文章详情 根据主键 (pk) 获取文章详情
@@ -71,22 +73,10 @@ def index(request):
) )
# 3. 构建数据 (纯内存操作,速度极快) # 3. 构建数据 (纯内存操作,速度极快)
section_data = [] section_data = [{
for main in main_sections: "key": main.code,
# 收集该主板块下所有子板块的文章 "data": {main.title: articles_qs.filter(section__in=main.children.all()).order_by('-created_at')[:7]}
all_articles = [] } for main in main_sections]
for sub in main.children.all():
# 使用预取好的 children
# 使用预取好的 latest_articles,并取前7条
all_articles.extend(sub.latest_articles[:7])
all_articles.sort(key=lambda x: x.created_at, reverse=True)
# 截取总列表的前7条(如果需要限制总数)
section_data.append({
"key": main.code, # 建议使用 code 作为 key,比对象本身更安全
"data": {
main.title: all_articles[:7]
}
})
logger.info(section_data) logger.info(section_data)
carousel = { carousel = {
"key": "index", "key": "index",
@@ -146,7 +136,7 @@ def news(request):
return render(request, 'front/news.html', context) return render(request, 'front/news.html', context)
def info(request, main): def section(request, main):
"""信息公开""" """信息公开"""
logger.info(f"正在访问 {main}") logger.info(f"正在访问 {main}")
main_section = MainMenu.objects.filter(code=main).first() main_section = MainMenu.objects.filter(code=main).first()
@@ -169,66 +159,13 @@ def info(request, main):
return render(request, 'front/info.html', context=context) return render(request, 'front/info.html', context=context)
def main_article_list(request, main):
"""信息公开"""
logger.info(f"正在访问 {main}")
main_section = MainMenu.objects.filter(code=main).first()
if not main_section:
raise Http404("不存在的板块")
articles_qs = Article.objects.filter(is_published=True).order_by('-created_at')
sections = main_section.active_children.order_by('order').prefetch_related(
Prefetch('article_set', queryset=articles_qs, to_attr='latest_articles')
)
section_data = {
"key": main_section,
"data": {
main_section.title: [
article
for section in sections
for article in section.latest_articles[:7]
],
}
}
logger.info(section_data)
context = {
'main_section': main_section,
'sections': sections,
'articles': [
article
for section in sections
for article in section.latest_articles[:7]
]
}
return render(request, 'front/list.html', context=context)
def sub_news_list(request, sub: str):
logger.info(f"正在访问 {sub}")
sections = NewsSection.objects.all().order_by('order')
logger.info(f"新闻板块: {sections}")
main_section = {
'title': '新闻中心',
'code': 'news'
}
sub_section = sections.filter(code=sub).first()
logger.info(f"主板块 {main_section} 子板块 {sub_section}")
if not sub_section or not main_section:
raise Http404("不存在的板块")
context = {
'main_section': main_section,
'sub_section': sub_section,
'sections': sections,
'articles': sub_section.news_set.filter(is_published=True).order_by('-created_at')[:21]
}
return render(request, 'front/list.html', context=context)
def main_news_list(request): def main_news_list(request):
logger.info("正在访问新闻中心") logger.info("正在访问新闻中心")
news_list = News.objects.all() news_list = News.objects.all()
news_sections = NewsSection.objects.all() news_sections = NewsSection.objects.all()
# 分页参数
news_list = custom_pagination(news_list, request)
return render(request, 'front/list.html', { return render(request, 'front/list.html', {
'main_section': { 'main_section': {
'title': '新闻中心', 'title': '新闻中心',
@@ -239,6 +176,70 @@ def main_news_list(request):
}) })
def custom_pagination(news_list, request):
page = request.GET.get('page', 1) # 当前页码,默认第1页
per_page = request.GET.get('per_page', 20) # 每页显示条数,默认20
# 创建分页器
paginator = Paginator(news_list, per_page)
try:
# 获取当前页数据
news_list = paginator.page(page)
except PageNotAnInteger:
# 如果页码不是整数,返回第一页
news_list = paginator.page(1)
except EmptyPage:
# 如果页码超出范围,返回最后一页
news_list = paginator.page(paginator.num_pages)
return news_list
def sub_news_list(request, sub: str):
logger.info(f"正在访问 {sub}")
sections = NewsSection.objects.all().order_by('order')
logger.info(f"新闻板块: {sections}")
main_section = {
'title': '新闻中心',
'code': 'news'
}
sub_section = sections.filter(code=sub).first()
logger.info(f"主板块 {main_section} 子板块 {sub_section}")
if not sub_section or not main_section:
raise Http404("不存在的板块")
news_list = sub_section.news_set.filter(is_published=True).order_by('-created_at')[:21]
news_list = custom_pagination(news_list, request)
context = {
'main_section': main_section,
'sub_section': sub_section,
'sections': sections,
'articles': news_list
}
logger.info(context)
return render(request, 'front/list.html', context=context)
def main_article_list(request, main):
"""信息公开"""
logger.info(f"正在访问 {main}")
main_section = MainMenu.objects.filter(code=main).first()
if not main_section:
raise Http404("不存在的板块")
articles_qs = Article.objects.filter(is_published=True, section__in=main_section.active_children).order_by(
'-created_at')
sections = main_section.active_children.order_by('order').prefetch_related(
Prefetch('article_set', queryset=articles_qs, to_attr='latest_articles')
)
articles = custom_pagination(articles_qs, request)
context = {
'main_section': main_section,
'sections': sections,
'articles': articles,
}
return render(request, 'front/list.html', context=context)
def sub_article_list(request, main: str, sub: str): def sub_article_list(request, main: str, sub: str):
"""信息公开""" """信息公开"""
logger.info(f"正在访问 {main}") logger.info(f"正在访问 {main}")
@@ -248,213 +249,12 @@ def sub_article_list(request, main: str, sub: str):
logger.info(f"主板块 {main_section} 子板块 {sub_section}") logger.info(f"主板块 {main_section} 子板块 {sub_section}")
if not sub_section or not main_section: if not sub_section or not main_section:
raise Http404("不存在的板块") raise Http404("不存在的板块")
articles = sub_section.article_set.filter(is_published=True).order_by('-created_at')
articles = custom_pagination(articles, request)
context = { context = {
'main_section': main_section, 'main_section': main_section,
'sub_section': sub_section, 'sub_section': sub_section,
'sections': sections.filter(parent__code=main), 'sections': sections.filter(parent__code=main),
'articles': sub_section.article_set.filter(is_published=True).order_by('-created_at')[:21] 'articles': articles
} }
return render(request, 'front/list.html', context=context) return render(request, 'front/list.html', context=context)
def service(request):
"""办事服务"""
q = request.GET.get('q') or "办事指南"
sections = [
"办事指南",
"政务服务",
"资料下载",
"办事统计",
]
data = {
"办事指南": [
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
],
"政务服务": [
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
],
"资料下载": [
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
{'title': '公告送达通知', 'date': '2026-03-10'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
]
}
context = {
"sections": sections,
"data_list": data.get(q),
"q": q,
}
return render(request, 'front/service.html', context)
def party(request):
"""党建引领"""
sections: List[Dict] = [
{
"key": "party_work",
"data": {
"党建工作": [
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
{'title': '公告送达通知', 'date': '2026-03-10'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
]
}
},
{
"key": "integrity",
"data": {
"党风廉政": [
# ⚠️ 请替换为真实的法律法规数据
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
{'title': '公告送达通知', 'date': '2026-03-10'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
]
}
},
{
"key": "advance",
"data": {
"先进典型": [
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
]
}
},
]
carousel: Dict = {
"key": "index",
"data": [
{
"id": 0,
"image_url": "/media/upload/images/2022/12/15/11146164001.jpg",
"title": "First slide label",
# "description": "Some representative placeholder content for the first slide."
},
{
"id": 1,
"image_url": "/media/upload/images/2022/12/15/11142163743.jpg",
"title": "Second slide label",
# "description": "Some representative placeholder content for the second slide."
},
{
"id": 2,
"image_url": "/media/upload/images/2022/12/15/11150164804.jpg",
"title": "Third slide label",
# "description": "Some representative placeholder content for the third slide."
}
]
}
sections.insert(1, carousel)
context = {
'sections': sections,
}
return render(request, 'front/party.html', context)
def interaction(request):
"""互动交流"""
q = request.GET.get('q') or "专家访谈"
sections = [
"专家访谈",
"调查征集",
"在线咨询",
]
data = {
"专家访谈": [
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
],
"调查征集": [
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
],
"在线咨询": [
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
{'title': '公告送达通知', 'date': '2026-03-10'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
]
}
context = {
"sections": sections,
"data_list": data.get(q),
"q": q,
}
return render(request, 'front/interaction.html', context)
def science(request):
"""消防科普"""
q = request.GET.get('q') or "数字消防"
sections = [
"数字消防",
"火灾预防",
"自救逃生",
]
data = {
"数字消防": [
{'title': '中共长白山保护开发区工委办公室关于印发杨文慧同志在 2026...', 'date': '2026-03-05'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区落实<吉林省...', 'date': '2026-02-28'},
{'title': '长白山保护开发区管理委员会 2025 年度行政执法工作报告', 'date': '2026-01-30'},
{'title': '长白山管委会办公室关于印发《美丽长白山建设行动方案(202...', 'date': '2025-12-31'},
{'title': '长白山管委会办公室关于印发《长白山保护开发区碳达峰实施...', 'date': '2025-12-31'},
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
],
"火灾预防": [
{'title': '《长白山保护开发区防雷减灾管理办法》政策解读', 'date': '2025-12-12'},
{'title': '《长白山保护开发区旅游漂流活动管理规范》政策解读', 'date': '2025-07-23'},
{'title': '《长白山 40 米射电望远镜电磁波宁静区保护办法》政策解读', 'date': '2025-07-23'},
{'title': '《长白山保护开发区古树名木管理办法(试行)》政策解读', 'date': '2025-06-18'},
{'title': '《长白山保护开发区公共租赁住房管理办法》政策解读', 'date': '2025-04-08'},
{'title': '《长白山保护开发区旅游民宿管理与服务规范(试行)》政策解读', 'date': '2024-12-31'},
],
"自救逃生": [
{'title': '关于第二轮中央生态环境保护督察第四十一项整改任务销号...', 'date': '2026-03-11'},
{'title': '关于第二轮中央生态环境保护督察第三十八项整改任务销号...', 'date': '2026-03-11'},
{'title': '公告送达通知', 'date': '2026-03-10'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
{'title': '吉林省长白山保护开发区管理委员会规划和自然资源局行政...', 'date': '2026-03-06'},
]
}
context = {
"sections": sections,
"data_list": data.get(q),
"q": q,
}
return render(request, 'front/science.html', context)
+1 -1
View File
@@ -4,7 +4,7 @@
<!-- 新闻中心 --> <!-- 新闻中心 -->
<li class="{% if menu.code in request.path %}active{% endif %}"> <li class="{% if menu.code in request.path %}active{% endif %}">
<a href="{% url 'front:menu' main=menu.code %}">{{ menu.title }}</a> <a href="{% url 'front:section' main=menu.code %}">{{ menu.title }}</a>
</li> </li>
{% endfor %} {% endfor %}
+118 -40
View File
@@ -39,7 +39,7 @@
<li class="list-group-item" style="background: #23418A; color: #f5f5f5"> <li class="list-group-item" style="background: #23418A; color: #f5f5f5">
<a href="{% url "front:main_list" main=main_section.code %}" <a href="{% url "front:main_list" main=main_section.code %}"
style="color: #F5F5F5;text-decoration: none;"> style="color: #F5F5F5;text-decoration: none;">
<h5>{{ main_section.title }}</h5> <h5 style="margin: 0; padding: 0; line-height: 1.2;">{{ main_section.title }}</h5>
</a> </a>
</li> </li>
{% for sec in sections %} {% for sec in sections %}
@@ -77,7 +77,7 @@
{# <div class="deco-top"></div>#} {# <div class="deco-top"></div>#}
{# <div class="deco-bottom"></div>#} {# <div class="deco-bottom"></div>#}
{# </div>#} {# </div>#}
<ul class="list-unstyled mb-0" style="width: 100%;padding-right: 38px; margin-left: 0;"> <ul class="list-unstyled mb-0">
{# items 就是当前 key 对应的列表数据,直接使用 #} {# items 就是当前 key 对应的列表数据,直接使用 #}
{% if articles %} {% if articles %}
{% for item in articles %} {% for item in articles %}
@@ -94,25 +94,99 @@
<li class="text-muted text-center py-2">暂无数据</li> <li class="text-muted text-center py-2">暂无数据</li>
{% endif %} {% endif %}
</ul> </ul>
<!-- 组件结束 -->
</div> </div>
<!-- 组件结束 --> <ul class="pagination pagination-sm pagination-wrapper">
<div style="display: flex; justify-content: center; margin-top: 10px;margin-bottom: -5px;"> <li class="page-item disabled">
<ul class="pagination" style="margin: auto;"> <a class="page-link">共 {{ articles.paginator.count }} 条</a>
</li>
<!-- 首页 -->
{% if articles.has_previous %}
<li class="page-item"> <li class="page-item">
<a class="page-link" href="#" aria-label="Previous"> <a class="page-link" href="?page=1">首页</a>
<span aria-hidden="true">&laquo;</span> </li>
{% else %}
<li class="page-item disabled">
<span class="page-link">首页</span>
</li>
{% endif %}
<!-- 上一页 -->
{% if articles.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ articles.previous_page_number }}"
aria-label="Previous">
<span>上一页</span>
</a> </a>
</li> </li>
<li class="page-item"><a class="page-link" href="#">1</a></li> {% else %}
<li class="page-item"><a class="page-link" href="#">2</a></li> <li class="page-item disabled">
<li class="page-item"><a class="page-link" href="#">3</a></li> <span class="page-link">上一页</span>
</li>
{% endif %}
{# 页码核心逻辑 #}
{% for i in articles.paginator.page_range %}
{% if articles.number == i %}
{# 当前页 #}
<li class="page-item active">
<span class="page-link">{{ i }}</span>
</li>
{% else %}
{# 显示规则:第1-2页 | 当前页前后各2页 | 最后2页 #}
{% if i == 1 or i == 2 or i == articles.paginator.num_pages or i == articles.paginator.num_pages|add:"-1" or i >= articles.number|add:"-2" and i <= articles.number|add:"2" %}
<li class="page-item">
<a class="page-link" href="?page={{ i }}">{{ i }}</a>
</li>
{% elif i == articles.number|add:"-3" or i == articles.number|add:"3" %}
{# 省略号只出现一次 #}
<li class="page-item disabled">
<span class="page-link">...</span>
</li>
{% endif %}
{% endif %}
{% endfor %}
<!-- 下一页 -->
{% if articles.has_next %}
<li class="page-item"> <li class="page-item">
<a class="page-link" href="#" aria-label="Next"> <a class="page-link" href="?page={{ articles.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span> <span>下一页</span>
</a> </a>
</li> </li>
</ul> {% else %}
</div> <li class="page-item disabled">
<span class="page-link">下一页</span>
</li>
{% endif %}
<!-- 尾页 -->
{% if articles.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ articles.paginator.num_pages }}"
aria-label="Last">
<span>尾页</span>
</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">尾页</span>
</li>
{% endif %}
{# 6. 跳转功能 (模拟图片样式:前往 [输入框] 页) #}
{# <li class="page-item">#}
{# <span class="page-link pagination-info">前往</span>#}
{# </li>#}
{# <li class="page-item">#}
{# <input class="page-jump-input" id="gotoPageInput" type="number" min="1"#}
{# max="{{ articles.paginator.num_pages }}" placeholder="页">#}
{# </li>#}
{# <li class="page-item d-none"> {# 这里隐藏一个提交按钮,主要靠JS触发 #}
{# <button id="jumpBtn" class="page-link" style="display: none;">确定</button>#}
{# </li>#}
</ul>
</div> </div>
</div> </div>
</div> </div>
@@ -123,7 +197,7 @@
.section-header-card { .section-header-card {
position: relative; position: relative;
width: 100%; width: 100%;
{#max-width: 800px; /* 模拟图片中的长宽比 */#} min-height: 720px; /* 设置一个保底高度 */ min-height: 720px; /* 设置一个保底高度 */
height: auto; /* 高度随内容增加而增加 */ height: auto; /* 高度随内容增加而增加 */
background-color: #ffffff; background-color: #ffffff;
border-radius: 12px; /* 大圆角 */ border-radius: 12px; /* 大圆角 */
@@ -133,7 +207,6 @@
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-left: 30px; padding-left: 30px;
{#justify-content: space-between;#}
} }
/* 左侧内容区域 */ /* 左侧内容区域 */
@@ -145,6 +218,35 @@
width: 100%; width: 100%;
} }
.list-unstyled {
flex-grow: 1; /* 使列表占满剩余的空间 */
padding-right: 38px;
margin-left: 0;
width: 100%;
}
.pagination-wrapper {
display: flex;
justify-content: end; /* 分页内容左右对齐 */
align-items: center;
margin: 10px auto -20px;
padding: 5px 0;
border-radius: 12px; /* 大圆角 */
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08) !important; /* 柔和阴影 */
}
.page-link {
border: none !important;
color: #6C757D;
}
.page-item.active .page-link {
background-color: #23408A;
border-color: #23408A;
}
/* 标题部分 */ /* 标题部分 */
.header-title { .header-title {
font-size: 20px; font-size: 20px;
@@ -175,30 +277,6 @@
margin: 0; margin: 0;
} }
/* --- 右侧装饰块 --- */
.right-decoration {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 60px; /* 装饰块宽度 */
display: flex;
flex-direction: column;
}
/* 上方深色块 */
.deco-top {
flex: 1; /* 占据上半部分 */
background-color: #5a6da3; /* 深蓝灰色 */
min-height: 50%;
}
/* 下方浅色块 */
.deco-bottom {
flex: 1; /* 占据下半部分 */
background-color: #eef4ff; /* 极浅的蓝色 */
min-height: 50%;
}
</style> </style>
{% endblock %} {% endblock %}