头条【vue+fastapi 】全栈教学项目系列之《04_项目架构与文件结构说明书》

本文是 头条【vue+fastapi 】全栈教学项目系列之《架构说明》
📎 配套开源项目(均已开源,欢迎 Star / Fork)

📐 项目架构与文件结构说明书

目的:全面理解项目的组织方式和设计思路

适合时机:开发过程中随时查阅,理解"为什么这样设计"


一、项目总览

1.1 技术架构图

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                         用户浏览器                              │
│                    (Chrome / Safari / 手机浏览器)               │
└──────────────────────────┬──────────────────────────────────────┘
                           │ HTTP/HTTPS
                           ▼
┌─────────────────────────────────────────────────────────────────┐
│                      前端 (Frontend)                            │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                   Vue 3 + Vite                          │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐  │   │
│  │  │ Vue     │ │ Vant UI │ │ Vue     │ │  Pinia      │  │   │
│  │  │ Router  │ │ 组件库   │ │ I18n    │ │  状态管理    │  │   │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────────┘  │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐                 │   │
│  │  │ Axios   │ │ Marked  │ │ DOMPure │                 │   │
│  │  │ HTTP    │ │ MD渲染  │ │ XSS防护 │                 │   │
│  │  └─────────┘ └─────────┘ └─────────┘                 │   │
│  └──────────────────────────┬──────────────────────────────┘   │
└─────────────────────────────┼──────────────────────────────────┘
                              │ RESTful API
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                      后端 (Backend)                             │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                    FastAPI                                │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐  │   │
│  │  │ Routes  │ │ Schemas │ │  CRUD   │ │  Models      │  │   │
│  │  │ 路由层  │ │ 数据验证│ │ 数据操作│ │  ORM模型     │  │   │
│  │  └─────────┘ └─────────┘ └─────────┘ └─────────────┘  │   │
│  │  ┌─────────┐ ┌─────────┐ ┌─────────┐                 │   │
│  │  │ Auth    │ │ Security│ │ Response│                 │   │
│  │  │ JWT认证 │ │ 密码加密│ │ 统一响应│                 │   │
│  │  └─────────┘ └─────────┘ └─────────┘                 │   │
│  └──────────────────────────┬──────────────────────────────┘   │
│  ┌──────────────────────────┴──────────────────────────────┐   │
│  │              数据层 (Data Layer)                         │   │
│  │  ┌─────────────────┐  ┌─────────────────┐              │   │
│  │  │     MySQL       │  │     Redis       │              │   │
│  │  │  (持久化存储)    │  │  (缓存/会话)    │              │   │
│  │  └─────────────────┘  └─────────────────┘              │   │
│  └─────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

1.2 前后端交互流程

复制代码
用户操作 → 前端组件 → Vuex/Pinia Store → Axios HTTP请求
                                            │
                                            ▼
                                      FastAPI Router
                                            │
                                            ▼
                                      Pydantic验证
                                            │
                                            ▼
                                      CRUD操作
                                            │
                                            ▼
                                    ┌───────┴───────┐
                                    ▼               ▼
                                  MySQL           Redis
                                    │               │
                                    └───────┬───────┘
                                            ▼
                                      JSON响应
                                            │
                                            ▼
                                   前端接收→更新状态→视图更新

二、完整目录树

2.1 项目顶层结构

复制代码
toutiao_heima-main/                     # 项目根目录
├── README.md                           # 项目说明文档
├── docs_output/                        # 教学文档输出目录(本套文档)
│   ├── 01_项目导学与学习大纲.md
│   ├── 02_双系统零基础环境搭建手册.md
│   ├── 03_分阶段分步实操指引.md
│   ├── 04_项目架构与文件结构说明书.md    ← 你在这里
│   ├── 05_源码注释与核心知识点手册.md
│   ├── 06_高频报错排查手册.md
│   ├── 07_功能测试与学生验收清单.md
│   └── 08_项目部署与进阶拓展指南.md
│
├── toutiao_frontend/                   # 【前端项目】Vue 3 + Vite
│   ├── public/                        # 静态资源目录
│   │   └── favicon.ico
│   ├── src/                           # 源代码目录
│   │   ├── views/                     # 页面组件(12个)
│   │   ├── components/                # 公共组件
│   │   ├── router/                    # 路由配置
│   │   ├── api/                       # 网络请求层(request 实例 + 拦截器)
│   │   ├── store/                     # 状态管理(Pinia)
│   │   ├── config/                    # 配置文件(后端地址常量)
│   │   ├── i18n/                      # 国际化
│   │   ├── utils/                     # 工具函数
│   │   ├── App.vue                    # 根组件
│   │   ├── main.js                    # 入口文件
│   │   └── style.css                  # 全局样式
│   ├── index.html                     # HTML模板
│   ├── package.json                   # 项目依赖配置(已显式声明 vue)
│   ├── vite.config.js                 # Vite构建配置(构建期 drop console)
│   ├── .env.example                  # 环境变量模板(真实 .env 不入库)
│   └── .gitignore                    # 已排除真实 .env 与 node_modules
│
└── toutiao_backend/                   # 【后端项目】FastAPI + MySQL
    ├── main.py                        # 应用入口
    ├── database.py                    # 数据库初始化
    ├── models.py                      # 数据模型(旧版)
    ├── auth.py                        # 认证模块(旧版)
    ├── requirements.txt               # Python依赖
    ├── config/                        # 配置模块
    │   ├── db_conf.py                 # 数据库配置
    │   ├── cache_conf.py              # Redis配置
    │   └── ai_conf.py                 # AI/OpenAI配置
    ├── models/                        # ORM模型(新版分层)
    │   ├── users.py                   # 用户模型
    │   ├── news.py                    # 新闻模型
    │   ├── favorite.py                # 收藏模型
    │   └── history.py                 # 历史模型
    ├── schemas/                       # Pydantic数据验证
    │   ├── base.py                    # 基础Schema
    │   ├── users.py                   # 用户Schema
    │   ├── favorite.py                # 收藏Schema
    │   ├── histroy.py                 # 历史Schema
    │   └── aichat.py                  # AI Schema
    ├── crud/                          # 数据库操作层
    │   ├── users.py                   # 用户CRUD
    │   ├── news.py                    # 新闻CRUD
    │   ├── news_cache.py              # 新闻缓存CRUD
    │   ├── favorite.py                # 收藏CRUD
    │   └── history.py                 # 历史CRUD
    ├── routers/                       # API路由层
    │   ├── __init__.py
    │   ├── users.py                   # 用户路由
    │   ├── news.py                    # 新闻路由
    │   ├── favorite.py                # 收藏路由
    │   ├── history.py                 # 历史路由
    │   └── aichat.py                  # AI路由
    └── utils/                         # 工具模块
        ├── auth.py                    # JWT认证
        ├── security.py                # 密码加密
        ├── response.py                # 统一响应
        ├── exception.py               # 自定义异常
        └── exception_handlers.py      # 异常处理器

三、前端文件详解

3.1 入口文件

main.js - 应用入口

文件路径toutiao_frontend/src/main.js

作用:Vue应用的起点,负责创建Vue实例并挂载到DOM

核心职责

  1. 创建Vue应用实例
  2. 注册全局插件(Router、Pinia、I18n)
  3. 引入全局样式
  4. 挂载应用到 #app DOM元素

依赖关系

复制代码
main.js
  ├── App.vue (根组件)
  ├── router/index.js (路由)
  ├── stores/* (状态管理)
  └── i18n (国际化)

App.vue - 根组件

文件路径toutiao_frontend/src/App.vue

作用:应用的最外层组件,包含全局布局

核心功能

  • 渲染 <router-view /> (路由出口)
  • 条件显示底部TabBar导航
  • 应用主题类名(亮色/暗色)

组件结构

复制代码
App.vue
  ├── <router-view />     ← 页面内容区(根据路由变化)
  └── <TabBar />          ← 底部导航(某些页面隐藏)

vite.config.js - 构建配置

文件路径toutiao_frontend/vite.config.js

作用:Vite构建工具的配置文件

关键配置项

配置项 说明
plugins [vue()] 使用Vue插件
server.port 5173 开发服务器端口
server.proxy./api localhost:8000 API代理到后端
server.proxy./docs localhost:8000 Swagger文档代理

为什么需要代理?

  • 开发环境前端运行在 :5173,后端在 :8000
  • 浏览器的同源策略禁止跨域请求
  • Vite代理将 /api 开头的请求转发到后端
  • 生产环境不需要(前端打包后和后端同源部署)

3.2 路由配置

router/index.js - 路由定义

文件路径toutiao_frontend/src/router/index.js

作用:定义URL路径与页面组件的映射关系

路由表

路径 组件 是否显示TabBar 说明
/ Home.vue 首页(新闻列表)
/category Category.vue 分类浏览页
/news/:id NewsDetail.vue 新闻详情页(动态参数)
/favorite Favorite.vue 我的收藏
/history History.vue 浏览历史
/aichat AIChat.vue AI问答
/my My.vue 个人中心
/login Login.vue 登录页
/register Register.vue 注册页
/profile Profile.vue 编辑资料
/settings Settings.vue 设置页

路由守卫

  • beforeEach 钩子:根据路由meta.title设置页面标题

3.3 页面组件(views/)

视图组件总览
复制代码
src/views/
├── Home.vue           # 首页 - 新闻列表、分类标签、下拉刷新、上拉加载
├── Login.vue          # 登录页 - 用户名密码表单
├── Register.vue       # 注册页 - 用户名密码手机号表单
├── NewsDetail.vue     # 新闻详情 - 内容渲染、收藏、评论
├── Category.vue       # 分类浏览 - 按分类查看新闻
├── Favorite.vue       # 我的收藏 - 收藏列表
├── History.vue        # 浏览历史 - 历史记录列表
├── AIChat.vue         # AI问答 - 对话界面
├── My.vue             # 个人中心 - 用户信息、功能入口
├── Profile.vue        # 编辑资料 - 修改昵称头像简介
└── Settings.vue       # 设置页 - 主题切换、语言切换
各页面详细说明
Home.vue - 首页

功能清单

  • 顶部导航栏(标题 + 搜索入口)
  • 分类标签栏(横向滚动,9个分类)
  • 新闻列表(封面图 + 标签 + 摘要 + 元信息)
  • 下拉刷新(PullRefresh)
  • 上拉加载更多(List组件)
  • 点击进入详情页

使用的StoreuseNewsStore()

API调用

  • GET /api/news/categories - 获取分类
  • GET /api/news/list - 获取新闻列表(分页)

组件依赖NewsItem.vue(新闻列表项子组件)


Login.vue - 登录页

功能清单

  • Logo和标语
  • 用户名输入框(必填验证)
  • 密码输入框(必填验证)
  • 登录按钮(带Loading状态)
  • 注册入口链接

使用的StoreuseUserStore()

API调用POST /api/user/login

交互逻辑

  1. 用户填写表单
  2. 点击登录 → 显示Loading
  3. 调用登录API
  4. 成功 → 保存Token → 跳转首页
  5. 失败 → 显示错误提示

Register.vue - 注册页

功能清单

  • 用户名输入(3-50字符)
  • 密码输入(6-100字符)
  • 确认密码输入(必须一致)
  • 手机号输入(可选,11位数字)
  • 注册协议勾选
  • 注册按钮

API调用POST /api/user/register


NewsDetail.vue - 新闻详情页

功能清单

  • 顶部导航(标题 + 收藏按钮)
  • 新闻标题
  • 元信息(作者、来源、时间、阅读量)
  • 封面图
  • Markdown正文渲染(防XSS)
  • 底部互动栏(点赞、评论、分享)
  • 评论区(输入框 + 评论列表)

使用的Store

  • useFavoriteStore() - 收藏操作
  • useHistoryStore() - 添加历史

API调用

  • GET /api/news/detail/:id - 获取详情
  • POST /api/favorite/add - 添加收藏
  • DELETE /api/favorite/remove - 取消收藏
  • GET /api/favorite/check - 检查收藏状态
  • POST /api/history/add - 添加历史
  • GET/POST /api/comment/* - 评论相关

第三方库

  • marked - Markdown转HTML
  • DOMPurify - HTML消毒(防XSS攻击)

Favorite.vue - 我的收藏

功能清单

  • 收藏新闻列表(与首页类似)
  • 空状态提示(无收藏时)
  • 取消收藏(滑动删除或按钮)
  • 清空全部收藏
  • 点击进入详情

API调用

  • GET /api/favorite/list - 获取收藏列表
  • DELETE /api/favorite/remove - 取消收藏
  • POST /api/favorite/clear - 清空收藏

History.vue - 浏览历史

功能清单

  • 历史记录列表(按时间倒序)
  • 分组显示(今天、昨天、更早)
  • 删除单条记录
  • 清空全部历史
  • 点击进入详情

API调用

  • GET /api/history/list - 获取历史列表
  • POST /api/history/clear - 清空历史

AIChat.vue - AI问答

功能清单

  • 对话消息列表(用户 + AI)
  • 消息输入框
  • 发送按钮
  • Loading状态(AI思考中)
  • Markdown回复渲染
  • 清空对话

API调用POST /api/aichat/chat

特殊处理

  • 流式响应(可选优化)
  • 对话上下文维护

My.vue - 个人中心

功能清单

  • 用户信息卡片(头像、昵称、简介)
  • 未登录状态显示"点击登录"
  • 功能入口列表:
    • 我的收藏(带数量角标)
    • 浏览历史(带数量角标)
    • AI问答
    • 编辑资料
    • 设置
  • 退出登录按钮

条件渲染

  • 根据 isLoggedIn() 显示不同内容

Settings.vue - 设置页

功能清单

  • 深色模式开关(Switch组件)
  • 语言选择(ActionSheet弹出)
  • 关于信息
  • 版本号显示

使用的Store

  • useThemeStore() - 主题切换
  • useLanguageStore() - 语言切换

Profile.vue - 编辑资料

功能清单

  • 头像上传/更换
  • 昵称修改
  • 手机号修改
  • 个人简介修改
  • 保存按钮

API调用PUT /api/user/update


3.4 公共组件(components/)

TabBar.vue - 底部导航栏

作用:固定在底部的标签导航

Tab项

图标 文字 路径
home-o 首页 /
search 分类 /category
chat-o AI问答 /aichat
user-o 我的 /my

特性

  • 使用Vant的 van-tabbar 组件
  • 通过 route prop 实现路由联动
  • 根据当前路由自动高亮

NewsItem.vue - 新闻列表项

作用:可复用的新闻卡片组件

Props

Prop名 类型 说明
news Object 新闻数据对象

显示内容

  • 左侧/上方:封面图(圆角)
  • 右侧/下方:标题(最多2行)、摘要、元信息

Events

事件名 触发条件
click 点击整张卡片

3.5 状态管理(store/)

Store架构图
复制代码
store/
├── index.js              # Store入口,导出所有Store
├── user.js               # 用户状态(登录、Token、用户信息)
├── theme.js              # 主题状态(亮色/暗色)
├── language.js           # 语言状态(中文/英文)
└── modules/              # 子模块
    ├── news.js           # 新闻状态(列表、分类、详情)
    ├── favorite.js       # 收藏状态(列表、收藏状态)
    └── history.js        # 历史状态(列表)
各Store详细说明
user.js - 用户Store

状态(State)

javascript 复制代码
{
  token: '',           // JWT Token
  userInfo: {},        // 用户信息对象
  isLoggedIn: false    // 是否已登录
}

操作(Actions)

方法 说明 参数
login(formData) 登录 {username, password}
register(formData) 注册 {username, password, phone}
logout() 退出登录
getUserInfo() 获取用户信息
updateProfile(data) 更新资料 {nickname, avatar_url, ...}

持久化 (采用 pinia-plugin-persistedstate v4 语法):

  • 用户信息 userInfo、登录态 isLogin 持久化到 sessionStorage(关闭标签页即清除,避免 token 明文常驻 localStorage)
  • Token 不再落盘 :仅存于内存与请求拦截器;刷新页面时由 main.js 从 sessionStorage 回灌,降低 XSS 盗取风险
  • 刷新页面后登录态恢复(会话内)

news.js - 新闻Store

状态(State)

javascript 复制代码
{
  categories: [],       // 分类列表
  newsList: [],         // 当前新闻列表
  currentNews: {},      // 当前查看的新闻详情
  loading: false,       // 加载状态
  total: 0,             // 总数
  page: 1,              // 当前页码
  finished: false       // 是否加载完全部
}

操作(Actions)

方法 说明
fetchCategories() 获取分类列表
fetchNewsList(params) 获取新闻列表(分页)
fetchNewsDetail(id) 获取新闻详情
resetList() 重置列表(切换分类时调用)

favorite.js - 收藏Store

状态(State)

javascript 复制代码
{
  favoriteList: [],     // 收藏列表
  favoriteSet: new Set(),  // 已收藏的ID集合(快速查找)
  loading: false
}

操作(Actions)

方法 说明
fetchFavorites() 获取收藏列表
addFavorite(newsId) 添加收藏
removeFavorite(newsId) 取消收藏
checkFavorite(newsId) 检查是否已收藏
clearFavorites() 清空收藏

theme.js - 主题Store

状态(State)

javascript 复制代码
{
  isDark: false         // 是否暗色模式
}

操作(Actions)

方法 说明
toggleTheme() 切换主题
applyTheme() 应用主题到DOM

实现原理

  1. 切换 <html> 元素的 dark class
  2. CSS变量根据class切换颜色值
  3. 保存偏好到 localStorage

language.js - 语言Store

状态(State)

javascript 复制代码
{
  locale: 'zh-CN'       // 当前语言
}

支持的语言

  • zh-CN - 简体中文
  • en-US - English

3.6 配置文件

config/api.js - API 基础地址配置

作用:从环境变量读取后端基础地址,供请求层复用

配置项

javascript 复制代码
// 开发走 Vite 的 /api 代理;生产/部署通过 VITE_API_BASE 指定真实地址
export const apiConfig = {
  baseURL: import.meta.env.VITE_API_BASE || ''  // 默认空串,配合 Vite 代理转发到后端
}
api/request.js - 统一请求层(新增)

作用:基于 Axios 创建全局请求实例,集中处理 token 注入与错误拦截

拦截器

  • 请求拦截器 :自动从用户状态读取 token 并附加 Authorization: Bearer <token>
  • 响应拦截器 :统一错误处理;遇到 401 自动清除 token 并跳转登录页
  • 各 Store 不再手写 Authorization 头,统一 import request from '../api/request' 调用

3.7 国际化(i18n/)

目录结构
复制代码
i18n/
├── index.js            # i18n实例创建和配置
└── locales/
    ├── zh-CN.js        # 中文语言包
    └── en-US.js        # 英文语言包
翻译键命名规范
javascript 复制代码
{
  common: { ... },      // 通用文案
  tabBar: { ... },      // 底部导航
  home: { ... },        // 首页
  login: { ... },       // 登录
  register: { ... },    // 注册
  my: { ... },          // 我的
  settings: { ... },    // 设置
  // ... 其他页面
}

四、后端文件详解

4.1 入口文件

main.py - FastAPI应用入口

文件路径toutiao_backend/main.py

作用:创建FastAPI应用、注册中间件和路由、启动服务器

核心职责

职责 代码位置
创建FastAPI实例 app = FastAPI(...)
CORS配置 app.add_middleware(CORSMiddleware, ...)
生命周期管理 lifespan 异步上下文管理器
路由注册 app.include_router(...)
启动服务器 uvicorn.run(app, ...)

启动命令

bash 复制代码
# 开发模式(热重载)
python main.py

# 或者使用uvicorn直接启动
uvicorn main:app --reload --host 0.0.0.0 --port 8000

4.2 配置模块(config/)

db_conf.py - 数据库配置

作用:管理MySQL数据库连接

核心组件

组件 类型 说明
engine AsyncEngine 异步数据库引擎(连接池)
AsyncSessionLocal sessionmaker 会话工厂
Base DeclarativeBase ORM模型基类
get_db() 依赖函数 为每个请求提供数据库会话

连接配置(从环境变量读取):

python 复制代码
DB_HOST = localhost
DB_PORT = 3306
DB_USER = root
DB_PASSWORD = 123456
DB_NAME = toutiao_db

连接URL格式

复制代码
mysql+aiomysql://user:password@host:port/database?charset=utf8mb4

cache_conf.py - Redis缓存配置

作用:管理Redis连接

核心组件

组件 类型 说明
redis_client redis.Redis Redis客户端实例
get_redis() 依赖函数 提供Redis连接

配置项

python 复制代码
REDIS_HOST = localhost
REDIS_PORT = 6379
REDIS_PASSWORD =        # 默认无密码
REDIS_DB = 0            # 使用0号数据库

典型用途

  • 缓存热点新闻数据
  • 存储用户会话/Token
  • 实现分布式锁

ai_conf.py - AI配置

作用:管理OpenAI API配置

配置项

python 复制代码
OPENAI_API_KEY = sk-xxx          # API密钥
OPENAI_BASE_URL = https://api.openai.com/v1  # API地址
MODEL_NAME = gpt-3.5-turbo       # 模型名称

安全提醒:生产环境中API Key应从环境变量读取,不要硬编码!


4.3 数据模型(models/)

模型总览
模型文件 对应表 主要字段
users.py user, user_token id, username, hashed_password, nickname, avatar...
news.py category, news id, name/title, content, view_count...
favorite.py favorite id, user_id, news_id
history.py history id, user_id, news_id
ER关系图
复制代码
┌──────────┐       ┌──────────┐       ┌──────────────┐
│  user    │       │ category │       │    news      │
├──────────┤       ├──────────┤       ├──────────────┤
│ PK id    │──┐    │ PK id    │──┐    │ PK id        │
│ username │  │    │ name     │  │    │ FK category_id├──┘
│ password │  │    │ sort_order│  │    │ title        │
│ nickname │  │    └──────────┘  │    │ content      │
│ ...      │  │                 │    │ FK author_id  ├──┐
└──────────┘  │                 │    │ view_count   │  │
              │                 │    └──────────────┘  │
              │                 │                     │
              ▼                 ▼                     ▼
       ┌──────────┐       ┌──────────────┐     ┌──────────────┐
       │user_token│       │  favorite    │     │   history    │
       ├──────────┤       ├──────────────┤     ├──────────────┤
       │ PK id    │       │ PK id        │     │ PK id        │
       │ FK user_id│       │ FK user_id ──┼─────┼─ FK user_id  │
       │ token    │       │ FK news_id ──┘     │ FK news_id ──┘
       │expire_time│       │ created_at   │     │ created_at   │
       └──────────┘       └──────────────┘     └──────────────┘

4.4 数据验证(schemas/)

Schema的作用

Pydantic Schema用于:

  1. 请求数据验证:确保前端提交的数据符合要求
  2. 响应数据序列化:控制返回给前端的数据格式
  3. 自动生成文档:Swagger UI中的请求/响应示例
Schema命名规范
类型 命名规则 示例
请求模型 xxxRequest UserRegisterRequest, LoginRequest
响应模型 xxxResponse UserResponse, LoginResponse
列表响应 xxxListResult NewsListResult
验证装饰器示例
python 复制代码
class UserRegisterRequest(BaseModel):
    username: str = Field(
        ...,                    # 必填
        min_length=3,           # 最小长度
        max_length=50,          # 最大长度
        description="用户名"     # API文档描述
    )
    password: str = Field(..., min_length=6, max_length=100)
    phone: Optional[str] = Field(  # 可选
        None,
        pattern=r"^1[3-9]\d{9}$"  # 正则验证手机号
    )

4.5 数据操作层(crud/)

CRUD的职责

CRUD (Create, Read, Update, Delete) 层封装了所有数据库操作:

文件 操作的表 主要函数
users.py user, user_token create_user, authenticate_user, update_user
news.py news, category get_news_list, create_news, update_news
news_cache.py redis缓存 get_cached_news, set_cached_news
favorite.py favorite add_favorite, remove_favorite, get_favorites
history.py history add_history, get_histories, clear_histories
代码模式示例
python 复制代码
async def get_xxx(db: AsyncSession, id: int) -> Optional[Xxx]:
    """查询单条记录"""
    result = await db.execute(select(Xxx).where(Xxx.id == id))
    return result.scalar_one_or_none()

async def create_xxx(db: AsyncSession, **kwargs) -> Xxx:
    """创建记录"""
    db_obj = Xxx(**kwargs)
    db.add(db_obj)
    await db.commit()
    await db.refresh(db_obj)
    return db_obj

async def update_xxx(db: AsyncSession, id: int, **kwargs) -> Optional[Xxx]:
    """更新记录"""
    obj = await get_xxx(db, id)
    if obj:
        for key, value in kwargs.items():
            setattr(obj, key, value)
        await db.commit()
        await db.refresh(obj)
    return obj

async def delete_xxx(db: AsyncSession, id: int) -> bool:
    """删除记录"""
    obj = await get_xxx(db, id)
    if obj:
        await db.delete(obj)
        await db.commit()
        return True
    return False

4.6 API路由层(routers/)

路由组织方式

每个业务模块一个路由文件,通过 APIRouter 创建:

python 复制代码
router = APIRouter(
    prefix="/api/xxx",     # URL前缀
    tags=["模块名称"],      # Swagger文档分组
)
路由注册到主应用

main.py 中:

python 复制代码
from routers.users import router as user_router
from routers.news import router as news_router
# ...

app.include_router(user_router)
app.include_router(news_router)
# ...
API接口清单

用户模块 (/api/user):

方法 路径 说明 认证
POST /register 用户注册
POST /login 用户登录
GET /info 获取用户信息
PUT /update 更新用户信息
POST /password 修改密码

新闻模块 (/api/news):

方法 路径 说明 认证
GET /categories 获取分类列表
GET /list 获取新闻列表
GET /detail/{id} 获取新闻详情
POST /publish 发布新闻
PUT /update/{id} 更新新闻
DELETE /delete/{id} 删除新闻

收藏模块 (/api/favorite):

方法 路径 说明 认证
POST /add 添加收藏
DELETE /remove 取消收藏
GET /check 检查收藏状态
GET /list 收藏列表
POST /clear 清空收藏

历史模块 (/api/history):

方法 路径 说明 认证
POST /add 添加历史
GET /list 历史列表
POST /clear 清空历史

AI模块 (/api/aichat):

方法 路径 说明 认证
POST /chat AI问答

4.7 工具模块(utils/)

auth.py - JWT认证

核心函数

函数 说明
create_access_token(data) 生成JWT Token
get_current_user() 依赖注入,获取当前登录用户

使用方式

python 复制代码
@router.get("/protected")
async def protected_route(current_user = Depends(get_current_user)):
    # current_user 就是当前登录的User对象
    return {"user_id": current_user.id}

security.py - 密码加密

核心函数

函数 说明
hash_password(password) 明文→哈希
verify_password(plain, hashed) 验证密码

算法:bcrypt(自带盐值,每次加密结果不同)


response.py - 统一响应格式

标准响应结构

json 复制代码
{
  "code": 0,           // 0=成功,其他=失败
  "message": "success", // 提示信息
  "data": {}            // 业务数据
}

exception.py - 自定义异常
异常类 HTTP状态码 说明
UnauthorizedException 401 未认证
ForbiddenException 403 无权限
NotFoundException 404 资源不存在
BusinessException 400 业务逻辑错误

五、数据流图

5.1 用户登录流程

复制代码
┌────────┐    ┌────────┐    ┌────────┐    ┌────────┐    ┌────────┐
│ 用户   │───▶│ Login  │───▶│ user   │───▶│ Axios  │───▶│ FastAPI│
│ 输入   │    │ Vue    │    │ Store  │    │        │    │ Router │
└────────┘    └────────┘    └────────┘    └────────┘    └───┬────┘
                                                   │
                                                   ▼
                                           ┌───────────────┐
                                           │ auth.py        │
                                           │ 验证用户名密码 │
                                           └───────┬───────┘
                                                   │
                                                   ▼
                                           ┌───────────────┐
                                           │ crud/users.py  │
                                           │ 查询user表     │
                                           │ bcrypt验密     │
                                           └───────┬───────┘
                                                   │
                                                   ▼
                                           ┌───────────────┐
                                           │ 生成JWT Token  │
                                           │ 返回用户+Token │
                                           └───────┬───────┘
                                                   │
                                                   ▼
                                              原路返回→会话内保存
                                              sessionStorage

5.2 新闻浏览流程

复制代码
┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐
│ Home   │──▶│ news   │──▶│ Axios  │──▶│ /api/  │──▶│ news   │
│ Vue    │   │ Store  │   │        │   │ news/  │   │ routes│
└────────┘   └────────┘   └────────┘   │ list   │   └───┬───┘
                                     └────┬───┘       │
                                          │           ▼
                                     ┌────▼─────┐ ┌──────────┐
                                     │ Vite Proxy│ │crud/news │
                                     │ 转发请求  │ │ 分页查询 │
                                     └────┬─────┘ └────┬─────┘
                                          │          │
                                          ▼          ▼
                                     ┌──────────────────────┐
                                     │      MySQL           │
                                     │  SELECT * FROM news  │
                                     │  WHERE is_published  │
                                     │  ORDER BY ... LIMIT  │
                                     └──────────┬───────────┘
                                                │
                                                ▼
                                           JSON响应
                                                │
                                                ▼
                                         更新newsList
                                                │
                                                ▼
                                          视图重新渲染

六、开发规范

6.1 命名规范

类型 规范 示例
文件名 小写+下划线 user_routes.py, NewsItem.vue
组件名 大驼峰 NewsItem, TabBar
变量/函数 小驼峰 userInfo, fetchData
常量 大蛇形 MAX_PAGE_SIZE, API_BASE_URL
数据库表 小写+下划线 user_token, news_detail
API路径 小写+连字符 /api/user-info, /news-list
CSS类 连字符 .news-item, .login-form

6.2 目录组织原则

复制代码
1. 按功能分层(router → schema → crud → model)
2. 同类文件放同一目录
3. 公共组件放 components/
4. 页面组件放 views/
5. 配置文件放 config/
6. 工具函数放 utils/

6.3 代码风格

Python (PEP 8)

  • 缩进:4空格
  • 行宽:最大120字符
  • 导入顺序:标准库 → 第三方 → 本地
  • 字符串:使用f-string格式化

JavaScript (Standard)

  • 缩进:2空格
  • 使用单引号(模板字符串除外)
  • 末尾不加分号(可选)
  • 使用const/let,禁止var

6.4 Git提交规范

复制代码
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式调整
refactor: 重构
test: 测试相关
chore: 构建/工具链

示例

复制代码
feat: 实现用户收藏功能
fix: 修复下拉刷新不触发的问题
docs: 更新API接口文档
style: 调整Home页样式

七、模块依赖关系

7.1 前端依赖图

复制代码
App.vue
├── router/index.js
│   └── views/*
│       ├── Home.vue ──────────┬── components/NewsItem.vue
│       ├── NewsDetail.vue ────┤
│       ├── Favorite.vue ──────┤
│       └── History.vue ───────┘
│
├── store/
│   ├── user.js ────────────── api/request.js (Axios 实例 + 拦截器)
│   ├── news.js
│   ├── favorite.js
│   ├── history.js
│   ├── theme.js
│   └── language.js
│
├── components/
│   ├── TabBar.vue
│   └── NewsItem.vue
│
├── api/request.js ──────────── axios (带拦截器)
├── config/api.js ───────────── 后端地址常量(VITE_API_BASE)
└── i18n/
    └── locales/*

7.2 后端依赖图

复制代码
main.py
├── config/
│   ├── db_conf.py ──────────── sqlalchemy, aiomysql
│   ├── cache_conf.py ───────── redis
│   └── ai_conf.py
│
├── routers/
│   ├── users.py ───────────── schemas/users.py
│   │    └── crud/users.py ─── models/users.py
│   │         └── utils/auth.py, security.py
│   │
│   ├── news.py ────────────── schemas/news.py
│   │    └── crud/news.py ──── models/news.py
│   │
│   ├── favorite.py ──── schemas/favorite.py
│   │    └── crud/favorite.py ── models/favorite.py
│   │
│   ├── history.py ───── schemas/histroy.py
│   │    └── crud/history.py ── models/history.py
│   │
│   └── aichat.py ──────── schemas/aichat.py
│         └── config/ai_conf.py
│
└── utils/
    ├── auth.py ────────────── python-jose
    ├── security.py ────────── passlib
    ├── response.py
    ├── exception.py
    └── exception_handlers.py

八、常见问题FAQ

Q1:为什么要分这么多文件夹?

A:分层架构的好处:

  • 职责清晰:每个文件只做一件事
  • 易于维护:改某个功能只需找到对应文件
  • 团队协作:多人开发互不冲突
  • 方便测试:可以单独测试某一层

Q2:前端为什么用Pinia而不是Vuex?

A:Pinia是Vue官方推荐的新一代状态管理:

  • TypeScript支持更好
  • API更简洁(不再需要mutations)
  • 更好的DevTools支持
  • 更小的打包体积

Q3:后端为什么用async/await?

A:异步编程的优势:

  • 高并发处理能力(不阻塞)
  • 特别适合I/O密集型任务(数据库查询、API调用)
  • FastAPI原生支持异步

Q4:为什么要用Redis?

A:Redis作为缓存的用途:

  • 减少MySQL查询压力
  • 热点数据快速读取(内存级速度)
  • 实现会话管理、排行榜等功能

文档版本 :v1.0

更新日期 :2026年7月

适用项目:toutiao_heima 新闻头条全栈项目

相关推荐
满栀5851 小时前
vue动态路由效果
前端·javascript·vue.js·前端框架·vue
物质波波波2 小时前
WS-RPE:面向边缘物理AI实时特征值计算的硬件工作窃取调度器与冗余PE激活架构
人工智能·fpga开发·架构·系统架构·硬件架构
心运软件2 小时前
SpringBoot+ Vue校园社团管理平台的完整架构设计
vue.js·后端
敲代码的玉米C3 小时前
测试一直在写你的真实数据根
前端·人工智能·架构
烟漠河洛3 小时前
拆解跨平台统一发货架构及亚马逊MCF降本三成技术落地
架构
真上帝的左手3 小时前
10. 软件设计&架构-Spring Security 7 整合CAS SSO 单点登录
java·spring·架构·sso
jjw_zyfx3 小时前
css vue vite实现闪烁的呼吸效果
javascript·css·vue.js
品牌测评3 小时前
大模型推理算力平台推荐分享|六家平台计费与架构拆解
大数据·人工智能·架构
微三云 - 廖会灵 (私域系统开发)3 小时前
智慧社区运营破局:“消费返物业费” 模式的数字化架构与落地实践
大数据·架构
浅水壁虎4 小时前
vue基础(第四章 Pinia)
前端·javascript·vue.js