添加后端todo-list

This commit is contained in:
Jiao77
2025-10-21 01:44:01 +08:00
parent 9ffb74becf
commit 4919bc6194
3 changed files with 2617 additions and 0 deletions

791
docs/DETAILED_TODOLIST.md Normal file
View File

@@ -0,0 +1,791 @@
# 🚀 网站现代化重构 - 详尽 TodoList
**项目周期**4-6 周 | **总任务数**87 项 | **优先级分布**P0(22) | P1(35) | P2(20) | P3(10)
---
## 📋 任务约定
- 🔴 **P0 - 必须**:项目核心,必须完成
- 🟠 **P1 - 重要**:功能完整性,应该完成
- 🟡 **P2 - 优化**:用户体验,可选完成
- 🟢 **P3 - 未来**:后续功能,后期实现
**状态说明**
-`not-started` - 未开始
- 🟦 `in-progress` - 进行中
-`completed` - 已完成
---
## 🎯 第一阶段:环境准备 & 项目规划(第 1 周)
### 🔴 P0 任务:项目初始化
#### 1.1 后端项目创建
- [ ] 创建 `/backend` 目录结构
```
backend/
├── src/
│ ├── server.ts
│ ├── config/
│ ├── routes/
│ ├── controllers/
│ ├── middleware/
│ ├── database/
│ └── types/
├── tests/
├── .env.example
├── package.json
└── tsconfig.json
```
- [ ] 初始化 Node.js 项目:`npm init -y`
- [ ] 安装基础依赖:`npm install express cors dotenv pg`
- [ ] 安装开发依赖:`npm install -D typescript @types/node @types/express ts-node nodemon`
- [ ] 创建 `.env` 和 `.env.example` 文件
- [ ] 创建 `tsconfig.json` 配置文件
- [ ] 创建 `package.json` 脚本配置
#### 1.2 前端项目升级
- [ ] 升级 Astro 到最新版本:`npm install astro@latest`
- [ ] 安装 React 集成:`npm install @astrojs/react react react-dom`
- [ ] 安装 API 相关依赖:`npm install axios zod isomorphic-dompurify`
- [ ] 验证项目能正常构建
#### 1.3 数据库规划
- [ ] 创建数据库初始化脚本目录 `backend/sql/`
- [ ] 制定数据库连接策略
- [ ] 准备 PostgreSQL 本地开发环境
- [ ] 创建数据库连接池配置
### 🟠 P1 任务:文档编写
#### 1.4 API 文档
- [ ] 编写完整的 API 规范文档
- [ ] 定义评论 API 端点
- [ ] 定义统计 API 端点
- [ ] 定义用户 API 端点
- [ ] 定义错误响应格式
#### 1.5 架构文档
- [ ] 绘制系统架构图
- [ ] 编写数据流说明
- [ ] 列出安全考虑点
- [ ] 记录性能优化策略
### 🟡 P2 任务:设计文档
#### 1.6 UI/UX 设计
- [ ] 设计评论区域样式
- [ ] 设计统计卡片样式
- [ ] 制定色系和排版规范
- [ ] 创建组件设计稿
---
## 🎯 第二阶段:后端开发(第 2-3 周)
### 🔴 P0 任务:核心基础设施
#### 2.1 Server 启动和基础配置
- [ ] 创建 `src/server.ts` 主文件
- [ ] 配置 Express 应用基础
- [ ] 配置 CORS 中间件
- [ ] 配置 JSON 解析中间件
- [ ] 实现环境变量加载
- [ ] 设置错误处理中间件
- [ ] 实现 404 路由处理
- [ ] 测试服务器启动成功
#### 2.2 数据库连接
- [ ] 创建 `src/database/connection.ts`
- [ ] 配置 PostgreSQL 连接池
- [ ] 实现连接错误处理
- [ ] 实现连接超时处理
- [ ] 添加连接测试函数
- [ ] 验证连接可用性
#### 2.3 数据库 Schema
- [ ] 创建 `backend/sql/001_init_schema.sql`
- [ ] 定义 `comments` 表
```sql
- id: SERIAL PRIMARY KEY
- report_id: VARCHAR(100)
- author: VARCHAR(100)
- email: VARCHAR(100)
- content: TEXT
- status: VARCHAR(20)
- created_at: TIMESTAMP
- updated_at: TIMESTAMP
```
- [ ] 定义 `report_stats` 表
```sql
- id: SERIAL PRIMARY KEY
- report_id: VARCHAR(100) UNIQUE
- views: INTEGER
- comments: INTEGER
- likes: INTEGER
- shares: INTEGER
```
- [ ] 定义 `likes` 表
```sql
- id: SERIAL PRIMARY KEY
- report_id: VARCHAR(100)
- client_id: VARCHAR(100)
- created_at: TIMESTAMP
```
- [ ] 创建必要的索引
- `idx_comments_report_id`
- `idx_stats_report_id`
- `idx_likes_report_id`
- [ ] 创建 `backend/sql/002_add_constraints.sql` (外键约束)
- [ ] 创建迁移脚本运行器
#### 2.4 TypeScript 类型定义
- [ ] 创建 `src/types/comment.ts`
- [ ] 创建 `src/types/stats.ts`
- [ ] 创建 `src/types/like.ts`
- [ ] 创建 `src/types/error.ts`
- [ ] 创建 `src/types/api-response.ts`
### 🔴 P0 任务:评论系统 API
#### 2.5 评论模块 - 路由层
- [ ] 创建 `src/routes/comments.ts`
- [ ] `GET /api/comments` - 获取评论列表
- [ ] 支持分页page, limit
- [ ] 支持排序created_at, likes
- [ ] 支持过滤status, reportId
- [ ] `GET /api/comments/:id` - 获取单条评论
- [ ] `POST /api/comments` - 创建评论
- [ ] `PUT /api/comments/:id` - 更新评论(仅作者或管理员)
- [ ] `DELETE /api/comments/:id` - 删除评论(仅作者或管理员)
#### 2.6 评论模块 - 控制器层
- [ ] 创建 `src/controllers/commentController.ts`
- [ ] 实现 `getAllComments()` 逻辑
- [ ] 实现 `getCommentById()` 逻辑
- [ ] 实现 `createComment()` 逻辑
- [ ] 实现 `updateComment()` 逻辑
- [ ] 实现 `deleteComment()` 逻辑
- [ ] 添加数据验证逻辑
- [ ] 添加错误处理
#### 2.7 评论模块 - 数据库层
- [ ] 创建 `src/database/commentQueries.ts`
- [ ] 实现 `fetchCommentsByReport()`
- [ ] 实现 `fetchCommentById()`
- [ ] 实现 `insertComment()`
- [ ] 实现 `updateComment()`
- [ ] 实现 `deleteComment()`
- [ ] 实现 `countCommentsByReport()`
- [ ] 添加事务处理
### 🔴 P0 任务:统计系统 API
#### 2.8 统计模块 - 路由层
- [ ] 创建 `src/routes/stats.ts`
- [ ] `GET /api/stats/:reportId` - 获取统计数据
- [ ] `POST /api/stats/:reportId/view` - 记录浏览
- [ ] `POST /api/stats/:reportId/like` - 点赞
- [ ] `DELETE /api/stats/:reportId/like` - 取消点赞
- [ ] `POST /api/stats/:reportId/share` - 记录分享
- [ ] `GET /api/stats/trending` - 获取热门
#### 2.9 统计模块 - 控制器层
- [ ] 创建 `src/controllers/statsController.ts`
- [ ] 实现 `getStats()` 逻辑
- [ ] 实现 `recordView()` 逻辑
- [ ] 实现 `recordLike()` 逻辑
- [ ] 实现 `removeLike()` 逻辑
- [ ] 实现 `recordShare()` 逻辑
- [ ] 实现 `getTrending()` 逻辑
- [ ] 添加重复检查
#### 2.10 统计模块 - 数据库层
- [ ] 创建 `src/database/statsQueries.ts`
- [ ] 实现 `fetchStats()`
- [ ] 实现 `updateViews()`
- [ ] 实现 `addLike()`
- [ ] 实现 `removeLike()`
- [ ] 实现 `checkLikeExists()`
- [ ] 实现 `updateShares()`
- [ ] 实现 `fetchTrending()`
### 🟠 P1 任务:中间件和工具
#### 2.11 验证中间件
- [ ] 创建 `src/middleware/validation.ts`
- [ ] 实现评论数据验证 (Zod schema)
- [ ] 实现统计数据验证
- [ ] 实现错误转换中间件
- [ ] 添加日志中间件
#### 2.12 安全中间件
- [ ] 创建 `src/middleware/security.ts`
- [ ] 实现速率限制express-rate-limit
- [ ] 实现 CSRF 保护
- [ ] 实现 XSS 防护 (DOMPurify)
- [ ] 实现输入清理函数
#### 2.13 认证中间件(可选基础)
- [ ] 创建 `src/middleware/auth.ts`
- [ ] 实现 JWT 验证(预留)
- [ ] 实现权限检查函数
- [ ] 实现管理员标识
### 🟡 P2 任务:辅助功能
#### 2.14 工具函数
- [ ] 创建 `src/utils/helpers.ts`
- [ ] 实现分页计算函数
- [ ] 实现日期格式化
- [ ] 实现 ID 生成器
- [ ] 实现数据转换函数
#### 2.15 缓存策略
- [ ] 创建 `src/cache/cacheManager.ts`(预留 Redis
- [ ] 实现内存缓存方案
- [ ] 实现缓存失效策略
- [ ] 实现缓存预热
#### 2.16 日志系统
- [ ] 创建 `src/logger/logger.ts`
- [ ] 配置日志级别
- [ ] 实现日志文件轮转
- [ ] 实现错误日志记录
---
## 🎯 第三阶段:前端开发(第 3-4 周)
### 🔴 P0 任务Astro 混合渲染配置
#### 3.1 更新 Astro 配置
- [ ] 修改 `astro.config.mjs` 启用混合渲染
```javascript
output: 'hybrid'
adapter: node({ mode: 'standalone' })
```
- [ ] 配置 React 集成
- [ ] 验证混合渲染配置正确
- [ ] 测试静态和动态页面生成
#### 3.2 创建 API 客户端
- [ ] 创建 `src/lib/api-client.ts`
- [ ] 实现 HTTP 请求拦截器
- [ ] 实现错误处理
- [ ] 实现请求重试逻辑
- [ ] 配置 API 基础 URL
#### 3.3 创建 React 上下文(可选)
- [ ] 创建 `src/contexts/ReportContext.tsx`
- [ ] 实现统计数据共享
- [ ] 实现用户状态管理
- [ ] 实现通知管理
### 🔴 P0 任务:评论组件开发
#### 3.4 评论列表组件
- [ ] 创建 `src/components/comments/CommentList.tsx`
- [ ] 实现分页显示
- [ ] 实现排序切换
- [ ] 实现加载状态
- [ ] 实现空状态提示
- [ ] 实现错误状态提示
#### 3.5 评论表单组件
- [ ] 创建 `src/components/comments/CommentForm.tsx`
- [ ] 实现表单输入验证
- [ ] 实现字符计数
- [ ] 实现提交加载状态
- [ ] 实现成功/失败提示
- [ ] 实现防重复提交
#### 3.6 单条评论组件
- [ ] 创建 `src/components/comments/CommentItem.tsx`
- [ ] 实现用户信息展示
- [ ] 实现时间格式化
- [ ] 实现评论内容渲染XSS 防护)
- [ ] 实现编辑/删除按钮(权限检查)
- [ ] 实现回复按钮(预留)
#### 3.7 完整评论区域组件
- [ ] 创建 `src/components/comments/CommentSection.tsx`
- [ ] 组合 List、Form、Item 组件
- [ ] 实现数据获取逻辑
- [ ] 实现实时更新
- [ ] 实现错误边界
- [ ] 实现加载骨架屏
### 🔴 P0 任务:统计组件开发
#### 3.8 统计卡片组件
- [ ] 创建 `src/components/stats/StatCard.tsx`
- [ ] 实现数字动画展示
- [ ] 实现图标展示
- [ ] 实现趋势指示
- [ ] 实现加载状态
#### 3.9 统计面板组件
- [ ] 创建 `src/components/stats/StatsPanel.tsx`
- [ ] 组合多个 StatCard
- [ ] 实现数据获取
- [ ] 实现自动刷新
- [ ] 实现响应式布局
#### 3.10 点赞按钮组件
- [ ] 创建 `src/components/interactions/LikeButton.tsx`
- [ ] 实现点赞/取消点赞逻辑
- [ ] 实现动画效果
- [ ] 实现重复点赞防护
- [ ] 实现点赞数显示
#### 3.11 分享按钮组件
- [ ] 创建 `src/components/interactions/ShareButton.tsx`
- [ ] 实现复制链接功能
- [ ] 实现社交分享(可选)
- [ ] 实现分享统计
- [ ] 实现分享提示
### 🟠 P1 任务:页面集成
#### 3.12 报告页面更新
- [ ] 修改 `src/pages/report/ai-eda-paper-report/index.astro`
- [ ] 导入统计组件
- [ ] 导入评论组件
- [ ] 添加统计展示区域
- [ ] 添加评论区域
- [ ] 实现客户端加载指令
#### 3.13 其他报告页面
- [ ] 为其他报告页面添加统计功能
- [ ] 为其他报告页面添加评论功能
- [ ] 统一样式风格
- [ ] 验证功能一致性
### 🟡 P2 任务:交互优化
#### 3.14 加载状态
- [ ] 创建 `src/components/common/Skeleton.tsx` (骨架屏)
- [ ] 创建 `src/components/common/LoadingSpinner.tsx`
- [ ] 创建 `src/components/common/ErrorBoundary.tsx`
- [ ] 应用到所有异步组件
#### 3.15 通知系统
- [ ] 创建 `src/components/common/Toast.tsx`
- [ ] 实现成功提示
- [ ] 实现错误提示
- [ ] 实现警告提示
- [ ] 实现通知队列
#### 3.16 动画效果
- [ ] 实现数字动画库集成(可选)
- [ ] 添加评论出现动画
- [ ] 添加统计数字动画
- [ ] 添加过渡效果
---
## 🎯 第四阶段:集成与测试(第 4 周)
### 🔴 P0 任务:后端测试
#### 4.1 单元测试
- [ ] 安装测试框架:`npm install -D jest @types/jest ts-jest`
- [ ] 创建 `backend/tests/` 目录
- [ ] 编写评论 API 单元测试
- [ ] 测试 GET /api/comments
- [ ] 测试 POST /api/comments
- [ ] 测试数据验证
- [ ] 测试错误处理
- [ ] 编写统计 API 单元测试
- [ ] 测试 GET /api/stats/:reportId
- [ ] 测试 POST /api/stats/:reportId/view
- [ ] 测试 POST /api/stats/:reportId/like
- [ ] 运行测试,确保覆盖率 > 80%
#### 4.2 集成测试
- [ ] 创建测试数据库配置
- [ ] 编写评论完整流程测试
- [ ] 编写统计完整流程测试
- [ ] 编写并发场景测试
- [ ] 验证所有 API 端点
#### 4.3 API 文档测试
- [ ] 使用 Postman/Insomnia 测试所有端点
- [ ] 验证请求/响应格式
- [ ] 验证错误响应
- [ ] 记录实际的 API 示例
### 🔴 P0 任务:前端测试
#### 4.4 组件测试
- [ ] 安装测试库:`npm install -D vitest @testing-library/react`
- [ ] 编写 CommentForm 测试
- [ ] 测试表单提交
- [ ] 测试验证逻辑
- [ ] 测试错误显示
- [ ] 编写 StatsPanel 测试
- [ ] 测试数据加载
- [ ] 测试数据展示
- [ ] 编写 LikeButton 测试
- [ ] 测试点赞逻辑
- [ ] 测试防重复点赞
#### 4.5 集成测试
- [ ] 测试 Astro 页面 + React 组件集成
- [ ] 测试客户端加载指令
- [ ] 测试数据流
- [ ] 测试错误恢复
### 🟠 P1 任务E2E 测试
#### 4.6 用户场景测试
- [ ] 安装 E2E 框架:`npm install -D playwright`
- [ ] 测试查看报告流程
- [ ] 测试发布评论流程
- [ ] 测试点赞流程
- [ ] 测试分享流程
- [ ] 测试移动端响应
#### 4.7 性能测试
- [ ] 测试页面加载时间
- [ ] 测试 API 响应时间
- [ ] 测试并发用户压力
- [ ] 记录性能基线
### 🟡 P2 任务:安全测试
#### 4.8 安全审查
- [ ] 审查 XSS 防护
- [ ] 审查 SQL 注入防护
- [ ] 审查认证逻辑
- [ ] 审查 CORS 配置
- [ ] 测试速率限制
---
## 🎯 第五阶段:部署与优化(第 5 周)
### 🔴 P0 任务Docker 配置
#### 5.1 后端 Docker 化
- [ ] 创建 `Dockerfile`
- [ ] 创建 `.dockerignore`
- [ ] 定义构建阶段
- [ ] 定义运行阶段
- [ ] 优化镜像大小
- [ ] 本地测试 Docker 镜像
#### 5.2 前端 Docker 化
- [ ] 为前端创建 `Dockerfile`
- [ ] 多阶段构建
- [ ] 静态文件优化
- [ ] 本地测试
#### 5.3 Docker Compose
- [ ] 创建 `docker-compose.yml`
- [ ] 配置后端服务
- [ ] 配置前端服务
- [ ] 配置数据库服务
- [ ] 配置网络
- [ ] 测试本地完整运行
#### 5.4 数据库容器
- [ ] 配置 PostgreSQL 容器
- [ ] 持久化数据卷
- [ ] 初始化脚本
- [ ] 备份策略
### 🔴 P0 任务:环境配置
#### 5.5 生产环境变量
- [ ] 创建 `.env.production`
- [ ] 配置数据库 URL
- [ ] 配置 API 基础 URL
- [ ] 配置日志级别
- [ ] 配置 CORS 源
- [ ] 配置密钥
#### 5.6 环境管理
- [ ] 创建环境配置管理器
- [ ] 验证必需变量
- [ ] 文档化所有变量
### 🟠 P1 任务:部署配置
#### 5.7 Nginx 反向代理
- [ ] 创建 `nginx.conf`
- [ ] 配置前端路由
- [ ] 配置后端 API 反向代理
- [ ] 配置 Gzip 压缩
- [ ] 配置缓存策略
- [ ] 配置 SSL可选
#### 5.8 PM2 进程管理
- [ ] 创建 `ecosystem.config.js`
- [ ] 配置后端进程
- [ ] 配置前端构建进程
- [ ] 实现自动重启
- [ ] 配置日志轮转
#### 5.9 部署脚本
- [ ] 创建 `deploy.sh` 脚本
- [ ] 拉取最新代码
- [ ] 安装依赖
- [ ] 构建项目
- [ ] 运行数据库迁移
- [ ] 重启服务
- [ ] 健康检查
### 🟠 P1 任务:性能优化
#### 5.10 数据库优化
- [ ] 分析查询性能
- [ ] 添加必要的索引
- [ ] 优化 N+1 查询
- [ ] 实现查询缓存
- [ ] 监控连接池
#### 5.11 API 优化
- [ ] 实现 API 分页
- [ ] 实现字段选择select
- [ ] 实现 API 压缩
- [ ] 实现响应缓存
- [ ] 实现 CDN 集成
#### 5.12 前端优化
- [ ] 代码分割优化
- [ ] 图片优化
- [ ] 字体加载优化
- [ ] 缓存策略
- [ ] 预加载/预连接
### 🟡 P2 任务:监控与日志
#### 5.13 应用监控
- [ ] 配置应用性能监控 (APM)
- [ ] 配置错误追踪
- [ ] 配置日志聚合
- [ ] 设置告警规则
#### 5.14 基础设施监控
- [ ] 配置 CPU 监控
- [ ] 配置内存监控
- [ ] 配置磁盘监控
- [ ] 配置网络监控
---
## 🎯 第六阶段:上线与维护(第 6 周)
### 🔴 P0 任务:上线前准备
#### 6.1 最终检查清单
- [ ] 所有测试通过
- [ ] 代码审查完成
- [ ] 文档完整
- [ ] 安全审计通过
- [ ] 性能测试通过
- [ ] 备份策略就位
- [ ] 回滚计划准备
#### 6.2 数据迁移
- [ ] 备份现有数据
- [ ] 准备数据迁移脚本
- [ ] 测试数据迁移
- [ ] 准备回滚方案
#### 6.3 DNS 配置
- [ ] 配置域名解析
- [ ] 配置 SSL 证书
- [ ] 测试 HTTPS 连接
- [ ] 配置 CDN可选
### 🟠 P1 任务:灰度发布
#### 6.4 金丝雀发布
- [ ] 发布到测试服务器
- [ ] 在小部分用户中测试
- [ ] 监控错误率
- [ ] 逐步增加流量
- [ ] 完整上线
#### 6.5 发布公告
- [ ] 准备发布说明
- [ ] 通知用户新功能
- [ ] 准备常见问题解答
- [ ] 监控用户反馈
### 🟠 P1 任务:上线后维护
#### 6.6 监控第一周
- [ ] 日常监控指标
- [ ] 应对用户反馈
- [ ] 快速修复 bug
- [ ] 记录问题和解决方案
#### 6.7 长期维护计划
- [ ] 建立定期备份
- [ ] 定期安全更新
- [ ] 定期依赖更新
- [ ] 性能优化迭代
### 🟡 P2 任务:用户支持
#### 6.8 文档完善
- [ ] 完善用户指南
- [ ] 编写 FAQ
- [ ] 编写故障排查指南
- [ ] 建立反馈渠道
#### 6.9 持续改进
- [ ] 收集用户反馈
- [ ] 分析使用数据
- [ ] 规划功能迭代
- [ ] 优化用户体验
---
## 🎯 可选增强功能P3 任务)
### 🟢 P3用户系统
#### 7.1 用户认证
- [ ] 实现用户注册
- [ ] 实现用户登录
- [ ] 实现密码重置
- [ ] 实现社交登录
#### 7.2 用户资料
- [ ] 用户头像上传
- [ ] 用户信息编辑
- [ ] 用户偏好设置
- [ ] 用户隐私控制
### 🟢 P3高级评论功能
#### 7.3 评论增强
- [ ] 评论回复功能
- [ ] 评论点赞功能
- [ ] 评论举报功能
- [ ] 评论标签功能
- [ ] 评论搜索功能
### 🟢 P3AI 增强
#### 7.4 智能功能
- [ ] 评论内容审核AI
- [ ] 自动回复建议
- [ ] 评论总结
- [ ] 智能分类
### 🟢 P3社区功能
#### 7.5 社区建设
- [ ] 排行榜系统
- [ ] 徽章系统
- [ ] 积分系统
- [ ] 社区讨论区
- [ ] 用户关注
### 🟢 P3数据分析
#### 7.6 深度分析
- [ ] 用户行为分析
- [ ] 评论情感分析
- [ ] 内容热力分析
- [ ] 用户转化分析
---
## 📊 时间和资源预估
### 时间分配
```
第一周:环境和规划 - 40 小时
第二周:后端开发 - 60 小时
第三周:前端开发 - 60 小时
第四周:测试和集成 - 50 小时
第五周:部署和优化 - 50 小时
第六周:上线和维护 - 40 小时
总计:约 300 小时 ≈ 7-8 周(单人开发)
```
### 资源需求
- **开发者**1-2 人(可并行)
- **测试**:可通过自动化完成
- **运维**1 人(兼职)
- **服务器**
- VPS¥30-50/月
- 数据库¥10-20/月
- 存储¥5-10/月
---
## 🎯 优先级执行策略
### 如果时间紧张2 周完成)
**优先完成 P0 任务**
1. 后端基础 + 数据库
2. 评论和统计 API
3. 前端组件集成
4. 基础部署
**跳过**
- 完整测试 → 手动测试即可
- 性能优化 → 后期迭代
- 用户系统 → 第二期实现
### 正常周期4-6 周)
**完成所有 P0 + P1 任务**
- 完整功能实现
- 充分测试
- 完善文档
- 生产级部署
### 完全版本8-12 周)
**完成所有任务**
- 包含所有 P2 优化
- 包含 P3 高级功能
- 完整的监控和维护体系
---
## 📝 检查清单模板
### 每周完成检查
- [ ] 所有 P0 任务完成
- [ ] 代码审查通过
- [ ] 测试覆盖率 > 80%
- [ ] 文档更新
- [ ] 部署到测试环境
- [ ] 演示给利益相关者
### 上线前最终检查
- [ ] 所有单元测试通过
- [ ] 所有集成测试通过
- [ ] 所有 E2E 测试通过
- [ ] 性能测试通过(<2s 加载)
- [ ] 安全审计通过
- [ ] 备份和回滚计划准备好
- [ ] 监控和告警配置完成
- [ ] 团队培训完成
- [ ] 用户文档完备
- [ ] 发布公告准备好
---
## 🚀 下一步行动
现在可以开始执行这个 TodoList
1. **立即开始**:第一阶段任务(环境准备)
2. **并行进行**:后端和前端开发(第二、三阶段)
3. **定期检查**:每周检查进度和质量
4. **灵活调整**:根据实际情况调整优先级
**建议**:建立一个项目管理工具(如 Trello、Notion、Linear来追踪这些任务的进度。

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,681 @@
# 🎯 网站现代化重构方案
**目标**:将静态 Astro 网站升级为具有评论系统、数据统计、用户交互的动态网站
---
## 📊 方案对比
### 方案 AAstro + Node.js 后端(推荐)⭐⭐⭐⭐⭐
**最适合当前项目!**
#### 技术栈
- **前端**Astro + React/Vue 组件(动态部分)
- **后端**Node.js + Express/Fastify
- **数据库**PostgreSQL / MongoDB
- **缓存**Redis
- **API**REST / GraphQL
- **部署**Docker + PM2
#### 优势
✅ 前后端分离,灵活可维护
✅ Astro 保留静态生成的性能优势
✅ 支持实时数据更新
✅ 可扩展性强
✅ 成熟的技术生态
#### 架构图
```
┌─────────────────────────────────────┐
│ 用户浏览器 (静态部分) │
├─────────────────────────────────────┤
│ Astro 静态生成 │
│ - 首页、报告页面 │
│ - SEO 优化 │
└────────────────┬────────────────────┘
┌────────▼────────┐
│ 动态组件加载 │
│ (React/Vue) │
├─────────────────┤
│ - 评论系统 │
│ - 数据统计 │
│ - 用户互动 │
└────────┬────────┘
│ API 调用
┌────────▼────────┐
│ Node.js 后端 │
├─────────────────┤
│ - 用户管理 │
│ - 评论处理 │
│ - 数据分析 │
│ - 权限控制 │
└────────┬────────┘
┌────────▼────────┐
│ 数据库 │
├─────────────────┤
│ - PostgreSQL │
│ - Redis Cache │
└─────────────────┘
```
---
### 方案 BAstro + 第三方服务(快速启动)⭐⭐⭐⭐
**无需后端维护,快速上线**
#### 技术栈
- **前端**Astro保持不变
- **评论**Disqus / Giscus / Utterances
- **数据统计**Google Analytics / Plausible
- **用户系统**Supabase / Firebase
- **内容管理**Contentful / Sanity
- **部署**Vercel / Netlify
#### 优势
✅ 零后端维护
✅ 快速集成
✅ 自动扩展
✅ 成本低
✅ 部署简单
#### 缺点
❌ 功能受限
❌ 数据隐私性
❌ 成本可能增加
---
### 方案 CAstro + Hybrid Rendering终极方案⭐⭐⭐⭐⭐
**Astro 4.0+ 的新特性:静态和动态混合**
#### 技术栈
- **Astro Hybrid SSR**:部分页面服务端渲染
- **后端**Node.js
- **数据库**PostgreSQL
- **实时**WebSocket
- **部署**:自托管或 Vercel
#### 优势
✅ 性能最优
✅ SEO 完美
✅ 实时交互
✅ 完全控制
---
## 🏗️ 推荐方案详细实现
### 方案 A完整实现步骤
#### 第一阶段前端重构1-2周
**1. 更新 Astro 配置支持混合渲染**
```javascript
// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import tailwind from '@astrojs/tailwind';
import node from '@astrojs/node';
export default defineConfig({
integrations: [
react(),
tailwind(),
],
// 启用混合渲染
output: 'hybrid',
adapter: node({
mode: 'standalone'
}),
vite: {
define: {
'process.env.NODE_ENV': JSON.stringify('production')
}
}
});
```
**2. 创建动态 React 组件**
```typescript
// src/components/comments/CommentSection.tsx
import React, { useState, useEffect } from 'react';
import type { Comment } from '../../types/comment';
export default function CommentSection({ reportId }: { reportId: string }) {
const [comments, setComments] = useState<Comment[]>([]);
const [newComment, setNewComment] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
fetchComments();
}, [reportId]);
const fetchComments = async () => {
try {
const response = await fetch(`/api/comments?reportId=${reportId}`);
const data = await response.json();
setComments(data);
} catch (error) {
console.error('Failed to fetch comments:', error);
}
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
const response = await fetch('/api/comments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
reportId,
content: newComment,
author: 'Anonymous', // 需要用户系统
})
});
const comment = await response.json();
setComments([...comments, comment]);
setNewComment('');
} catch (error) {
console.error('Failed to post comment:', error);
} finally {
setLoading(false);
}
};
return (
<div className="mt-8 p-6 bg-white rounded-lg shadow">
<h2 className="text-2xl font-bold mb-4"> ({comments.length})</h2>
{/* 评论列表 */}
<div className="space-y-4 mb-6">
{comments.map((comment) => (
<div key={comment.id} className="p-4 bg-gray-50 rounded-lg">
<div className="flex justify-between items-start">
<strong className="text-gray-800">{comment.author}</strong>
<time className="text-sm text-gray-500">
{new Date(comment.createdAt).toLocaleDateString('zh-CN')}
</time>
</div>
<p className="text-gray-600 mt-2">{comment.content}</p>
</div>
))}
</div>
{/* 评论表单 */}
<form onSubmit={handleSubmit} className="pt-6 border-t">
<textarea
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
placeholder="分享你的想法..."
className="w-full p-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
rows={4}
required
/>
<button
type="submit"
disabled={loading}
className="mt-3 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
>
{loading ? '发布中...' : '发布评论'}
</button>
</form>
</div>
);
}
```
**3. 创建数据统计组件**
```typescript
// src/components/stats/ReportStats.tsx
import React, { useState, useEffect } from 'react';
import type { ReportStats as Stats } from '../../types/stats';
export default function ReportStats({ reportId }: { reportId: string }) {
const [stats, setStats] = useState<Stats | null>(null);
useEffect(() => {
fetch(`/api/stats/${reportId}`)
.then(r => r.json())
.then(setStats);
}, [reportId]);
if (!stats) return <div>...</div>;
return (
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 p-6 bg-gradient-to-r from-blue-50 to-purple-50 rounded-lg">
<div className="text-center">
<div className="text-3xl font-bold text-blue-600">{stats.views}</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-green-600">{stats.comments}</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-yellow-600">{stats.likes}</div>
<div className="text-sm text-gray-600"></div>
</div>
<div className="text-center">
<div className="text-3xl font-bold text-red-600">{stats.shares}</div>
<div className="text-sm text-gray-600"></div>
</div>
</div>
);
}
```
#### 第二阶段后端开发2-3周
**1. 创建 Node.js 后端**
```typescript
// server/index.ts
import express from 'express';
import cors from 'cors';
import { Pool } from 'pg';
const app = express();
app.use(cors());
app.use(express.json());
// 数据库连接
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});
// ==================== 评论 API ====================
// 获取评论
app.get('/api/comments', async (req, res) => {
try {
const { reportId } = req.query;
const result = await pool.query(
`SELECT * FROM comments
WHERE report_id = $1
ORDER BY created_at DESC`,
[reportId]
);
res.json(result.rows);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 发布评论
app.post('/api/comments', async (req, res) => {
try {
const { reportId, content, author, email } = req.body;
// 数据验证
if (!content || content.length > 5000) {
return res.status(400).json({ error: '评论内容无效' });
}
const result = await pool.query(
`INSERT INTO comments (report_id, content, author, email, created_at)
VALUES ($1, $2, $3, $4, NOW())
RETURNING *`,
[reportId, content, author, email]
);
res.json(result.rows[0]);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// ==================== 统计 API ====================
// 获取报告统计
app.get('/api/stats/:reportId', async (req, res) => {
try {
const { reportId } = req.params;
const result = await pool.query(
`SELECT
COALESCE(views, 0) as views,
COALESCE(comments, 0) as comments,
COALESCE(likes, 0) as likes,
COALESCE(shares, 0) as shares
FROM report_stats
WHERE report_id = $1`,
[reportId]
);
res.json(result.rows[0] || {
views: 0,
comments: 0,
likes: 0,
shares: 0
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// 记录浏览
app.post('/api/stats/:reportId/view', async (req, res) => {
try {
const { reportId } = req.params;
await pool.query(
`INSERT INTO report_stats (report_id, views)
VALUES ($1, 1)
ON CONFLICT (report_id)
DO UPDATE SET views = views + 1`,
[reportId]
);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// ==================== 点赞 API ====================
app.post('/api/stats/:reportId/like', async (req, res) => {
try {
const { reportId } = req.params;
const clientId = req.body.clientId; // 使用客户端 ID 避免重复点赞
const checkResult = await pool.query(
`SELECT * FROM likes WHERE report_id = $1 AND client_id = $2`,
[reportId, clientId]
);
if (checkResult.rows.length > 0) {
return res.status(400).json({ error: '已点赞' });
}
await pool.query(
`INSERT INTO likes (report_id, client_id) VALUES ($1, $2)`,
[reportId, clientId]
);
await pool.query(
`UPDATE report_stats SET likes = likes + 1 WHERE report_id = $1`,
[reportId]
);
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
```
**2. 数据库 schema**
```sql
-- 评论表
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL,
email VARCHAR(100),
content TEXT NOT NULL,
status VARCHAR(20) DEFAULT 'pending', -- pending, approved, rejected
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 报告统计表
CREATE TABLE report_stats (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) UNIQUE NOT NULL,
views INTEGER DEFAULT 0,
comments INTEGER DEFAULT 0,
likes INTEGER DEFAULT 0,
shares INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 点赞表
CREATE TABLE likes (
id SERIAL PRIMARY KEY,
report_id VARCHAR(100) NOT NULL,
client_id VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(report_id, client_id)
);
-- 索引优化
CREATE INDEX idx_comments_report ON comments(report_id);
CREATE INDEX idx_stats_report ON report_stats(report_id);
CREATE INDEX idx_likes_report ON likes(report_id);
```
#### 第三阶段集成与部署1-2周
**1. 在 Astro 页面中使用新组件**
```astro
---
// src/pages/report/ai-eda-paper-report/index.astro
// ... 其他导入
import CommentSection from '../../../components/comments/CommentSection';
import ReportStats from '../../../components/stats/ReportStats';
const reportId = 'ai-eda-paper-report';
// 记录浏览
if (Astro.request.method === 'GET') {
await fetch('http://localhost:3000/api/stats/ai-eda-paper-report/view', {
method: 'POST'
});
}
---
<BaseLayout ...>
<!-- 统计卡片 -->
<ReportStats client:load reportId={reportId} />
<!-- ... 其他内容 -->
<!-- 评论系统 -->
<CommentSection client:load reportId={reportId} />
</BaseLayout>
```
**2. Docker 部署**
```dockerfile
# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
```
**3. Docker Compose**
```yaml
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:password@postgres:5432/jiao77
NODE_ENV: production
depends_on:
- postgres
restart: unless-stopped
postgres:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: jiao77
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- api
restart: unless-stopped
volumes:
postgres_data:
```
---
## 📋 实施路线图
| 阶段 | 任务 | 时间 | 优先级 |
|-----|------|------|--------|
| **P0** | 前端Astro 混合渲染配置 | 3天 | 🔴 必须 |
| **P0** | 前端React 评论组件 | 4天 | 🔴 必须 |
| **P0** | 后端Express 基础项目 | 2天 | 🔴 必须 |
| **P1** | 后端:评论 API | 3天 | 🟠 重要 |
| **P1** | 后端:统计 API | 2天 | 🟠 重要 |
| **P1** | 数据库设计与优化 | 2天 | 🟠 重要 |
| **P2** | 前端:统计组件 | 2天 | 🟡 可选 |
| **P2** | 用户认证系统 | 5天 | 🟡 可选 |
| **P3** | 测试与优化 | 3天 | 🟢 后续 |
| **P3** | Docker 部署 | 2天 | 🟢 后续 |
---
## 💰 成本对比
### 方案 A自托管年成本
- VPS¥360-1200
- 域名¥69
- SSL免费 (Let's Encrypt)
- 总计:≈ ¥500/年
### 方案 B第三方服务年成本
- Disqus Pro$120
- Firebase≈ $50-500
- Google Analytics免费
- 总计:≈ ¥1000-4000/年
### 方案 CVercel 部署(年成本)
- 高级计划:$20/月
- 数据库¥500/年
- 总计:≈ ¥3000/年
---
## 🔒 安全建议
1. **数据验证**
```typescript
// 使用 zod 进行数据验证
import { z } from 'zod';
const CommentSchema = z.object({
reportId: z.string().min(1),
content: z.string().min(1).max(5000),
author: z.string().min(1).max(100),
email: z.string().email().optional()
});
```
2. **XSS 防护**
```typescript
import DOMPurify from 'isomorphic-dompurify';
const sanitized = DOMPurify.sanitize(userInput);
```
3. **速率限制**
```typescript
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100
});
app.post('/api/comments', limiter, (req, res) => {
// ...
});
```
4. **CORS 配置**
```typescript
app.use(cors({
origin: process.env.ALLOWED_ORIGINS?.split(','),
credentials: true
}));
```
---
## 📈 性能优化
1. **查询优化**
- 添加数据库索引
- 使用分页加载评论
- Redis 缓存热门数据
2. **前端优化**
- 代码分割
- 懒加载评论组件
- 虚拟滚动(大量评论)
3. **CDN 加速**
- 静态资源 CDN
- API 响应缓存
---
## 🎯 总结
**最推荐方案:方案 AAstro + Node.js + PostgreSQL**
**完全控制**:所有功能自主开发
**成本低**:仅需便宜 VPS
**性能好**Astro 保留优势
**可扩展**:微服务架构
**学习价值**:深入技术栈
---
## 🚀 快速开始
你想我帮你立即开始哪个方面?
1. **立即创建后端项目** → 生成 Express 项目结构
2. **更新 Astro 配置** → 启用混合渲染
3. **创建 React 组件** → 评论和统计组件
4. **设计数据库** → SQL 脚本和迁移
5. **Docker 配置** → 完整部署方案