我给你一套生产级、可直接落地的「前端 + FastAPI 全栈项目完整目录结构」,兼顾「工程化规范、易维护性、前端开发习惯」,你可以直接按这个结构建项目,后续对接 AI 流式接口、部署上线都不用改结构。
一、项目总目录(前端+后端一体化)
fullstack-ai-project/ # 项目根目录
├── frontend/ # Vue3 前端项目(基于Vite)
├── backend/ # FastAPI 后端项目
├── docker-compose.yml # 一键启动配置(前端+后端+数据库)
├── .gitignore # 全局忽略文件
└── README.md # 项目说明(部署/启动步骤)
二、后端(FastAPI)目录结构(重点)
贴合 Python 工程化规范,同时适配前端「模块化」思维:
backend/
├── app/ # 核心应用代码(前端理解:src目录)
│ ├── __init__.py # 包初始化文件(空文件即可)
│ ├── main.py # FastAPI 入口文件(启动、跨域、路由注册)
│ ├── api/ # 接口路由(前端理解:router目录)
│ │ ├── __init__.py
│ │ ├── v1/ # 接口版本管理(推荐v1,方便后续迭代)
│ │ │ ├── __init__.py
│ │ │ ├── auth.py # 登录/鉴权接口
│ │ │ ├── user.py # 用户管理接口
│ │ │ ├── upload.py # 文件上传接口
│ │ │ └── ai.py # AI 流式接口
│ ├── core/ # 核心配置(前端理解:config目录)
│ │ │ ├── __init__.py
│ │ │ ├── config.py # 全局配置(数据库、JWT、AI API Key)
│ │ │ └── dependencies.py # 依赖注入(数据库会话、鉴权)
│ ├── models/ # 数据库模型(前端理解:schema/model)
│ │ │ ├── __init__.py
│ │ │ └── user.py # 用户表模型
│ ├── schemas/ # 数据校验模型(前端理解:TS接口)
│ │ │ ├── __init__.py
│ │ │ ├── user.py # 用户相关请求/响应模型
│ │ │ └── ai.py # AI 接口请求/响应模型
│ ├── crud/ # 数据库操作(前端理解:api/request)
│ │ │ ├── __init__.py
│ │ │ └── user.py # 用户CURD
│ ├── utils/ # 工具函数(前端理解:utils)
│ │ │ ├── __init__.py
│ │ │ ├── jwt.py # JWT 工具
│ │ │ ├── password.py # 密码加密
│ │ │ └── ai.py # AI API 调用工具
│ └── static/ # 静态文件(上传的图片/文件)
│ └── uploads/
├── .dockerignore # Docker 忽略文件
├── .env # 环境变量(本地开发,不上传git)
├── .env.example # 环境变量示例(上传git,标注必填项)
├── Dockerfile # 后端Dockerfile
├── requirements.txt # 依赖清单
└── uvicorn_config.py # uvicorn 启动配置(可选)
关键文件示例(保证可运行)
- backend/app/core/config.py(全局配置,从环境变量读取)
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
# 数据库配置
DATABASE_URL: str = "mysql+pymysql://root:123456@mysql:3306/fastapi_demo"
# JWT配置
SECRET_KEY: str = "your-secret-key-123456"
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
# AI API配置
DOUBAO_API_KEY: str = ""
# 跨域配置
CORS_ORIGINS: list = ["*"]
# 加载.env文件
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
# 全局配置实例
settings = Settings()
- backend/app/main.py(入口文件,注册路由)
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from app.api.v1 import auth, user, upload, ai
from app.core.config import settings
# 初始化FastAPI
app = FastAPI(
title="前端+FastAPI全栈项目",
description="包含用户管理、文件上传、AI流式接口",
version="1.0.0"
)
# 跨域配置
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 注册路由(前端理解:app.use('/api/v1', router))
app.include_router(auth.router, prefix="/api/v1/auth", tags=["认证"])
app.include_router(user.router, prefix="/api/v1/user", tags=["用户"])
app.include_router(upload.router, prefix="/api/v1/upload", tags=["文件上传"])
app.include_router(ai.router, prefix="/api/v1/ai", tags=["AI接口"])
# 静态文件服务(上传文件访问)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
# 根路由
@app.get("/")
def root():
return {"message": "后端服务已启动,访问 /docs 查看接口文档"}
- backend/app/api/v1/auth.py(路由示例,拆分模块化)
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.core.dependencies import get_db
from app.schemas.user import UserLogin
from app.crud.user import get_user_by_username
from app.utils.jwt import create_access_token
from app.utils.password import verify_password
router = APIRouter()
@router.post("/login")
def login(user: UserLogin, db: Session = Depends(get_db)):
# 查用户
db_user = get_user_by_username(db, username=user.username)
if not db_user:
return {"code": 401, "msg": "用户名不存在", "data": None}
# 验证密码
if not verify_password(user.password, db_user.password):
return {"code": 401, "msg": "密码错误", "data": None}
# 生成Token
access_token = create_access_token(data={"sub": db_user.username})
return {"code": 200, "msg": "登录成功", "data": {"token": access_token}}
三、前端(Vue3)目录结构(Vite+Pinia+Axios)
贴合前端工程化规范,适配全栈联调场景:
frontend/
├── public/ # 静态资源(不打包)
├── src/
│ ├── api/ # 接口请求(和后端路由对应)
│ │ ├── index.js # Axios 封装
│ │ ├── auth.js # 认证相关接口
│ │ ├── user.js # 用户相关接口
│ │ ├── upload.js # 文件上传接口
│ │ └── ai.js # AI 流式接口
│ ├── assets/ # 静态资源(图片/样式)
│ ├── components/ # 通用组件
│ │ ├── common/ # 公共组件(按钮/输入框)
│ │ ├── auth/ # 认证组件(登录/注册)
│ │ └── ai/ # AI 聊天组件
│ ├── layouts/ # 布局组件
│ ├── pages/ # 页面组件
│ │ ├── Login.vue # 登录页
│ │ ├── User.vue # 用户管理页
│ │ ├── Upload.vue # 文件上传页
│ │ └── AIChat.vue # AI 聊天页
│ ├── pinia/ # 状态管理
│ │ ├── index.js
│ │ └── userStore.js # 用户状态
│ ├── router/ # 路由
│ │ └── index.js
│ ├── utils/ # 工具函数
│ │ ├── request.js # Axios 拦截器(Token、统一响应)
│ │ └── sse.js # SSE 流式处理工具
│ ├── App.vue
│ └── main.js
├── .dockerignore # Docker 忽略文件
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
├── Dockerfile # 前端Dockerfile
├── index.html
├── package.json
└── vite.config.js # Vite 配置(代理、端口)
关键文件示例
- frontend/src/utils/request.js(Axios 封装,对接后端统一响应)
import axios from 'axios'
import { useUserStore } from '@/pinia/userStore'
// 创建Axios实例
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000/api/v1',
timeout: 10000
})
// 请求拦截器(添加Token)
service.interceptors.request.use(
(config) => {
const userStore = useUserStore()
if (userStore.token) {
config.headers.Authorization = `Bearer ${userStore.token}`
}
return config
},
(error) => Promise.reject(error)
)
// 响应拦截器(统一处理响应)
service.interceptors.response.use(
(response) => {
const res = response.data
// 统一处理code
if (res.code !== 200) {
// 登录失效
if (res.code === 401) {
const userStore = useUserStore()
userStore.logout()
window.location.href = '/login'
}
// 提示错误
ElMessage.error(res.msg || '请求失败')
return Promise.reject(res)
}
return res
},
(error) => {
ElMessage.error(error.message || '网络错误')
return Promise.reject(error)
}
)
export default service
- frontend/vite.config.js(配置代理,解决开发跨域)
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
},
server: {
port: 8080,
proxy: {
// 代理后端接口,避免开发跨域
'/api': {
target: 'http://localhost:8000',
changeOrigin: true
}
}
}
})
四、全局配置文件
- docker-compose.yml(项目根目录,一键启动)
version: '3.8'
services:
# 前端服务
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "8080:80"
depends_on:
- backend
restart: always
networks:
- fullstack-network
# 后端服务
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8000:8000"
depends_on:
- mysql
environment:
- DATABASE_URL=mysql+pymysql://root:123456@mysql:3306/fastapi_demo
- SECRET_KEY=your-secret-key-123456
- CORS_ORIGINS=["*"]
restart: always
networks:
- fullstack-network
# 数据库服务
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=fastapi_demo
volumes:
- mysql-data:/var/lib/mysql
restart: always
networks:
- fullstack-network
# 网络配置
networks:
fullstack-network:
driver: bridge
# 数据卷(持久化数据库)
volumes:
mysql-data:
- .gitignore(全局忽略)
# 后端
backend/__pycache__/
backend/.env
backend/app/static/uploads/
backend/venv/
# 前端
frontend/node_modules/
frontend/dist/
frontend/.env
frontend/.vscode/
frontend/package-lock.json
# Docker
*.dockerignore
.docker-compose.override.yml
# 通用
.DS_Store
*.log
.vscode/
.idea/
五、核心优势(适配前端开发习惯)
- 模块化拆分:后端按「接口/配置/模型/工具」拆分,和前端「api/config/components/utils」一一对应,易理解、易维护;
-
环境隔离:前端/后端都有
.env环境变量,开发/生产环境配置分离; - Docker 友好:每个模块都有独立的 Dockerfile,docker-compose 一键启动所有服务;
-
可扩展性:新增 AI 功能只需在
backend/app/api/v1/ai.py和frontend/src/api/ai.js中添加代码,不改动核心结构; - 工程化规范:符合 Python/FastAPI 官方规范 + 前端 Vue 生态规范,面试时展示这个结构会加分。
总结
- 目录核心逻辑:「前端/后端」目录分离,内部按「功能模块」拆分,前后端路由一一对应,降低联调成本;
- 落地性:直接按这个结构建文件夹,把之前写的 FastAPI 接口、Vue3 组件、AI 流式代码填充进去即可;
- 扩展性:后续加 Redis、RAG 知识库、CI/CD 都能在这个结构上扩展,不用重构。
如果需要我补充某个具体文件的完整代码(比如 backend/app/crud/user.py、frontend/src/api/ai.js),或者提供「项目初始化脚本」,直接说就行。