一、项目简介
智能城市交通管理系统面向城市交通指挥中心、交警大队和智慧园区运维人员,提供道路监测点管理、交通事件上报、事件处置、信号灯配时方案维护和交通运行驾驶舱统计能力。项目不是单一算法演示,而是一个包含后端 API、SQLite 数据库、用户认证鉴权、Vue 3 前端页面和部署说明的 Python 全栈项目。
本项目适合作为课程设计、毕业设计原型或 FastAPI + Vue 3 入门案例。系统核心目标包括:
- 用户可以注册、登录并获取访问令牌。
- 业务接口必须经过 JWT 鉴权。
- 登录后可以维护道路监测点,记录车流量、平均速度和拥堵等级。
- 登录后可以上报交通事故、拥堵、施工等事件,并更新事件状态。
- 登录后可以维护路口信号配时方案。
- 驾驶舱自动汇总监测点数量、事件数量、待处理事件、平均速度和拥堵指数。
二、技术栈
| 层级 | 技术 |
|---|---|
| 后端框架 | FastAPI |
| 数据库 | SQLite |
| ORM | SQLAlchemy |
| 数据校验 | Pydantic |
| 认证鉴权 | JWT Token、passlib bcrypt 密码哈希 |
| 前端框架 | Vue 3 |
| 构建工具 | Vite |
| 接口通信 | Fetch API 封装 |
| 项目运行 | Uvicorn + npm run dev |
前端主技术栈为 Vue 3 + Vite,后端主技术栈为 FastAPI + SQLite。
三、系统架构
系统采用前后端分离架构:
text
浏览器 Vue 3 页面
│
│ HTTP/JSON + Authorization Bearer Token
▼
FastAPI REST API
│
│ SQLAlchemy ORM
▼
SQLite traffic.db
后端项目结构如下:
text
backend/app/
├── main.py # FastAPI 应用、路由、鉴权依赖
├── database.py # SQLite 连接与 Session 管理
├── models.py # SQLAlchemy 数据模型
├── schemas.py # Pydantic 请求/响应结构
└── crud.py # 用户、监测点、事件、信号方案业务逻辑
前端项目结构如下:
text
frontend/src/
├── main.js # Vue 应用入口
├── App.vue # 登录注册和业务页面
├── api.js # API 请求封装与 token 处理
└── style.css # 页面样式
四、功能模块
1. 用户认证模块
- 注册:用户名、邮箱、密码。
- 登录:验证密码哈希,返回 JWT token。
- 当前用户:根据 token 获取用户信息。
- 退出登录:前端清除本地 token。
2. 交通监测点模块
维护道路监测点数据,包括名称、位置、车流量、平均速度、拥堵等级和更新时间。该模块可模拟来自摄像头、地磁线圈、雷达等设备的聚合数据。
3. 交通事件模块
支持上报交通事件,例如车辆追尾、道路施工、拥堵、管制等。事件字段包括标题、位置、严重程度、状态和描述。用户可将事件状态更新为"已处理"。
4. 信号配时方案模块
维护路口信号灯方案,包括路口名称、早高峰绿灯秒数、晚高峰绿灯秒数和调度策略说明。
5. 驾驶舱统计模块
统计监测点数量、事件数量、待处理事件数量、平均速度和拥堵指数,为交通调度人员提供态势概览。
五、数据库/数据模型设计
系统使用 SQLite 数据库,运行后自动生成 traffic.db。主要表如下:
users 用户表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | Integer | 主键 |
| username | String | 用户名,唯一 |
| String | 邮箱,唯一 | |
| hashed_password | String | 哈希后的密码 |
| created_at | DateTime | 创建时间 |
road_sensors 道路监测点表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | Integer | 主键 |
| name | String | 监测点名称 |
| location | String | 位置 |
| traffic_flow | Integer | 车流量 |
| avg_speed | Float | 平均速度 |
| congestion_level | String | 拥堵等级 |
| updated_at | DateTime | 更新时间 |
incidents 交通事件表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | Integer | 主键 |
| title | String | 事件标题 |
| location | String | 发生位置 |
| severity | String | 严重程度 |
| status | String | 状态 |
| description | Text | 描述 |
| owner_id | Integer | 上报用户 |
| created_at | DateTime | 创建时间 |
signal_plans 信号方案表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | Integer | 主键 |
| intersection | String | 路口 |
| morning_green | Integer | 早高峰绿灯秒数 |
| evening_green | Integer | 晚高峰绿灯秒数 |
| strategy | String | 策略说明 |
六、后端接口设计
| 方法 | 路径 | 是否鉴权 | 说明 |
|---|---|---|---|
| GET | /api/health |
否 | 健康检查 |
| POST | /api/auth/register |
否 | 用户注册 |
| POST | /api/auth/login |
否 | 用户登录 |
| GET | /api/auth/me |
是 | 当前用户信息 |
| GET | /api/dashboard |
是 | 驾驶舱统计 |
| GET | /api/sensors |
是 | 监测点列表 |
| POST | /api/sensors |
是 | 新增监测点 |
| GET | /api/incidents |
是 | 事件列表 |
| POST | /api/incidents |
是 | 上报事件 |
| PATCH | /api/incidents/{incident_id} |
是 | 更新事件状态 |
| GET | /api/signal-plans |
是 | 信号方案列表 |
| POST | /api/signal-plans |
是 | 新增信号方案 |
鉴权方式:登录成功后前端保存 access_token,后续请求加入请求头:
text
Authorization: Bearer <token>
七、前端页面设计
前端使用 Vue 3 单文件组件实现,页面分为两个状态:
- 未登录状态:展示登录卡片与注册卡片。
- 已登录状态:展示驾驶舱统计、道路监测点表单、事件上报表单、信号方案表单和三类业务列表。
前端关键交互:
- 注册成功后提示用户登录。
- 登录成功后保存 token 并加载全部业务数据。
- 页面刷新时通过
/api/auth/me恢复登录状态。 - 退出登录时清除 token。
- 新增或更新业务数据后重新刷新驾驶舱统计。
八、核心代码讲解
1. SQLite 数据库连接
backend/app/database.py 中通过 SQLAlchemy 创建 SQLite 连接:
python
engine = create_engine(
"sqlite:///./traffic.db", connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
get_db() 使用生成器模式,为每个请求创建数据库会话并在结束后关闭。
2. 密码哈希与 JWT
backend/app/crud.py 中使用 passlib 对密码进行 bcrypt 哈希,避免明文存储密码:
python
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def get_password_hash(password: str) -> str:
return pwd_context.hash(password)
登录成功后创建 JWT:
python
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
to_encode = data.copy()
expire = datetime.now(timezone.utc) + (expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES))
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
3. FastAPI 鉴权依赖
backend/app/main.py 中通过 OAuth2PasswordBearer 读取 Bearer Token,再解码获取用户:
python
def get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)):
username = crud.decode_token(token)
if not username:
raise HTTPException(status_code=401, detail="登录已失效")
user = crud.get_user_by_username(db, username)
if not user:
raise HTTPException(status_code=401, detail="用户不存在")
return user
业务接口添加 current_user: models.User = Depends(get_current_user) 后即可实现认证保护。
4. 拥堵指数计算
驾驶舱通过监测点的拥堵等级计算拥堵指数:
python
level_score = {"畅通": 0.15, "缓行": 0.45, "拥堵": 0.75, "严重拥堵": 1.0}
congestion_index = round(
sum(level_score.get(s.congestion_level, 0.3) for s in sensors) / len(sensors), 2
) if sensors else 0
5. 前端 API 封装
frontend/src/api.js 统一处理接口地址、JSON 请求头、Token 和错误提示:
javascript
export async function request(path, options = {}) {
const headers = { 'Content-Type': 'application/json', ...(options.headers || {}) }
const token = getToken()
if (token) headers.Authorization = `Bearer ${token}`
const response = await fetch(`${API_BASE}${path}`, { ...options, headers })
const data = await response.json().catch(() => ({}))
if (!response.ok) throw new Error(data.detail || '请求失败')
return data
}
九、部署与运行步骤
1. 启动后端
bash
cd project/backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
后端默认地址:http://127.0.0.1:8000。
2. 启动 Vue 3 前端
bash
cd project/frontend
npm install
npm run dev
前端默认地址:http://127.0.0.1:5173。
3. 初始化使用
- 打开前端页面。
- 注册账号,例如
admin / admin@example.com / 123456。 - 登录后新增监测点,例如"人民路监测点"。
- 上报交通事件,例如"车辆追尾"。
- 新增信号配时方案,例如"中心广场路口"。
- 在驾驶舱查看统计数据变化。
十、项目总结
本项目完成了一个主题明确、可运行的 Python 全栈系统:后端基于 FastAPI 提供 REST API,SQLite 负责轻量级数据持久化,SQLAlchemy 管理数据模型,JWT 和 bcrypt 实现安全认证,前端基于 Vue 3 + Vite 构建交互式管理页面。通过该项目可以学习从需求分析、数据库设计、接口设计、前端状态管理到部署运行的一整套全栈开发流程。
智能城市交通管理场景还可以继续扩展:接入地图 SDK、WebSocket 实时推送、视频 AI 事件识别、拥堵预测模型、多角色权限、告警规则和大屏可视化等能力。当前版本保留了清晰的模块边界,便于后续迭代。