Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,46 @@
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.shortcuts import redirect, get_object_or_404
|
||||
from django.views.generic.edit import DeleteView
|
||||
from django.urls import reverse_lazy
|
||||
from .models import Article, Category, Tag, ArticleImage
|
||||
|
||||
|
||||
class ArticleDeleteView(LoginRequiredMixin, DeleteView):
|
||||
"""删除文章视图"""
|
||||
model = Article
|
||||
template_name = 'blog/article_delete_confirm.html'
|
||||
pk_url_kwarg = 'article_id'
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
# 只有文章作者或管理员可以删除
|
||||
if obj.author != request.user and not request.user.is_superuser:
|
||||
return redirect('blog:detailbyid',
|
||||
article_id=obj.id,
|
||||
year=obj.creation_time.year,
|
||||
month=obj.creation_time.month,
|
||||
day=obj.creation_time.day)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['all_categories'] = Category.objects.all()
|
||||
context['all_tags'] = Tag.objects.all()
|
||||
return context
|
||||
|
||||
def delete(self, request, *args, **kwargs):
|
||||
# 删除文章前先删除所有相关图片
|
||||
self.object = self.get_object()
|
||||
images = ArticleImage.objects.filter(article=self.object)
|
||||
for image in images:
|
||||
# 删除图片文件
|
||||
image.image.delete()
|
||||
# 删除图片记录
|
||||
image.delete()
|
||||
|
||||
# 调用父类的delete方法删除文章
|
||||
return super().delete(request, *args, *kwargs)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy('blog:index')
|
||||
@ -0,0 +1,15 @@
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from .models import ArticleImage
|
||||
|
||||
|
||||
class ImageUploadForm(forms.ModelForm):
|
||||
"""图片上传表单"""
|
||||
class Meta:
|
||||
model = ArticleImage
|
||||
fields = ['image', 'description']
|
||||
widgets = {
|
||||
'image': forms.FileInput(attrs={'class': 'form-control', 'accept': 'image/*'}),
|
||||
'description': forms.TextInput(attrs={'class': 'form-control', 'placeholder': _('可选,添加图片描述')})
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,41 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from blog.models import Category
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '创建文章分类'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
categories = [
|
||||
'技术',
|
||||
'生活',
|
||||
'旅行',
|
||||
'美食',
|
||||
'摄影',
|
||||
'读书',
|
||||
'电影',
|
||||
'音乐',
|
||||
'编程',
|
||||
'设计',
|
||||
'健康',
|
||||
'教育',
|
||||
'职场',
|
||||
'财经',
|
||||
'历史',
|
||||
'文化',
|
||||
'体育',
|
||||
'游戏',
|
||||
'科技'
|
||||
]
|
||||
|
||||
for name in categories:
|
||||
category, created = Category.objects.get_or_create(
|
||||
name=name,
|
||||
defaults={'parent_category': None}
|
||||
)
|
||||
if created:
|
||||
self.stdout.write(self.style.SUCCESS(f'创建分类: {name}'))
|
||||
else:
|
||||
self.stdout.write(self.style.WARNING(f'分类已存在: {name}'))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS('分类创建完成'))
|
||||
@ -0,0 +1,13 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from blog.models import Category
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = '列出所有文章分类'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
categories = Category.objects.all()
|
||||
self.stdout.write('当前数据库中的分类:')
|
||||
for category in categories:
|
||||
self.stdout.write(f'- {category.name} (ID: {category.id})')
|
||||
self.stdout.write(f'总计: {categories.count()} 个分类')
|
||||
@ -0,0 +1,24 @@
|
||||
# Generated by Django
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('blog', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='articleimage',
|
||||
name='article',
|
||||
field=models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=models.deletion.CASCADE,
|
||||
related_name='images',
|
||||
to='blog.article'
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,29 @@
|
||||
# Generated by Django 4.2.14 on 2025-11-20 20:45
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('blog', '0006_alter_blogsettings_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ArticleImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ImageField(upload_to='article_images/%Y/%m/%d/', verbose_name='图片')),
|
||||
('description', models.CharField(blank=True, max_length=255, verbose_name='图片描述')),
|
||||
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
|
||||
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='blog.article')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': '文章图片',
|
||||
'verbose_name_plural': '文章图片',
|
||||
'ordering': ['-created_time'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,14 @@
|
||||
# Generated by Django 4.2.14 on 2025-11-20 22:28
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('blog', '0002_auto_20231201_1200'),
|
||||
('blog', '0007_articleimage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,91 @@
|
||||
|
||||
/* 自定义样式 - 修改导航栏背景色和按钮样式 */
|
||||
|
||||
/* 导航栏背景色改为天蓝色 */
|
||||
.main-navigation {
|
||||
background: linear-gradient(to right, #2e9ac5, #66b8db) !important;
|
||||
}
|
||||
|
||||
/* 文章标题链接样式 - 去掉蓝色按钮效果 */
|
||||
.entry-title a {
|
||||
color: #2c3e50 !important;
|
||||
text-decoration: none !important;
|
||||
background: none !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.entry-title a:hover {
|
||||
color: #3498db !important;
|
||||
text-decoration: underline !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* 侧边栏链接样式 - 去掉蓝色按钮效果 */
|
||||
.widget a {
|
||||
color: #34495e !important;
|
||||
text-decoration: none !important;
|
||||
background: none !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.widget a:hover {
|
||||
color: #3498db !important;
|
||||
text-decoration: underline !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* 文章阅读更多链接 - 去掉蓝色按钮效果 */
|
||||
.read-more {
|
||||
background: none !important;
|
||||
color: #3498db !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
.read-more:hover {
|
||||
background: none !important;
|
||||
color: #2980b9 !important;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* 文章链接 - 去掉蓝色按钮效果 */
|
||||
a[href*="/p/"],
|
||||
a[href*="/article/"] {
|
||||
background: none !important;
|
||||
color: #3498db !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
text-decoration: underline !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
a[href*="/p/"]:hover,
|
||||
a[href*="/article/"]:hover {
|
||||
background: none !important;
|
||||
color: #2980b9 !important;
|
||||
transform: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
/* 背景图片样式 */
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
background-image: url('/static/blog/img/default_bg.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* 网站容器样式,确保背景图片可见 */
|
||||
.site {
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
|
||||
/* 简单的图标样式 */
|
||||
|
||||
/* 图标基础样式 */
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin-right: 0.2em;
|
||||
line-height: 1;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
text-align: center;
|
||||
text-decoration: inherit;
|
||||
text-transform: none;
|
||||
speak: none;
|
||||
}
|
||||
|
||||
/* 文件夹图标 */
|
||||
.icon-folder:before {
|
||||
content: "📁";
|
||||
}
|
||||
|
||||
/* 标签图标 */
|
||||
.icon-tag:before {
|
||||
content: "🏷️";
|
||||
}
|
||||
|
||||
/* 评论图标 */
|
||||
.icon-comment:before {
|
||||
content: "💬";
|
||||
}
|
||||
|
||||
/* 搜索图标 */
|
||||
#searchform input[type="submit"]:before {
|
||||
content: "🔍";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 首页图标 */
|
||||
#menu-item-3498 a:before {
|
||||
content: "🏠";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 归档图标 */
|
||||
.menu-item a[href*="archives"]:before {
|
||||
content: "📚";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 管理站点图标 */
|
||||
.menu-item a[href*="admin"]:before {
|
||||
content: "⚙️";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 登录/登出图标 */
|
||||
.menu-item a[href*="login"]:before {
|
||||
content: "🔑";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
.menu-item a[href*="logout"]:before {
|
||||
content: "🚪";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 发布文章图标 */
|
||||
.menu-item a[href*="create"]:before {
|
||||
content: "✍️";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 我的文章图标 */
|
||||
.menu-item a[href*="my_articles"]:before {
|
||||
content: "📝";
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
/* 返回顶部按钮 */
|
||||
#rocket:before {
|
||||
content: "⬆️";
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
/* 背景切换按钮 */
|
||||
.bg-toggle-btn i {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
@ -0,0 +1,968 @@
|
||||
|
||||
/* 现代化博客样式 - 保持原有布局但提升视觉效果 */
|
||||
|
||||
/* 全局样式优化 */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 网站容器优化 */
|
||||
.site {
|
||||
max-width: 1200px;
|
||||
margin: 2rem auto;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 网站头部优化 */
|
||||
.site-header {
|
||||
background: linear-gradient(to bottom, #fff, #f8f9fa);
|
||||
padding: 1.5rem 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.site-title a {
|
||||
font-size: 2.2rem;
|
||||
font-weight: 700;
|
||||
color: #2c3e50;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-title a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
left: 0;
|
||||
width: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(to right, #3498db, #2980b9);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.site-title a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.site-title a:hover::after {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.site-description {
|
||||
color: #7f8c8d;
|
||||
font-size: 1.1rem;
|
||||
margin-top: 0.5rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* 导航栏优化 */
|
||||
.main-navigation {
|
||||
margin-top: 1rem;
|
||||
background: linear-gradient(to right, #34495e, #2c3e50);
|
||||
padding: 0;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main-navigation::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 4px;
|
||||
background: linear-gradient(to right, #3498db, #2980b9);
|
||||
box-shadow: 0 2px 4px rgba(52, 152, 219, 0.3);
|
||||
}
|
||||
|
||||
.main-navigation::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.main-navigation ul {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.main-navigation li {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.main-navigation a {
|
||||
color: #ecf0f1;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
padding: 0.9rem 1.2rem;
|
||||
display: block;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main-navigation a::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(to right, #3498db, #2980b9);
|
||||
transform: translateX(-50%);
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
.main-navigation a:hover::before {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.main-navigation a::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: width 0.6s ease, height 0.6s ease;
|
||||
}
|
||||
|
||||
.main-navigation a:hover::after {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.main-navigation a:hover {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* 当前活动菜单项 */
|
||||
.main-navigation .current-menu-item > a,
|
||||
.main-navigation .current_page_item > a {
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.main-navigation .current-menu-item > a::before,
|
||||
.main-navigation .current_page_item > a::before {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
/* 下拉菜单样式 */
|
||||
.main-navigation .sub-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
background: linear-gradient(to bottom, #34495e, #2c3e50);
|
||||
min-width: 220px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transform: translateY(15px);
|
||||
transition: all 0.3s ease;
|
||||
z-index: 1000;
|
||||
border-radius: 0 0 6px 6px;
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.main-navigation li:hover > .sub-menu {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.main-navigation .sub-menu li {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.main-navigation .sub-menu a {
|
||||
padding: 0.8rem 1.2rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.main-navigation .sub-menu li:last-child a {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.main-navigation .sub-menu a::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
background: linear-gradient(to bottom, #3498db, #2980b9);
|
||||
transform: scaleY(0);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.main-navigation .sub-menu a:hover::before {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
/* 移动端菜单按钮 */
|
||||
.menu-toggle {
|
||||
display: none;
|
||||
background-color: #34495e;
|
||||
color: #ecf0f1;
|
||||
padding: 0.75rem 1rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
margin: 1rem auto;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-toggle::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.menu-toggle:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.menu-toggle:hover {
|
||||
background-color: #3498db;
|
||||
}
|
||||
|
||||
/* 主内容区域优化 */
|
||||
#main {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
#primary {
|
||||
flex: 2;
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
#secondary {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 文章卡片样式 */
|
||||
article.post {
|
||||
margin-bottom: 2rem;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
article.post:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.entry-header {
|
||||
padding: 1.5rem 1.5rem 0;
|
||||
}
|
||||
|
||||
/* 文章顶部元信息 */
|
||||
.article-meta-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.author-avatar {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.author-avatar img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.author-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.author-name {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.post-date {
|
||||
font-size: 0.9rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.post-views {
|
||||
font-size: 0.9rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
/* 文章标题 */
|
||||
.entry-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pin-indicator {
|
||||
color: #e74c3c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.entry-title a {
|
||||
color: #2c3e50;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.entry-title a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
/* 面包屑导航 */
|
||||
.breadcrumb {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.breadcrumb a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.breadcrumb a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 文章元信息 */
|
||||
.article-meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 0.9rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.article-meta span {
|
||||
margin-right: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.article-meta a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.article-meta a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 文章内容 */
|
||||
.entry-content {
|
||||
padding: 0 1.5rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.article-summary {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.read-more-container {
|
||||
text-align: right;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.read-more {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(to right, #3498db, #2980b9);
|
||||
color: #fff;
|
||||
padding: 0.6rem 1.2rem;
|
||||
border-radius: 30px;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 5px rgba(52, 152, 219, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.read-more::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.6s ease;
|
||||
}
|
||||
|
||||
.read-more:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.read-more:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
|
||||
.read-more .arrow {
|
||||
margin-left: 0.5rem;
|
||||
font-weight: bold;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.read-more:hover .arrow {
|
||||
transform: translateX(3px);
|
||||
}
|
||||
|
||||
/* 统一所有阅读更多链接的样式 */
|
||||
a[href*="/p/"],
|
||||
a[href*="/article/"] {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(to right, #3498db, #2980b9);
|
||||
color: #fff;
|
||||
padding: 0.6rem 1.2rem;
|
||||
border-radius: 30px;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 5px rgba(52, 152, 219, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
a[href*="/p/"]::before,
|
||||
a[href*="/article/"]::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.6s ease;
|
||||
}
|
||||
|
||||
a[href*="/p/"]:hover::before,
|
||||
a[href*="/article/"]:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
a[href*="/p/"]:hover,
|
||||
a[href*="/article/"]:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(52, 152, 219, 0.4);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 目录样式 */
|
||||
.toc-container {
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 6px;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.toc-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.75rem;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.toc-content ul {
|
||||
padding-left: 1.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.toc-content li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.toc-content a {
|
||||
color: #34495e;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.toc-content a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
/* 文章内容区域 */
|
||||
.article-content {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
/* 文章页脚 */
|
||||
.entry-footer {
|
||||
padding: 0 1.5rem 1.5rem;
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
/* 侧边栏样式 */
|
||||
.widget-area {
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.widget {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.widget-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 2px solid #3498db;
|
||||
}
|
||||
|
||||
.widget ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.widget li {
|
||||
padding: 0.5rem 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.widget li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.widget a {
|
||||
color: #34495e;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.widget a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
/* 搜索框样式 */
|
||||
#searchform {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#searchform input[type="text"] {
|
||||
flex: 1;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px 0 0 4px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
#searchform input[type="submit"] {
|
||||
background-color: #3498db;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 0 1rem;
|
||||
border-radius: 0 4px 4px 0;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
#searchform input[type="submit"]:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
/* 标签云样式 */
|
||||
.tagcloud a {
|
||||
display: inline-block;
|
||||
margin: 0.25rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
background-color: #f1f2f6;
|
||||
color: #34495e;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.tagcloud a:hover {
|
||||
background-color: #3498db;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 评论区域样式 */
|
||||
.comments-area {
|
||||
margin-top: 2rem;
|
||||
padding: 1.5rem;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.comment-list {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.comment {
|
||||
margin-bottom: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.comment:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.comment-author {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.comment-meta {
|
||||
font-size: 0.8rem;
|
||||
color: #7f8c8d;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* 页脚样式 */
|
||||
footer[role="contentinfo"] {
|
||||
background-color: #34495e;
|
||||
color: #ecf0f1;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
footer[role="contentinfo"] a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
footer[role="contentinfo"] a:hover {
|
||||
color: #5dade2;
|
||||
}
|
||||
|
||||
/* 归档页面样式 */
|
||||
.archive-header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.archive-title {
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.archive-title .icon-folder {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.archive-description {
|
||||
font-size: 1rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.archive-content {
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
/* 时间轴样式 */
|
||||
.timeline-container {
|
||||
position: relative;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.timeline-container::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: linear-gradient(to bottom, #3498db, #2980b9);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.timeline-year {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.year-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1.5rem;
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.year-badge {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background-color: #3498db;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 3px 10px rgba(52, 152, 219, 0.3);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.year-text {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.article-count {
|
||||
font-size: 0.9rem;
|
||||
color: #7f8c8d;
|
||||
background-color: #f8f9fa;
|
||||
padding: 0.2rem 0.5rem;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.timeline-months {
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
.timeline-month {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.month-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.month-badge {
|
||||
position: absolute;
|
||||
left: -45px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #2ecc71;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 6px rgba(46, 204, 113, 0.3);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.month-text {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.timeline-articles {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.archive-article {
|
||||
display: flex;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.archive-article:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.article-date {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.day {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: #f1f2f6;
|
||||
color: #2c3e50;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.article-title {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.article-title a {
|
||||
color: #2c3e50;
|
||||
text-decoration: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.article-title a:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.article-meta {
|
||||
display: flex;
|
||||
font-size: 0.8rem;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.article-meta .category {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.article-meta a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.article-meta a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* 返回顶部按钮 */
|
||||
#rocket {
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
right: 2rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
background-color: #3498db;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||
transition: all 0.3s ease;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#rocket.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#rocket:hover {
|
||||
background-color: #2980b9;
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
#rocket::before {
|
||||
content: "↑";
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media screen and (max-width: 992px) {
|
||||
#main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#primary {
|
||||
padding-right: 0;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.widget-area {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.site {
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.main-navigation ul {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.main-navigation li {
|
||||
margin: 0.25rem;
|
||||
}
|
||||
|
||||
#primary, #secondary {
|
||||
padding: 0 1rem;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 330 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 324 KiB |
|
After Width: | Height: | Size: 584 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
|
||||
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChAI9jU77yQAAAABJRU5ErkJggg==
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue