前阵子把一直在维护的 v810b 版本机票预定座位管理系统重新过了一遍,顺手解决了好几个当时遗留的问题。这个项目前端用的 Vue,后端用的 Node.js,核心业务是航空公司官网里最常见的流程:用户查询航班、选择舱位、在座位图上挑座位、提交订单,管理员在后台维护航班和座位数据。整套系统说大不大,但把机票库存、座位锁定、订单状态这些逻辑串起来之后,还是很考验工程能力的。如果你刚开始接触全栈项目、想拿真实业务练手,或者正在做毕业设计,这篇文章大概能帮你少走不少弯路。
1. 这类机票预订系统到底在解决什么问题
1.1 业务角色和核心流程
很多人一听到“机票预定座位管理系统”,第一反应就是“这不就是个 CRUD 吗”。如果只是把航班、订单做增删改查,那确实简单,但真正把业务跑通之后会发现,核心难点在于状态的一致性和并发控制。
系统里主要有两类角色。普通用户要完成的是三个动作:按出发城市、到达城市、日期查航班;在航班详情里选择舱位和座位;提交订单并完成支付。管理员要维护的是航班计划、飞机机型、舱位价格、座位库存,还要处理订单取消和退票。表面上看角色不多,但每个动作背后都牵扯到一张或多张表的状态变化。
举个例子,用户搜索航班时看到的“剩余座位数”,并不是存一个字段就能解决的。因为同一个航班下,不同舱位的座位数不同,不同日期、不同飞机的座位布局也不同。如果管理端改了一个机型的座位布局,那所有关联航班的可售座位数都要跟着变。这类联动逻辑如果不用数据表去建模,而是硬编码在业务代码里,后期维护成本会非常高。
所以我在设计时把流程拆成了几条线:航班查询链路解决“有哪些航班能买”,座位选择链路解决“这个航班还有哪些座位能选”,订单链路解决“选好的座位怎么锁住并完成支付”。这三条链路各自独立,又在订单提交那一刻交会,交会点就是整个系统的核心。
1.2 为什么 Node.js 加 Vue 的组合适合这个项目
技术选型的时候,我考虑过很多组合。后端可以用 Java Spring Boot,也可以用 Python Django,但最后选了 Node.js 加 Express,核心原因是这个系统的业务特征属于典型的 I/O 密集型场景:用户不断发起查询、提交订单、刷新座位状态,真正消耗 CPU 计算的逻辑并不多。Node.js 基于事件循环和非阻塞 I/O,在这种高并发读多写少的场景下,用很小的资源就能扛住大量连接。
前端选 Vue 也有很实际的考虑。机票预订页面有大量表单交互和数据联动,比如选择日期后要重新拉取航班列表,选择舱位后座位图要刷新,选择座位后底部价格汇总要变化。Vue 的响应式系统和 computed 计算属性特别适合处理这种“一个数据变化带动一片界面更新”的场景,写起来比手动操作 DOM 或者用 jQuery 维护状态要省心得多。
还有一个原因是前后端分离带来的部署灵活性。前端打包成纯静态文件,可以扔到 Nginx 或者 CDN 上;后端跑 Node 服务,接口独立升级。这个项目里我甚至在同一台服务器上同时部署了前端静态资源和后端 API,通过反向代理把 /api 转发给 Node 服务,其他路径都交给前端静态文件。这种架构对个人项目和中小团队来说,性价比很高。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 项目骨架搭建:Node.js、npm 与 Vue 工程化的第一道坎
2.1 版本选型:为什么推荐 Node.js 20 加 Vue 3 加 Vite
v810b 版本里,前端我用的 Vue 3.4 加 Vite 5,后端用的 Node.js 20 LTS 加 Express 4。这里有一个很现实的建议:如果你是照着教程从零起步,Node.js 一定要装 LTS 版本,不要追最新版。LTS 版本意味着生态兼容性稳定,很多原生模块在 LTS 版本上测试最充分。Node.js 20 对 ES Modules 的支持已经很完善,Express 4 的中间件生态也完全兼容。
前端用 Vite 而不是 Vue CLI,是因为 Vite 在开发环境下启动速度确实快很多。Vue CLI 基于 Webpack,冷启动一个中型项目可能要十几秒,Vite 借助原生 ES Module,基本一两秒就能起来。这种体感差异在频繁调试时非常明显。
配套的 UI 组件库我用的 Ant Design Vue。它的表格、日期选择器、表单校验组件都比较完整,尤其是日期范围选择和时间选择,做航班查询表单时几乎不用额外封装。如果你不喜欢这个风格,Element Plus 也行,但尽量从头到尾只用一套组件库,不要混用,否则样式和交互逻辑容易打架。
2.2 从零安装 Node.js:环境变量和 npm 源配置
装 Node.js 本身不难,很多人栽在环境变量和 npm 源上。Windows 下直接去官网下载 LTS 版本的 .msi 安装包,一路下一步就行。安装完成后,在命令行里执行 node -v 和 npm -v,如果能正常输出版本号,说明安装成功。
但有个非常常见的坑:你安装的是 Node.js,命令行里敲 npm 却报错,提示 npm 不是内部或外部命令。这种情况绝大多数是因为安装时没有勾选“Add to PATH”选项,或者安装之后环境变量没有生效。解决办法是手动把 Node.js 的安装目录加到系统环境变量 Path 里,然后重新开一个命令行窗口。
npm 默认源在国内访问速度很慢,安装依赖经常卡住。我建议装完 Node.js 之后立刻把源切换成国内镜像:
bash复制npm config set registry https://registry.npmmirror.com
npm config get registry
看到输出是 npmmirror 的地址,说明切换成功。后续所有 npm install 都会走镜像源,速度会快很多。这里还有一个细节:镜像源只影响下载包的速度,不影响包本身的代码内容,所以不用担心安全性问题。
2.3 前端工程化和后端的目录结构
项目我用了最经典的 monorepo 目录方式,一个仓库里同时放前端和后端,各自独立维护依赖。这样做的最大好处是,前后端代码改动可以在同一个提交记录里看到,联调时定位问题特别方便。
text复制airline-system/
├── frontend/ # Vue 3 工程
│ ├── public/
│ ├── src/
│ │ ├── api/ # 接口请求封装
│ │ ├── assets/
│ │ ├── components/ # 通用组件
│ │ ├── router/ # 路由配置
│ │ ├── stores/ # 状态管理
│ │ ├── views/ # 页面组件
│ │ ├── App.vue
│ │ └── main.js
│ ├── package.json
│ ├── vite.config.js
│ └── index.html
└── backend/ # Node.js 服务
├── app.js # Express 入口
├── routes/ # 路由模块
│ ├── auth.js
│ ├── flights.js
│ ├── orders.js
│ └── seats.js
├── middleware/ # 中间件
│ └── auth.js
├── db/ # 数据库连接
├── models/ # 数据模型
├──
