大家好,我是Java1234_小锋老师,分享一套锋哥原创的基于Python的微信小程序网约车(打车,在线叫车,移动出行)系统(FastAPI+Vue3) 。

项目介绍
随着移动互联网与共享经济的深入发展,网约车已成为城市出行的重要方式。传统打车模式存在供需匹配效率低、信息不对称、服务质量难监管等问题,而基于微信小程序的轻量级应用能够降低用户使用门槛,便于快速触达乘客与司机两端。本文围绕"微信小程序网约车系统"这一课题,采用前后端分离架构,设计并实现了一套覆盖乘客出行、司机接单与后台运营管理的完整业务系统。
系统后端基于Python语言与FastAPI框架构建RESTful接口服务,结合SQLAlchemy完成对象关系映射,使用MySQL数据库持久化业务数据;管理端采用Vue3、Vite、Element Plus与ECharts实现可视化运营后台;乘客端与司机端分别开发微信小程序,通过用户名密码完成注册登录,并支持个人资料、头像与密码修改。系统实现了叫车下单、价格预估、司机抢单、行程状态流转、余额支付、评价投诉、公告发布、司机审核及数据统计等核心功能,并利用WebSocket实现订单状态的实时推送,提升了调度响应效率。
数据库设计以db_taxi为库名,表名统一以t_开头,围绕乘客、司机、车辆、车型、订单、评价、投诉、公告、余额流水与司机位置等实体展开。论文给出了实体属性图、实体关系图、系统功能结构图与关键业务时序图,详细描述了各数据表字段结构,并结合核心代码说明了主要功能的实现过程。测试结果表明,系统功能完整、流程闭环,能够满足本科毕业设计对工程实践与文档规范的要求,也为同类出行类应用的二次开发提供了可复用的技术路径。
源码下载
链接: https://pan.baidu.com/s/1O65qrmtFmZbM11ntbo-mNw?pwd=1234
提取码: 1234
系统展示









核心代码
python
"""WebSocket 连接管理"""
import json
from typing import Any
from fastapi import WebSocket
class DispatchWebSocketManager:
"""派单 WebSocket 连接池"""
driver_sessions: dict[int, WebSocket] = {}
passenger_sessions: dict[int, WebSocket] = {}
@classmethod
async def connect(cls, user_type: str, user_id: int, websocket: WebSocket) -> None:
"""建立连接"""
await websocket.accept()
if user_type == "driver":
cls.driver_sessions[user_id] = websocket
elif user_type == "passenger":
cls.passenger_sessions[user_id] = websocket
@classmethod
def disconnect(cls, user_type: str, user_id: int) -> None:
"""断开连接"""
if user_type == "driver":
cls.driver_sessions.pop(user_id, None)
elif user_type == "passenger":
cls.passenger_sessions.pop(user_id, None)
@classmethod
async def send_message(cls, websocket: WebSocket, message: Any) -> None:
"""发送文本消息"""
await websocket.send_text(json.dumps(message, ensure_ascii=False, default=str))
@classmethod
async def broadcast_to_drivers(cls, message: Any) -> None:
"""广播消息给所有在线司机"""
for websocket in list(cls.driver_sessions.values()):
try:
await cls.send_message(websocket, message)
except Exception:
pass
@classmethod
async def send_to_passenger(cls, passenger_id: int, message: Any) -> None:
"""发送消息给指定乘客"""
websocket = cls.passenger_sessions.get(passenger_id)
if websocket:
try:
await cls.send_message(websocket, message)
except Exception:
pass
@classmethod
async def send_to_driver(cls, driver_id: int, message: Any) -> None:
"""发送消息给指定司机"""
websocket = cls.driver_sessions.get(driver_id)
if websocket:
try:
await cls.send_message(websocket, message)
except Exception:
pass
python
<template>
<div class="page-container">
<div class="table-card">
<div class="search-bar">
<el-select v-model="userType" placeholder="用户类型" clearable style="width: 140px" @change="loadData">
<el-option label="乘客" :value="1" /><el-option label="司机" :value="2" />
</el-select>
</div>
<el-table :data="tableData" stripe border>
<el-table-column prop="userId" label="用户ID" min-width="80" />
<el-table-column prop="username" label="用户名" min-width="100" />
<el-table-column label="用户类型" min-width="90">
<template #default="{ row }">{{ row.userType === 1 ? '乘客' : '司机' }}</template>
</el-table-column>
<el-table-column label="类型" min-width="80">
<template #default="{ row }">{{ recordTypeMap[row.type] }}</template>
</el-table-column>
<el-table-column prop="amount" label="金额(元)" min-width="100" />
<el-table-column prop="balanceAfter" label="变动后余额" min-width="110" />
<el-table-column prop="orderId" label="关联订单" min-width="90" />
<el-table-column prop="remark" label="备注" min-width="140" />
<el-table-column label="时间" min-width="160">
<template #default="{ row }">{{ formatDateTime(row.createTime) }}</template>
</el-table-column>
</el-table>
<el-pagination style="margin-top: 16px; justify-content: flex-end" v-model:current-page="current" :total="total" layout="total, prev, pager, next" @current-change="loadData" />
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import request from '@/utils/request'
import { formatDateTime, recordTypeMap } from '@/utils/date'
const tableData = ref([])
const userType = ref(null)
const current = ref(1)
const total = ref(0)
async function loadData() {
const res = await request.get('/admin/balanceRecord/page', { params: { current: current.value, size: 10, userType: userType.value } })
tableData.value = res.data.records
total.value = res.data.total
}
onMounted(() => loadData())
</script>