博客系统项目

项目规划

博客系统是Web开发中最经典的项目类型之一,它涵盖了内容管理、用户交互、数据存储等多个方面,是学习全栈开发的绝佳实践项目。

东巴文(db-w.cn) 认为:博客系统不仅是一个技术项目,更是一个内容平台。好的博客系统应该让作者专注于创作,让读者享受阅读。

项目目标

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>项目规划 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .goal-card {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .goal-card h3 {
            margin-bottom: 10px;
        }
        
        .info-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        
        .info-table th,
        .info-table td {
            padding: 12px;
            text-align: left;
            border: 1px solid #ddd;
        }
        
        .info-table th {
            background: #667eea;
            color: white;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>项目规划</h1>
        
        <h2>项目目标</h2>
        
        <div class="goal-card">
            <h3>🎯 核心目标</h3>
            <ul>
                <li>实现文章的发布、编辑、删除功能</li>
                <li>支持文章分类和标签管理</li>
                <li>实现用户评论和互动功能</li>
                <li>提供良好的阅读体验</li>
            </ul>
        </div>
        
        <div class="goal-card">
            <h3>🎯 次要目标</h3>
            <ul>
                <li>支持Markdown编辑</li>
                <li>实现文章搜索功能</li>
                <li>支持代码高亮显示</li>
                <li>提供RSS订阅功能</li>
            </ul>
        </div>
        
        <h2>技术选型</h2>
        <table class="info-table">
            <thead>
                <tr>
                    <th>技术层</th>
                    <th>技术选择</th>
                    <th>说明</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>前端</td>
                    <td>HTML5 + CSS3 + JavaScript</td>
                    <td>原生技术,易于理解和学习</td>
                </tr>
                <tr>
                    <td>后端</td>
                    <td>Node.js + Express</td>
                    <td>轻量级,适合中小型项目</td>
                </tr>
                <tr>
                    <td>数据库</td>
                    <td>MongoDB / SQLite</td>
                    <td>灵活的文档数据库或轻量级关系数据库</td>
                </tr>
                <tr>
                    <td>部署</td>
                    <td>云服务器 / Vercel</td>
                    <td>灵活的部署选项</td>
                </tr>
            </tbody>
        </table>
        
        <h2>项目范围</h2>
        <ul>
            <li><strong>用户角色:</strong> 管理员、作者、读者</li>
            <li><strong>核心功能:</strong> 文章管理、用户管理、评论系统</li>
            <li><strong>开发周期:</strong> 4-6周</li>
            <li><strong>团队规模:</strong> 1-3人</li>
        </ul>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>博客系统可以从简单开始,逐步增加功能。先实现核心的文章发布和展示功能,再考虑评论、搜索等高级功能。
        </div>
    </div>
</body>
</html>

需求分析

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>需求分析 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .feature-list {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .feature-list h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .feature-item {
            background: white;
            padding: 15px;
            margin: 10px 0;
            border-left: 4px solid #667eea;
        }
        
        .info-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        
        .info-table th,
        .info-table td {
            padding: 12px;
            text-align: left;
            border: 1px solid #ddd;
        }
        
        .info-table th {
            background: #667eea;
            color: white;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>需求分析</h1>
        
        <h2>功能需求</h2>
        
        <div class="feature-list">
            <h3>📝 文章管理</h3>
            <div class="feature-item">
                <strong>功能:</strong>
                <ul>
                    <li>创建、编辑、删除文章</li>
                    <li>文章分类和标签</li>
                    <li>文章封面图片</li>
                    <li>文章状态(草稿、发布)</li>
                    <li>文章浏览统计</li>
                </ul>
            </div>
        </div>
        
        <div class="feature-list">
            <h3>👤 用户管理</h3>
            <div class="feature-item">
                <strong>功能:</strong>
                <ul>
                    <li>用户注册和登录</li>
                    <li>用户资料管理</li>
                    <li>用户角色和权限</li>
                    <li>头像上传</li>
                    <li>密码找回</li>
                </ul>
            </div>
        </div>
        
        <div class="feature-list">
            <h3>💬 评论系统</h3>
            <div class="feature-item">
                <strong>功能:</strong>
                <ul>
                    <li>发表评论和回复</li>
                    <li>评论审核</li>
                    <li>评论点赞</li>
                    <li>评论举报</li>
                    <li>评论通知</li>
                </ul>
            </div>
        </div>
        
        <div class="feature-list">
            <h3>🔍 搜索功能</h3>
            <div class="feature-item">
                <strong>功能:</strong>
                <ul>
                    <li>全文搜索</li>
                    <li>按分类筛选</li>
                    <li>按标签筛选</li>
                    <li>按时间排序</li>
                    <li>搜索建议</li>
                </ul>
            </div>
        </div>
        
        <h2>非功能需求</h2>
        <table class="info-table">
            <thead>
                <tr>
                    <th>需求类型</th>
                    <th>具体要求</th>
                    <th>优先级</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>性能</td>
                    <td>页面加载时间 &lt; 3秒</td>
                    <td></td>
                </tr>
                <tr>
                    <td>安全</td>
                    <td>防止XSS、CSRF攻击</td>
                    <td></td>
                </tr>
                <tr>
                    <td>可用性</td>
                    <td>响应式设计,支持移动端</td>
                    <td></td>
                </tr>
                <tr>
                    <td>可维护性</td>
                    <td>代码结构清晰,注释完善</td>
                    <td></td>
                </tr>
                <tr>
                    <td>可扩展性</td>
                    <td>支持插件和主题扩展</td>
                    <td></td>
                </tr>
            </tbody>
        </table>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>需求分析要区分核心功能和扩展功能。优先实现核心功能,确保系统可用,再逐步添加高级功能。
        </div>
    </div>
</body>
</html>

数据库设计

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据库设计 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .db-schema {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .db-schema h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>数据库设计</h1>
        
        <h2>数据模型</h2>
        
        <div class="db-schema">
            <h3>用户表(Users)</h3>
            <div class="code-block">
                <pre>
{
    "_id": ObjectId,
    "username": String,          // 用户名
    "email": String,             // 邮箱
    "password": String,          // 密码(加密)
    "avatar": String,            // 头像URL
    "role": String,              // 角色(admin, author, reader)
    "bio": String,               // 个人简介
    "created_at": Date,          // 创建时间
    "updated_at": Date           // 更新时间
}
                </pre>
            </div>
        </div>
        
        <div class="db-schema">
            <h3>文章表(Articles)</h3>
            <div class="code-block">
                <pre>
{
    "_id": ObjectId,
    "title": String,             // 标题
    "slug": String,              // URL友好标题
    "content": String,           // 内容(Markdown)
    "excerpt": String,           // 摘要
    "cover_image": String,       // 封面图片
    "author_id": ObjectId,       // 作者ID
    "category_id": ObjectId,     // 分类ID
    "tags": [String],            // 标签数组
    "status": String,            // 状态(draft, published)
    "view_count": Number,        // 浏览次数
    "like_count": Number,        // 点赞次数
    "comment_count": Number,     // 评论次数
    "created_at": Date,          // 创建时间
    "updated_at": Date,          // 更新时间
    "published_at": Date         // 发布时间
}
                </pre>
            </div>
        </div>
        
        <div class="db-schema">
            <h3>分类表(Categories)</h3>
            <div class="code-block">
                <pre>
{
    "_id": ObjectId,
    "name": String,              // 分类名称
    "slug": String,              // URL友好名称
    "description": String,       // 分类描述
    "parent_id": ObjectId,       // 父分类ID(可选)
    "created_at": Date,          // 创建时间
    "updated_at": Date           // 更新时间
}
                </pre>
            </div>
        </div>
        
        <div class="db-schema">
            <h3>评论表(Comments)</h3>
            <div class="code-block">
                <pre>
{
    "_id": ObjectId,
    "article_id": ObjectId,      // 文章ID
    "user_id": ObjectId,         // 用户ID
    "parent_id": ObjectId,       // 父评论ID(可选)
    "content": String,           // 评论内容
    "status": String,            // 状态(pending, approved, rejected)
    "like_count": Number,        // 点赞次数
    "created_at": Date,          // 创建时间
    "updated_at": Date           // 更新时间
}
                </pre>
            </div>
        </div>
        
        <h2>索引设计</h2>
        <ul>
            <li><strong>用户表:</strong> username(唯一), email(唯一)</li>
            <li><strong>文章表:</strong> slug(唯一), author_id, category_id, status, created_at</li>
            <li><strong>评论表:</strong> article_id, user_id, status</li>
        </ul>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>数据库设计要考虑查询效率和数据一致性。合理使用索引可以大幅提升查询性能,但过多的索引会影响写入性能。
        </div>
    </div>
</body>
</html>

后端API设计

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>后端API设计 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .api-endpoint {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .api-endpoint h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
        
        .method {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 3px;
            font-weight: bold;
            margin-right: 10px;
        }
        
        .get { background: #61affe; color: white; }
        .post { background: #49cc90; color: white; }
        .put { background: #fca130; color: white; }
        .delete { background: #f93e3e; color: white; }
    </style>
</head>
<body>
    <div class="container">
        <h1>后端API设计</h1>
        
        <h2>RESTful API设计原则</h2>
        <ul>
            <li>使用名词而非动词</li>
            <li>使用复数形式</li>
            <li>使用HTTP方法表示操作</li>
            <li>返回适当的状态码</li>
            <li>支持过滤、排序、分页</li>
        </ul>
        
        <h2>文章API</h2>
        
        <div class="api-endpoint">
            <h3>获取文章列表</h3>
            <div class="code-block">
                <pre>
<span class="method get">GET</span> /api/articles

查询参数:
- page: 页码(默认1)
- limit: 每页数量(默认10)
- category: 分类ID
- tag: 标签名称
- status: 文章状态
- sort: 排序字段(默认created_at)
- order: 排序方式(asc/desc,默认desc)

响应示例:
{
    "success": true,
    "data": {
        "articles": [...],
        "pagination": {
            "page": 1,
            "limit": 10,
            "total": 100,
            "pages": 10
        }
    }
}
                </pre>
            </div>
        </div>
        
        <div class="api-endpoint">
            <h3>创建文章</h3>
            <div class="code-block">
                <pre>
<span class="method post">POST</span> /api/articles

请求体:
{
    "title": "文章标题",
    "content": "文章内容(Markdown)",
    "excerpt": "文章摘要",
    "cover_image": "封面图片URL",
    "category_id": "分类ID",
    "tags": ["标签1", "标签2"],
    "status": "published"
}

响应示例:
{
    "success": true,
    "data": {
        "article": {
            "_id": "文章ID",
            "title": "文章标题",
            ...
        }
    }
}
                </pre>
            </div>
        </div>
        
        <div class="api-endpoint">
            <h3>更新文章</h3>
            <div class="code-block">
                <pre>
<span class="method put">PUT</span> /api/articles/:id

请求体:
{
    "title": "新标题",
    "content": "新内容",
    ...
}

响应示例:
{
    "success": true,
    "data": {
        "article": {
            "_id": "文章ID",
            "title": "新标题",
            ...
        }
    }
}
                </pre>
            </div>
        </div>
        
        <div class="api-endpoint">
            <h3>删除文章</h3>
            <div class="code-block">
                <pre>
<span class="method delete">DELETE</span> /api/articles/:id

响应示例:
{
    "success": true,
    "message": "文章已删除"
}
                </pre>
            </div>
        </div>
        
        <h2>认证API</h2>
        
        <div class="api-endpoint">
            <h3>用户注册</h3>
            <div class="code-block">
                <pre>
<span class="method post">POST</span> /api/auth/register

请求体:
{
    "username": "用户名",
    "email": "邮箱",
    "password": "密码"
}

响应示例:
{
    "success": true,
    "data": {
        "user": {
            "_id": "用户ID",
            "username": "用户名",
            "email": "邮箱"
        },
        "token": "JWT令牌"
    }
}
                </pre>
            </div>
        </div>
        
        <div class="api-endpoint">
            <h3>用户登录</h3>
            <div class="code-block">
                <pre>
<span class="method post">POST</span> /api/auth/login

请求体:
{
    "email": "邮箱",
    "password": "密码"
}

响应示例:
{
    "success": true,
    "data": {
        "user": {
            "_id": "用户ID",
            "username": "用户名",
            "email": "邮箱"
        },
        "token": "JWT令牌"
    }
}
                </pre>
            </div>
        </div>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>API设计要遵循RESTful原则,保持一致性和可预测性。使用合适的HTTP状态码和错误处理机制,让API易于使用和调试。
        </div>
    </div>
</body>
</html>

前端实现

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>前端实现 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .frontend-demo {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .frontend-demo h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>前端实现</h1>
        
        <h2>文章列表页面</h2>
        
        <div class="frontend-demo">
            <h3>HTML结构</h3>
            <div class="code-block">
                <pre>
&lt;!-- 文章列表 --&gt;
&lt;div class="article-list"&gt;
    &lt;!-- 文章卡片 --&gt;
    &lt;article class="article-card"&gt;
        &lt;img src="cover.jpg" alt="文章封面" class="article-cover"&gt;
        &lt;div class="article-content"&gt;
            &lt;h2 class="article-title"&gt;
                &lt;a href="/article/slug"&gt;文章标题&lt;/a&gt;
            &lt;/h2&gt;
            &lt;p class="article-excerpt"&gt;文章摘要...&lt;/p&gt;
            &lt;div class="article-meta"&gt;
                &lt;span class="author"&gt;作者名&lt;/span&gt;
                &lt;span class="date"&gt;2024-01-01&lt;/span&gt;
                &lt;span class="category"&gt;分类名&lt;/span&gt;
            &lt;/div&gt;
            &lt;div class="article-tags"&gt;
                &lt;a href="/tag/javascript" class="tag"&gt;JavaScript&lt;/a&gt;
                &lt;a href="/tag/html" class="tag"&gt;HTML&lt;/a&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/article&gt;
&lt;/div&gt;

&lt;!-- 分页 --&gt;
&lt;div class="pagination"&gt;
    &lt;a href="?page=1" class="page-link"&gt;1&lt;/a&gt;
    &lt;a href="?page=2" class="page-link"&gt;2&lt;/a&gt;
    &lt;a href="?page=3" class="page-link"&gt;3&lt;/a&gt;
&lt;/div&gt;
                </pre>
            </div>
        </div>
        
        <h2>文章详情页面</h2>
        
        <div class="frontend-demo">
            <h3>HTML结构</h3>
            <div class="code-block">
                <pre>
&lt;!-- 文章详情 --&gt;
&lt;article class="article-detail"&gt;
    &lt;header class="article-header"&gt;
        &lt;h1 class="article-title"&gt;文章标题&lt;/h1&gt;
        &lt;div class="article-meta"&gt;
            &lt;img src="author-avatar.jpg" alt="作者头像" class="author-avatar"&gt;
            &lt;div class="author-info"&gt;
                &lt;span class="author-name"&gt;作者名&lt;/span&gt;
                &lt;time class="publish-date"&gt;2024-01-01&lt;/time&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/header&gt;
    
    &lt;div class="article-cover"&gt;
        &lt;img src="cover.jpg" alt="文章封面"&gt;
    &lt;/div&gt;
    
    &lt;div class="article-content"&gt;
        &lt;!-- Markdown渲染后的HTML内容 --&gt;
    &lt;/div&gt;
    
    &lt;footer class="article-footer"&gt;
        &lt;div class="article-tags"&gt;
            &lt;a href="/tag/javascript" class="tag"&gt;JavaScript&lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="article-actions"&gt;
            &lt;button class="like-btn"&gt;点赞&lt;/button&gt;
            &lt;button class="share-btn"&gt;分享&lt;/button&gt;
        &lt;/div&gt;
    &lt;/footer&gt;
&lt;/article&gt;

&lt;!-- 评论区域 --&gt;
&lt;section class="comments-section"&gt;
    &lt;h2&gt;评论&lt;/h2&gt;
    &lt;!-- 评论表单 --&gt;
    &lt;form class="comment-form"&gt;
        &lt;textarea name="content" placeholder="发表评论..."&gt;&lt;/textarea&gt;
        &lt;button type="submit"&gt;提交评论&lt;/button&gt;
    &lt;/form&gt;
    &lt;!-- 评论列表 --&gt;
    &lt;div class="comment-list"&gt;
        &lt;!-- 评论项 --&gt;
    &lt;/div&gt;
&lt;/section&gt;
                </pre>
            </div>
        </div>
        
        <h2>Markdown编辑器</h2>
        
        <div class="frontend-demo">
            <h3>编辑器实现</h3>
            <div class="code-block">
                <pre>
&lt;!-- Markdown编辑器 --&gt;
&lt;div class="markdown-editor"&gt;
    &lt;div class="editor-toolbar"&gt;
        &lt;button data-action="bold"&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;/button&gt;
        &lt;button data-action="italic"&gt;&lt;em&gt;I&lt;/em&gt;&lt;/button&gt;
        &lt;button data-action="heading"&gt;H&lt;/button&gt;
        &lt;button data-action="link"&gt;链接&lt;/button&gt;
        &lt;button data-action="image"&gt;图片&lt;/button&gt;
        &lt;button data-action="code"&gt;代码&lt;/button&gt;
    &lt;/div&gt;
    
    &lt;div class="editor-container"&gt;
        &lt;textarea id="markdown-input" placeholder="输入Markdown内容..."&gt;&lt;/textarea&gt;
        &lt;div id="markdown-preview"&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;script&gt;
// 简单的Markdown渲染器
function renderMarkdown(markdown) {
    // 标题
    markdown = markdown.replace(/^### (.*$)/gim, '&lt;h3&gt;$1&lt;/h3&gt;');
    markdown = markdown.replace(/^## (.*$)/gim, '&lt;h2&gt;$1&lt;/h2&gt;');
    markdown = markdown.replace(/^# (.*$)/gim, '&lt;h1&gt;$1&lt;/h1&gt;');
    
    // 粗体和斜体
    markdown = markdown.replace(/\*\*(.*?)\*\*/gim, '&lt;strong&gt;$1&lt;/strong&gt;');
    markdown = markdown.replace(/\*(.*?)\*/gim, '&lt;em&gt;$1&lt;/em&gt;');
    
    // 链接
    markdown = markdown.replace(/\[([^\]]+)\]\(([^\)]+)\)/gim, '&lt;a href="$2"&gt;$1&lt;/a&gt;');
    
    // 代码块
    markdown = markdown.replace(/```([\s\S]*?)```/gim, '&lt;pre&gt;&lt;code&gt;$1&lt;/code&gt;&lt;/pre&gt;');
    markdown = markdown.replace(/`([^`]+)`/gim, '&lt;code&gt;$1&lt;/code&gt;');
    
    // 段落
    markdown = markdown.replace(/\n/gim, '&lt;br&gt;');
    
    return markdown;
}

// 实时预览
const input = document.getElementById('markdown-input');
const preview = document.getElementById('markdown-preview');

input.addEventListener('input', function() {
    preview.innerHTML = renderMarkdown(this.value);
});
&lt;/script&gt;
                </pre>
            </div>
        </div>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>前端实现要注重用户体验。使用合理的布局、清晰的视觉层次和流畅的交互,让用户专注于内容本身。
        </div>
    </div>
</body>
</html>

用户认证

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>用户认证 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .auth-demo {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .auth-demo h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>用户认证</h1>
        
        <h2>JWT认证机制</h2>
        
        <div class="auth-demo">
            <h3>JWT令牌结构</h3>
            <div class="code-block">
                <pre>
// JWT由三部分组成:Header.Payload.Signature

// Header
{
    "alg": "HS256",
    "typ": "JWT"
}

// Payload
{
    "userId": "用户ID",
    "username": "用户名",
    "role": "用户角色",
    "iat": 1234567890,  // 签发时间
    "exp": 1234571490   // 过期时间
}

// Signature
HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
)
                </pre>
            </div>
        </div>
        
        <h2>登录表单</h2>
        
        <div class="auth-demo">
            <h3>HTML实现</h3>
            <div class="code-block">
                <pre>
&lt;form id="login-form" class="auth-form"&gt;
    &lt;div class="form-group"&gt;
        &lt;label for="email"&gt;邮箱&lt;/label&gt;
        &lt;input type="email" id="email" name="email" required&gt;
    &lt;/div&gt;
    
    &lt;div class="form-group"&gt;
        &lt;label for="password"&gt;密码&lt;/label&gt;
        &lt;input type="password" id="password" name="password" required&gt;
    &lt;/div&gt;
    
    &lt;div class="form-options"&gt;
        &lt;label&gt;
            &lt;input type="checkbox" name="remember"&gt; 记住我
        &lt;/label&gt;
        &lt;a href="/forgot-password" class="forgot-link"&gt;忘记密码?&lt;/a&gt;
    &lt;/div&gt;
    
    &lt;button type="submit" class="btn-primary"&gt;登录&lt;/button&gt;
&lt;/form&gt;

&lt;script&gt;
document.getElementById('login-form').addEventListener('submit', async (e) =&gt; {
    e.preventDefault();
    
    const formData = new FormData(e.target);
    const data = {
        email: formData.get('email'),
        password: formData.get('password')
    };
    
    try {
        const response = await fetch('/api/auth/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });
        
        const result = await response.json();
        
        if (result.success) {
            // 存储JWT令牌
            localStorage.setItem('token', result.data.token);
            localStorage.setItem('user', JSON.stringify(result.data.user));
            
            // 跳转到首页
            window.location.href = '/';
        } else {
            alert(result.message);
        }
    } catch (error) {
        console.error('登录失败:', error);
        alert('登录失败,请重试');
    }
});
&lt;/script&gt;
                </pre>
            </div>
        </div>
        
        <h2>认证中间件</h2>
        
        <div class="auth-demo">
            <h3>后端验证</h3>
            <div class="code-block">
                <pre>
// 认证中间件
function authMiddleware(req, res, next) {
    const token = req.headers.authorization?.split(' ')[1];
    
    if (!token) {
        return res.status(401).json({
            success: false,
            message: '未提供认证令牌'
        });
    }
    
    try {
        // 验证JWT令牌
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.user = decoded;
        next();
    } catch (error) {
        return res.status(401).json({
            success: false,
            message: '无效的认证令牌'
        });
    }
}

// 使用中间件保护路由
app.get('/api/profile', authMiddleware, (req, res) =&gt; {
    res.json({
        success: true,
        data: {
            user: req.user
        }
    });
});
                </pre>
            </div>
        </div>
        
        <h2>权限控制</h2>
        
        <div class="auth-demo">
            <h3>角色权限中间件</h3>
            <div class="code-block">
                <pre>
// 角色权限中间件
function roleMiddleware(...allowedRoles) {
    return (req, res, next) =&gt; {
        if (!req.user) {
            return res.status(401).json({
                success: false,
                message: '未认证'
            });
        }
        
        if (!allowedRoles.includes(req.user.role)) {
            return res.status(403).json({
                success: false,
                message: '权限不足'
            });
        }
        
        next();
    };
}

// 使用示例
app.delete('/api/articles/:id', 
    authMiddleware, 
    roleMiddleware('admin', 'author'), 
    deleteArticle
);
                </pre>
            </div>
        </div>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>用户认证是安全的关键环节。使用HTTPS传输、加密存储密码、设置合理的令牌过期时间,确保系统安全。
        </div>
    </div>
</body>
</html>

评论系统

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>评论系统 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .comment-demo {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .comment-demo h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>评论系统</h1>
        
        <h2>评论列表</h2>
        
        <div class="comment-demo">
            <h3>HTML结构</h3>
            <div class="code-block">
                <pre>
&lt;div class="comments-section"&gt;
    &lt;h2&gt;评论 (3)&lt;/h2&gt;
    
    &lt;!-- 评论表单 --&gt;
    &lt;form class="comment-form"&gt;
        &lt;textarea name="content" placeholder="发表评论..." required&gt;&lt;/textarea&gt;
        &lt;button type="submit"&gt;提交评论&lt;/button&gt;
    &lt;/form&gt;
    
    &lt;!-- 评论列表 --&gt;
    &lt;div class="comment-list"&gt;
        &lt;!-- 评论项 --&gt;
        &lt;div class="comment-item"&gt;
            &lt;img src="avatar.jpg" alt="用户头像" class="comment-avatar"&gt;
            &lt;div class="comment-body"&gt;
                &lt;div class="comment-header"&gt;
                    &lt;span class="comment-author"&gt;用户名&lt;/span&gt;
                    &lt;span class="comment-date"&gt;2024-01-01&lt;/span&gt;
                &lt;/div&gt;
                &lt;p class="comment-content"&gt;评论内容...&lt;/p&gt;
                &lt;div class="comment-actions"&gt;
                    &lt;button class="like-btn"&gt;点赞 (5)&lt;/button&gt;
                    &lt;button class="reply-btn"&gt;回复&lt;/button&gt;
                &lt;/div&gt;
                
                &lt;!-- 回复列表 --&gt;
                &lt;div class="reply-list"&gt;
                    &lt;div class="comment-item reply"&gt;
                        &lt;!-- 回复内容 --&gt;
                    &lt;/div&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
                </pre>
            </div>
        </div>
        
        <h2>评论提交</h2>
        
        <div class="comment-demo">
            <h3>JavaScript实现</h3>
            <div class="code-block">
                <pre>
// 提交评论
async function submitComment(articleId, content, parentId = null) {
    const token = localStorage.getItem('token');
    
    if (!token) {
        alert('请先登录');
        return;
    }
    
    try {
        const response = await fetch('/api/comments', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${token}`
            },
            body: JSON.stringify({
                article_id: articleId,
                content: content,
                parent_id: parentId
            })
        });
        
        const result = await response.json();
        
        if (result.success) {
            // 重新加载评论列表
            loadComments(articleId);
            // 清空表单
            document.querySelector('.comment-form textarea').value = '';
        } else {
            alert(result.message);
        }
    } catch (error) {
        console.error('提交评论失败:', error);
        alert('提交评论失败,请重试');
    }
}

// 加载评论列表
async function loadComments(articleId) {
    try {
        const response = await fetch(`/api/comments?article_id=${articleId}`);
        const result = await response.json();
        
        if (result.success) {
            renderComments(result.data.comments);
        }
    } catch (error) {
        console.error('加载评论失败:', error);
    }
}

// 渲染评论列表
function renderComments(comments) {
    const commentList = document.querySelector('.comment-list');
    commentList.innerHTML = comments.map(comment =&gt; `
        &lt;div class="comment-item"&gt;
            &lt;img src="${comment.user.avatar}" alt="头像" class="comment-avatar"&gt;
            &lt;div class="comment-body"&gt;
                &lt;div class="comment-header"&gt;
                    &lt;span class="comment-author"&gt;${comment.user.username}&lt;/span&gt;
                    &lt;span class="comment-date"&gt;${formatDate(comment.created_at)}&lt;/span&gt;
                &lt;/div&gt;
                &lt;p class="comment-content"&gt;${comment.content}&lt;/p&gt;
                &lt;div class="comment-actions"&gt;
                    &lt;button class="like-btn" onclick="likeComment('${comment._id}')"&gt;
                        点赞 (${comment.like_count})
                    &lt;/button&gt;
                    &lt;button class="reply-btn" onclick="showReplyForm('${comment._id}')"&gt;
                        回复
                    &lt;/button&gt;
                &lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    `).join('');
}
                </pre>
            </div>
        </div>
        
        <h2>评论审核</h2>
        
        <div class="comment-demo">
            <h3>审核流程</h3>
            <div class="code-block">
                <pre>
// 后端评论审核
app.post('/api/comments', authMiddleware, async (req, res) =&gt; {
    const { article_id, content, parent_id } = req.body;
    
    // 内容过滤
    const filteredContent = filterSensitiveWords(content);
    
    // 创建评论
    const comment = await Comment.create({
        article_id,
        user_id: req.user.id,
        content: filteredContent,
        parent_id,
        status: 'pending'  // 待审核状态
    });
    
    // 发送通知给管理员
    notifyAdmin('new_comment', comment);
    
    res.json({
        success: true,
        message: '评论已提交,等待审核'
    });
});

// 管理员审核评论
app.put('/api/admin/comments/:id/approve', 
    authMiddleware, 
    roleMiddleware('admin'), 
    async (req, res) =&gt; {
        await Comment.findByIdAndUpdate(req.params.id, {
            status: 'approved'
        });
        
        res.json({
            success: true,
            message: '评论已通过'
        });
    }
);
                </pre>
            </div>
        </div>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>评论系统要平衡开放性和安全性。提供便捷的评论功能,同时防止垃圾信息和恶意内容。合理的审核机制是必要的。
        </div>
    </div>
</body>
</html>

搜索功能

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>搜索功能 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .search-demo {
            background: #f8f9fa;
            padding: 20px;
            border: 2px solid #ddd;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .search-demo h3 {
            color: #667eea;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>搜索功能</h1>
        
        <h2>搜索界面</h2>
        
        <div class="search-demo">
            <h3>HTML结构</h3>
            <div class="code-block">
                <pre>
&lt;!-- 搜索框 --&gt;
&lt;div class="search-container"&gt;
    &lt;form class="search-form"&gt;
        &lt;input type="text" 
               id="search-input" 
               placeholder="搜索文章..." 
               autocomplete="off"&gt;
        &lt;button type="submit"&gt;搜索&lt;/button&gt;
    &lt;/form&gt;
    
    &lt;!-- 搜索建议 --&gt;
    &lt;div id="search-suggestions" class="search-suggestions"&gt;
        &lt;!-- 动态生成 --&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;!-- 搜索结果 --&gt;
&lt;div class="search-results"&gt;
    &lt;div class="search-info"&gt;
        找到 &lt;span id="result-count"&gt;0&lt;/span&gt; 个结果
    &lt;/div&gt;
    &lt;div id="results-container"&gt;
        &lt;!-- 动态生成 --&gt;
    &lt;/div&gt;
&lt;/div&gt;
                </pre>
            </div>
        </div>
        
        <h2>实时搜索</h2>
        
        <div class="search-demo">
            <h3>JavaScript实现</h3>
            <div class="code-block">
                <pre>
// 防抖函数
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () =&gt; {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

// 搜索建议
const searchInput = document.getElementById('search-input');
const suggestionsContainer = document.getElementById('search-suggestions');

const showSuggestions = debounce(async (query) =&gt; {
    if (query.length &lt; 2) {
        suggestionsContainer.style.display = 'none';
        return;
    }
    
    try {
        const response = await fetch(`/api/search/suggestions?q=${encodeURIComponent(query)}`);
        const result = await response.json();
        
        if (result.success && result.data.suggestions.length &gt; 0) {
            suggestionsContainer.innerHTML = result.data.suggestions.map(item =&gt; `
                &lt;div class="suggestion-item" onclick="selectSuggestion('${item.title}')"&gt;
                    &lt;span class="suggestion-title"&gt;${highlightMatch(item.title, query)}&lt;/span&gt;
                    &lt;span class="suggestion-category"&gt;${item.category}&lt;/span&gt;
                &lt;/div&gt;
            `).join('');
            suggestionsContainer.style.display = 'block';
        } else {
            suggestionsContainer.style.display = 'none';
        }
    } catch (error) {
        console.error('搜索建议失败:', error);
    }
}, 300);

searchInput.addEventListener('input', (e) =&gt; {
    showSuggestions(e.target.value);
});

// 高亮匹配文本
function highlightMatch(text, query) {
    const regex = new RegExp(`(${query})`, 'gi');
    return text.replace(regex, '&lt;mark&gt;$1&lt;/mark&gt;');
}

// 选择建议
function selectSuggestion(title) {
    searchInput.value = title;
    suggestionsContainer.style.display = 'none';
    performSearch(title);
}
                </pre>
            </div>
        </div>
        
        <h2>后端搜索</h2>
        
        <div class="search-demo">
            <h3>全文搜索实现</h3>
            <div class="code-block">
                <pre>
// MongoDB全文搜索
app.get('/api/search', async (req, res) =&gt; {
    const { q, category, tag, sort, page = 1, limit = 10 } = req.query;
    
    try {
        // 构建查询条件
        let query = { status: 'published' };
        
        if (q) {
            // 全文搜索
            query.$text = { $search: q };
        }
        
        if (category) {
            query.category_id = category;
        }
        
        if (tag) {
            query.tags = tag;
        }
        
        // 排序选项
        let sortOption = { created_at: -1 };
        if (sort === 'popular') {
            sortOption = { view_count: -1 };
        } else if (sort === 'likes') {
            sortOption = { like_count: -1 };
        }
        
        // 执行查询
        const articles = await Article.find(query)
            .sort(sortOption)
            .skip((page - 1) * limit)
            .limit(parseInt(limit))
            .populate('author_id', 'username avatar')
            .populate('category_id', 'name');
        
        // 总数
        const total = await Article.countDocuments(query);
        
        res.json({
            success: true,
            data: {
                articles,
                pagination: {
                    page: parseInt(page),
                    limit: parseInt(limit),
                    total,
                    pages: Math.ceil(total / limit)
                }
            }
        });
    } catch (error) {
        res.status(500).json({
            success: false,
            message: '搜索失败'
        });
    }
});
                </pre>
            </div>
        </div>
        
        <h2>高级搜索</h2>
        
        <div class="search-demo">
            <h3>多条件搜索</h3>
            <div class="code-block">
                <pre>
// 高级搜索表单
&lt;form class="advanced-search"&gt;
    &lt;div class="search-row"&gt;
        &lt;input type="text" name="keyword" placeholder="关键词"&gt;
    &lt;/div&gt;
    
    &lt;div class="search-row"&gt;
        &lt;select name="category"&gt;
            &lt;option value=""&gt;所有分类&lt;/option&gt;
            &lt;option value="tech"&gt;技术&lt;/option&gt;
            &lt;option value="life"&gt;生活&lt;/option&gt;
        &lt;/select&gt;
        
        &lt;select name="date_range"&gt;
            &lt;option value=""&gt;所有时间&lt;/option&gt;
            &lt;option value="week"&gt;最近一周&lt;/option&gt;
            &lt;option value="month"&gt;最近一月&lt;/option&gt;
            &lt;option value="year"&gt;最近一年&lt;/option&gt;
        &lt;/select&gt;
        
        &lt;select name="sort"&gt;
            &lt;option value="date"&gt;按时间排序&lt;/option&gt;
            &lt;option value="popular"&gt;按热度排序&lt;/option&gt;
            &lt;option value="likes"&gt;按点赞排序&lt;/option&gt;
        &lt;/select&gt;
    &lt;/div&gt;
    
    &lt;button type="submit"&gt;搜索&lt;/button&gt;
&lt;/form&gt;
                </pre>
            </div>
        </div>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>搜索功能是内容型网站的核心功能。提供实时搜索建议、多条件筛选和排序选项,帮助用户快速找到所需内容。
        </div>
    </div>
</body>
</html>

部署与维护

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>部署与维护 - 东巴文</title>
    
    <style>
        body {
            font-family: 'Segoe UI', sans-serif;
            padding: 20px;
            background: #f5f5f5;
        }
        
        .container {
            max-width: 800px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 10px;
        }
        
        h1 {
            color: #667eea;
            margin-bottom: 20px;
        }
        
        h2 {
            color: #764ba2;
            margin: 30px 0 15px;
            border-left: 4px solid #764ba2;
            padding-left: 15px;
        }
        
        .deployment-card {
            background: #d4edda;
            border: 2px solid #28a745;
            padding: 20px;
            margin: 15px 0;
            border-radius: 10px;
        }
        
        .deployment-card h3 {
            color: #155724;
            margin-bottom: 10px;
        }
        
        .code-block {
            background: #2d2d2d;
            color: #f8f8f2;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            margin: 10px 0;
        }
        
        .info-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        
        .info-table th,
        .info-table td {
            padding: 12px;
            text-align: left;
            border: 1px solid #ddd;
        }
        
        .info-table th {
            background: #667eea;
            color: white;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>部署与维护</h1>
        
        <h2>部署选项</h2>
        
        <table class="info-table">
            <thead>
                <tr>
                    <th>部署方式</th>
                    <th>优点</th>
                    <th>缺点</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>云服务器(VPS)</td>
                    <td>完全控制,灵活配置</td>
                    <td>需要运维知识,成本较高</td>
                </tr>
                <tr>
                    <td>PaaS平台</td>
                    <td>简单快捷,自动扩展</td>
                    <td>限制较多,成本随使用增长</td>
                </tr>
                <tr>
                    <td>容器化部署</td>
                    <td>环境一致,易于迁移</td>
                    <td>学习曲线陡峭</td>
                </tr>
                <tr>
                    <td>Serverless</td>
                    <td>按需付费,自动扩展</td>
                    <td>冷启动延迟,调试困难</td>
                </tr>
            </tbody>
        </table>
        
        <h2>服务器部署</h2>
        
        <div class="deployment-card">
            <h3>Node.js应用部署</h3>
            <div class="code-block">
                <pre>
# 1. 安装Node.js和npm
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# 2. 安装PM2进程管理器
sudo npm install -g pm2

# 3. 克隆项目代码
git clone https://github.com/username/blog.git
cd blog

# 4. 安装依赖
npm install --production

# 5. 配置环境变量
cp .env.example .env
nano .env  # 编辑配置文件

# 6. 启动应用
pm2 start ecosystem.config.js

# 7. 设置开机自启
pm2 startup
pm2 save

# 8. 配置Nginx反向代理
sudo nano /etc/nginx/sites-available/blog
                </pre>
            </div>
        </div>
        
        <h2>Nginx配置</h2>
        
        <div class="deployment-card">
            <h3>反向代理配置</h3>
            <div class="code-block">
                <pre>
server {
    listen 80;
    server_name example.com www.example.com;
    
    # 重定向到HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL证书配置
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # SSL优化配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    
    # 静态文件缓存
    location /static/ {
        alias /var/www/blog/public/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    
    # API代理
    location /api/ {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
    
    # 前端路由
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
                </pre>
            </div>
        </div>
        
        <h2>数据库备份</h2>
        
        <div class="deployment-card">
            <h3>自动备份脚本</h3>
            <div class="code-block">
                <pre>
#!/bin/bash

# MongoDB备份脚本
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/var/backups/mongodb"
DB_NAME="blog"

# 创建备份目录
mkdir -p $BACKUP_DIR

# 执行备份
mongodump --db $DB_NAME --out $BACKUP_DIR/$DATE

# 压缩备份文件
tar -czf $BACKUP_DIR/$DATE.tar.gz -C $BACKUP_DIR $DATE

# 删除原始备份目录
rm -rf $BACKUP_DIR/$DATE

# 删除30天前的备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete

echo "备份完成: $DATE.tar.gz"
                </pre>
            </div>
        </div>
        
        <h2>监控与日志</h2>
        
        <div class="deployment-card">
            <h3>应用监控</h3>
            <ul>
                <li><strong>PM2监控:</strong> pm2 monit</li>
                <li><strong>日志管理:</strong> pm2 logs</li>
                <li><strong>性能监控:</strong> New Relic, Datadog</li>
                <li><strong>错误追踪:</strong> Sentry</li>
                <li><strong>正常运行时间:</strong> UptimeRobot</li>
            </ul>
        </div>
        
        <h2>维护清单</h2>
        <ul>
            <li>✅ 定期更新依赖包</li>
            <li>✅ 监控服务器资源使用</li>
            <li>✅ 定期备份数据库</li>
            <li>✅ 检查安全日志</li>
            <li>✅ 更新SSL证书</li>
            <li>✅ 清理日志文件</li>
            <li>✅ 监控应用性能</li>
            <li>✅ 定期安全审计</li>
        </ul>
        
        <div style="background: #fff3cd; padding: 15px; border-radius: 5px; margin-top: 20px;">
            <strong>东巴文提示:</strong>部署不是终点,而是新的起点。建立完善的监控和备份机制,定期维护和更新,确保系统稳定运行。
        </div>
    </div>
</body>
</html>

学习检验

基础问题

  1. 博客系统应该包含哪些核心功能?
  2. 如何设计博客系统的数据库模型?
  3. RESTful API设计原则是什么?
  4. 如何实现用户认证和权限控制?

实践任务

  1. 设计并实现一个简单的博客系统
  2. 实现文章的CRUD操作
  3. 添加用户注册和登录功能
  4. 实现评论系统

进阶挑战

  1. 添加Markdown编辑器支持
  2. 实现全文搜索功能
  3. 添加文章分类和标签管理
  4. 部署到云服务器并配置域名

东巴文(db-w.cn) 提醒:博客系统是学习Web开发的最佳实践项目。从简单开始,逐步增加功能,在实践中学习和成长。记住,好的博客系统应该让内容创作变得简单愉快。