14 KiB
14 KiB
飞点健康官网 CMS 系统 - 架构设计文档
1. 项目概述
基于 fumamxCRM 技术栈重写飞点健康(尿大夫/吾大夫/吴试纸)企业官网,采用模块化首页设计,支持后台可视化配置。
2. 技术栈
前端
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 19.2.4 | UI 框架 |
| Vite | 8.0.4 | 构建工具 |
| TailwindCSS | 4.2.2 | 样式框架 |
| React Router | 7.14.1 | 路由管理 |
| @uiw/react-md-editor | ^4.1.0 | Markdown 编辑器 |
| Lucide React | ^1.8.0 | 图标库 |
后端
| 技术 | 版本 | 用途 |
|---|---|---|
| Python | 3.12 | 运行环境 |
| FastAPI | ^0.115 | Web 框架 |
| SQLAlchemy | ^2.0 | ORM |
| Pydantic | ^2.0 | 数据验证 |
| JWT | ^2.8 | 认证 |
| Uvicorn | ^0.32 | ASGI 服务器 |
数据库
- SQLite - 轻量级数据库,适合 CMS 场景
3. 系统架构
┌─────────────────────────────────────────────────────────────┐
│ 客户端 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ PC 浏览器 │ │ 平板浏览器 │ │ 手机浏览器 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Nginx 反向代理 │
│ (端口: 10002 前端 / 10003 API) │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┴───────────────┐
▼ ▼
┌───────────────────────┐ ┌───────────────────────────┐
│ 前端 (React + Vite) │ │ 后端 (FastAPI) │
│ 端口: 10002 │ │ 端口: 10003 │
│ serve 静态部署 │ │ Uvicorn 运行 │
│ │ │ │
│ ┌─────────────────┐ │ │ ┌─────────────────────┐ │
│ │ 前台用户端 │ │ │ │ API 路由层 │ │
│ │ - 首页 │ │◄─────►│ │ - /api/* │ │
│ │ - 产品页 │ │ │ └─────────────────────┘ │
│ │ - 新闻页 │ │ │ │ │
│ └─────────────────┘ │ │ ▼ │
│ ┌─────────────────┐ │ │ ┌─────────────────────┐ │
│ │ 后台管理端 │ │◄─────►│ │ 服务层 (Services) │ │
│ │ - 首页模块管理 │ │ │ │ - 首页模块服务 │ │
│ │ - 导航管理 │ │ │ │ - 内容管理服务 │ │
│ │ - 内容管理 │ │ │ │ - 认证服务 │ │
│ └─────────────────┘ │ │ └─────────────────────┘ │
│ │ │ │ │
└────────────────────────┘ │ ▼ │
│ ┌─────────────────────┐ │
│ │ 数据访问层 (ORM) │ │
│ │ SQLAlchemy Models │ │
│ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ SQLite 数据库 │ │
│ │ cms.db │ │
│ └─────────────────────┘ │
│ │
└────────────────────────────┘
4. 目录结构
website-new/
├── docs/ # 设计文档
│ ├── ARCHITECTURE.md # 架构设计
│ ├── DATABASE.md # 数据库设计
│ ├── API.md # API 接口文档
│ ├── FRONTEND.md # 前端组件设计
│ ├── NEWS_MODULE_DESIGN.md # 新闻模块设计
│ └── ROADMAP.md # 实现路线图
│
├── backend/ # 后端项目
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # FastAPI 入口
│ │ ├── config.py # 配置(含 UPLOAD_DIR 等)
│ │ ├── database.py # 数据库连接
│ │ ├── auth.py # JWT 认证
│ │ ├── models/ # SQLAlchemy 模型
│ │ │ ├── __init__.py
│ │ │ ├── admin.py # 管理员
│ │ │ ├── home_module.py # 首页模块
│ │ │ ├── image.py # 图片资源
│ │ │ ├── nav_menu.py # 导航菜单
│ │ │ ├── news_category.py # 新闻栏目
│ │ │ ├── news_post.py # 新闻资讯
│ │ │ └── setting.py # 系统设置
│ │ ├── routers/ # API 路由
│ │ │ ├── __init__.py
│ │ │ ├── auth.py # 认证接口
│ │ │ ├── crawl.py # 文章采集
│ │ │ ├── home_modules.py # 首页模块接口
│ │ │ ├── images.py # 图片资源管理
│ │ │ ├── nav_menus.py # 导航菜单接口
│ │ │ ├── news.py # 新闻资讯接口
│ │ │ ├── settings.py # 系统设置接口
│ │ │ └── upload.py # 通用文件上传
│ │ └── utils/
│ │ └── file_utils.py # 文件工具(含缩略图清理)
│ ├── requirements.txt
│ └── cms.db # SQLite 数据库
│
├── frontend/ # 前端项目
│ ├── src/
│ │ ├── main.jsx # React 入口
│ │ ├── App.jsx # 根组件
│ │ ├── api/ # API 请求封装
│ │ │ └── index.js # 自定义 ApiClient
│ │ ├── components/ # 公共组件
│ │ │ ├── admin/ # 后台通用组件
│ │ │ │ ├── Badge.jsx
│ │ │ │ ├── Button.jsx
│ │ │ │ ├── Card.jsx
│ │ │ │ ├── Input.jsx
│ │ │ │ ├── Modal.jsx
│ │ │ │ ├── Stats.jsx
│ │ │ │ └── Table.jsx
│ │ │ ├── AdminLayout.jsx # 后台布局
│ │ │ ├── HelpModal.jsx
│ │ │ └── Layout.jsx # 前台布局
│ │ ├── contexts/
│ │ │ └── AuthContext.jsx # 认证上下文
│ │ ├── pages/ # 页面组件
│ │ │ ├── admin/ # 后台管理页
│ │ │ │ ├── images/
│ │ │ │ │ └── ImageManager.jsx # 图片管理
│ │ │ │ ├── news/
│ │ │ │ │ ├── CategoryList.jsx # 栏目管理
│ │ │ │ │ ├── CrawlNews.jsx # 采集新闻
│ │ │ │ │ ├── PostEdit.jsx # 添加/编辑资讯
│ │ │ │ │ └── PostList.jsx # 资讯列表
│ │ │ │ ├── BannerManage.jsx
│ │ │ │ ├── FeaturesManage.jsx
│ │ │ │ └── HomeManage.jsx
│ │ │ ├── AdminHome.jsx
│ │ │ ├── Login.jsx
│ │ │ ├── Modules.jsx
│ │ │ ├── NavMenus.jsx
│ │ │ ├── NewsDetail.jsx
│ │ │ ├── NewsList.jsx
│ │ │ ├── PublicHome.jsx
│ │ │ └── Settings.jsx
│ │ ├── App.css
│ │ └── index.css
│ ├── index.html
│ ├── package.json
│ └── vite.config.js
│
├── storage/ # 文件存储目录
│ ├── admin/
│ │ └── images/ # 管理员上传图片
│ │ ├── thumbnails/ # 自动生成的缩略图
│ │ ├── banners/ # 轮播图(手动维护)
│ │ ├── features/ # 特色展示图(手动维护)
│ │ └── 202604/ # 按月分组的旧文件
│ └── public/ # 公开文件(预留)
│
└── scripts/ # 启动脚本
├── start-backend.sh
└── start-frontend.sh
5. 部署架构
| 服务 | 端口 | 命令 | 说明 |
|---|---|---|---|
| 前端开发 | 10002 | npm run dev |
Vite 开发服务器(含代理) |
| 前端生产 | 10002 | serve -s dist -l 10002 |
静态文件服务 |
| 后端 | 10003 | uvicorn app.main:app --host 0.0.0.0 --port 10003 |
API 服务 |
Vite 代理配置(开发环境)
// vite.config.js
proxy: {
'/api': { target: 'http://localhost:10003', changeOrigin: true },
'/uploads': { target: 'http://localhost:10003', changeOrigin: true },
'/storage': { target: 'http://localhost:10003', changeOrigin: true },
}
静态文件挂载(后端)
# main.py
app.mount("/uploads", StaticFiles(directory="storage/admin/images"), name="uploads")
app.mount("/storage/admin", StaticFiles(directory="storage/admin"), name="storage_admin")
app.mount("/storage/public", StaticFiles(directory="storage/public"), name="storage_public")
6. 设计风格:新粗野主义 (Neobrutalism)
参考 personal-blog 和 RetroUI 项目:
| 元素 | 规范 |
|---|---|
| 主背景 | #FEF9E7 奶油色 |
| 边框 | 2px 纯黑硬边框 |
| 阴影 | 4px 硬阴影偏移 |
| 圆角 | 无(直角) |
| 强调色 | 粉红 #FF6B9D、青色 #00D9FF、黄色 #FFDE59 |
| 交互 | 点击位移 + 阴影消失 |
7. 图片存储架构
7.1 存储路径规则
| 配置项 | 值 | 说明 |
|---|---|---|
UPLOAD_DIR |
../storage/admin/images |
相对于 backend/ 目录 |
| 实际物理路径 | {project_root}/storage/admin/images |
项目根目录下的 storage |
| 缩略图目录 | {UPLOAD_DIR}/thumbnails |
自动生成 |
重要: UPLOAD_DIR 配置值是基于后端启动目录(backend/)的相对路径。从 backend/ 到 storage/admin/images 只需 ../storage/admin/images(上一级到项目根目录)。
7.2 图片生命周期管理
上传流程:
- 接收上传文件 → 校验格式和大小
- 生成唯一文件名:
YYYYMMDD_HHMMSS_xxxxxxxx.ext - 保存原图到
storage/admin/images/ - 自动创建缩略图到
storage/admin/images/thumbnails/ - 写入数据库(记录路径为
/storage/admin/images/...)
缩略图规则:
- 最大尺寸:300x300 像素,等比缩放
- 格式:统一为 JPEG,质量 85%
- 命名:与原图同名,扩展名统一为
.jpg - 失败处理:缩略图创建失败时,
thumb_path为null
删除规则:
- 单条删除:
DELETE /api/images/{id}→ 删除数据库记录 + 物理文件(原图 + 缩略图) - 批量删除:
POST /api/images/batch-delete→ 同上,循环处理 - 资讯删除:删除资讯时同步删除封面图及其缩略图
- 外部 URL:删除时跳过物理文件(仅删除数据库记录)
清理工具: app/utils/file_utils.py
cleanup_file(): 根据路径删除文件及缩略图cleanup_file_by_path(): 包装函数,支持/storage/admin/images/格式路径
7.3 图片访问路径
| 类型 | URL 格式 | 物理路径 |
|---|---|---|
| 原图 | /storage/admin/images/{filename} |
storage/admin/images/{filename} |
| 缩略图 | /storage/admin/images/thumbnails/{filename}.jpg |
storage/admin/images/thumbnails/{filename}.jpg |
| 兼容旧路径 | /uploads/{filename} |
与 /storage/admin/images/ 指向同一目录 |
8. 安全策略
- 认证: JWT + Bearer Token
- 密码: bcrypt 加密存储
- CORS: 允许前端域名访问
- 上传: 限制文件类型(jpg, png, gif, webp, bmp)和大小(10MB)
- SQL: 使用 ORM 防止注入
- 文件访问: 防止目录遍历攻击(
file_path.resolve().relative_to()检查)
9. 性能目标
- API 响应时间 < 300ms
- 首页加载时间 < 2s
- 支持图片懒加载