☰
Java毕设:航空票务移动端平台设计与实现全解析
2026/10/5 8:13:31 网站建设 项目流程

每年到了毕业季,计算机专业的同学就开始为毕业设计发愁。Java方向的选题翻来覆去就那么几个:管理系统、电商平台、校园服务APP。而航空票务这个方向,在“XX管理系统”扎堆的选题里算是比较讨巧的——业务链路完整、用户角色清晰、有复杂的余票状态和订单流程可以讲,既不会太简单显得没含量,也不至于像大型电商那样超出个人开发能力范围。今天这篇就好好聊一下“云上航空”这个基于Java的移动端航空票务服务平台,也就是你在标题里看到的“云端翼行”或“智航云途”的完整设计与实现过程,从选题拆解、技术选型、数据库设计、核心功能落地,到答辩展示和常见坑位排查,一次性说清楚。

如果你正准备做类似的学生项目,或者刚拿到这个题目想快速理清思路,这篇文章值得认真看完。我会把整个项目拆开揉碎了讲,包括很多我在实际开发和答辩中被反复问到的问题,以及一套可以直接照搬的优化思路和避坑清单。

1. 项目拆解与整体设计思路

1.1 毕设选题的核心藏在业务闭环里

先说说为什么这个题目值得做。打开毕设选题库,你会发现大量重复的“XX管理系统”——学生信息、图书借阅、超市进销存。不是不能做,但这类项目有个通病:业务逻辑太单薄,数据库就三五张表,答辩时老师随便问两个业务场景就把你问住了。航空票务平台不一样,它的业务天然是闭环的:用户查询航班、选择舱位、提交订单、支付出票、订单状态流转,每一步都牵扯到数据一致性和状态转换。这种“业务闭环”恰恰是毕设评审老师最看重的点,他们不需要你整多炫酷的技术,而是希望看到你能完整地解决一条真实业务链路里的问题。

再往深一层说,航空票务这个场景还有几个天然优势:第一,领域模型足够经典——航班、航线、舱位、订单、乘客,这些都是教材里反复出现的设计对象,照着民航系统的真实业务逻辑去抽象,UML图好画,数据表好设计;第二,性能问题有地方可讲——余票数量的并发扣减、重复下单的判定、支付超时释放舱位,这些点都能引出一大段技术讨论,论文和答辩都不愁没话说;第三,移动端可以外包给Android原生或跨平台方案,服务端用Spring Boot,整个技术栈都是Java生态,非常匹配Java方向的毕设要求。

所以,“云上航空”这个名字听起来花哨,背后的核心就是一句话:做一个以航班票务为核心的移动端前后端分离项目,覆盖用户端、服务端和数据库三层,最终交付一个可演示、可测试、可扩展的完整系统。如果你在选题表上看到的是“云端翼行”或“智航云途”,本质都是一个东西,只是换了个更贴合“云”概念的名字。

1.2 技术选型不追新,够用且能自圆其说

技术选型这块,很多同学有个误区,觉得毕设技术越新越好,微服务、Redis、消息队列一顿上。我的建议是:服务端用Spring Boot + MyBatis-Plus,数据库用MySQL,移动端用Android原生Java开发,最多再用一个JWT做无状态登录认证。听起来不惊艳,但这就是一套能让你稳稳毕业的组合,理由如下。

Spring Boot是目前Java后端的事实标准,封装了繁琐的SSM配置,内置Tomcat,你不需要折腾一堆XML配置就能跑起来一个Web工程。MyBatis-Plus则省掉大量手写SQL的重复劳动,分页插件、条件构造器、逻辑删除都是现成的,对需要快速产出的课程设计和毕设来说非常友好。移动端选择Android原生Java,是因为和毕设技术栈完全一致,不需要引入前端框架的学习成本,你只需要把Activity、RecyclerView、OkHttp、Gson这几样吃透,一个可用的移动端就能搭出来。

服务的BFF结构也很清晰:Android端通过HTTP请求访问后端的RESTful接口,后端Controller层处理请求参数和权限校验,Service层承载业务逻辑(下单、查询余票、处理支付回调),Mapper层通过MyBatis-Plus操作MySQL。至于为什么不做成前后端分离的Web应用,因为题目限定是“移动端票务管理系统”,APP在演示和答辩时比纯网页更有视觉冲击力,评委能拿在手里滑动、点按,体验区分度高。

下面用一张表格快速总结我最终选型,这也是答辩PPT里直接可以放的“技术栈清单”:

层次技术选型用于什么为什么选
服务端框架Spring Boot 2.7.x提供RESTful接口快速搭建、内置Tomcat、生态成熟
持久层MyBatis-Plus 3.5.x数据库CRUD操作简化开发、内置分页和条件构造器
数据库MySQL 8.0存储用户、航班、订单等数据免费、常用、事务支持好
移动端Android(Java原生)用户操作界面与Java技术栈统一
网络请求OkHttp + GsonHTTP通信、JSON解析轻量、通用、上手快
认证方案JWT(jjwt库)登录状态无状态校验适合移动端、分担Session压力
开发工具IDEA + Navicat + Android Studio编码、数据库管理、手机APP打包开发者主流组合,调试方便

这套组合还有一个隐性好处:每一个组件都能在答辩时讲出“选型理由”。比如数据库为什么不用Oracle——毕设用MySQL足够且免费;持久层为什么不用Spring Data JPA——MyBatis-Plus写动态SQL更方便,自己能控制查询逻辑;移动端为什么不用Flutter——Java方向的毕设,用Java原生更贴合课程体系。这些问题我在后面“常见问题”里详细展开。

1.3 三条业务角色线,理清用户到底是谁

系统面向的角色一共三类:普通游客、注册用户和管理员。游客可以浏览航班信息但无法下单,注册用户登录后能下单、支付、查询订单、退票,管理员则负责航班管理、航线管理和订单状态监控。这三类角色对应三套完全不同的权限控制逻辑,也是你画“系统用例图”时的核心骨架。

游客和用户的分界线在于购买权限。游客浏览航班和航班详情时,只需要调用公开的查询接口;点击“立即预订”按钮时,后端会先拦截并提示登录。这里不要只在界面隐藏按钮,因为HTTP接口本身是暴露的,别人可以直接用Postman调用你的下单接口。所以服务端的权限校验必须落在接口层面——用一个拦截器检查请求头里的Token,判断该接口是否允许匿名访问。这个“前端隐藏按钮 + 后端接口鉴权”的双重机制,踩坑率极高,很多同学的账号权限漏洞就是这里出的问题,答辩老师最喜欢顺着这层问下去。

管理员是另一个维度。管理员不做业务操作,但他需要看到全量航班和订单数据,还要能新增、上架、下架航班。实际设计中我会把管理功能拆成一个独立的Controller层模块,并且入口放在APP的“管理入口”分类里,普通用户根本看不到这个模块入口,接口再配合一个AdminInterceptor做二次校验,防止越权访问。

2. 数据库设计与核心业务规则

2.1 五张核心表,撑起整个平台业务

数据库设计是毕设论文里占了大量篇幅的部分,也是评委必看的内容。别贪多,核心表控制在6到8张就够了,再多反而显得业务场景失真,因为真实的小型航空公司后台也就这个规模。

我最终设计用了六张核心表:用户表(member)、乘客表(passenger)、航线表(route)、航班表(flight)、订单表(orders)、订单明细表(order_item)。用户表存登录账号、密码(BCrypt加密)和会员等级;乘客表存常用乘机人信息,一个用户可以有多个乘客;航线表存出发地、目的地和预计飞行时间;航班表存具体某一天某个航线的班次、起飞时间、舱位和余票量;订单表存订单号、总价、状态和支付时间;订单明细表存该订单下每一张票对应的乘客和舱位信息。

有人可能要问,为什么有余票量放在航班表里,订单和航班直接关联不好吗?这就要说到民航系统的真实业务规则了。一个航班的余票资源是有限的,订票的本质就是扣减这个资源。如果把余票放在订单表里用“统计”的方式动态计算,每次查询都要聚合一遍全部历史订单,用户量大了以后性能一定扛不住。单独在航班表里维护一个remaining字段,下单时做一次原子扣减,查余票时直接读字段值,这才符合生产环境的设计思路。

数据表之间的关联关系我放在这里,方便画E-R图时直接参考:

表名主键外键关联说明
memberid无用户表,存账号密码
passengeridmember_id属于某个用户的常用乘机人
routeid无航线表,存起降城市
flightidroute_id航班属于某条航线,存日期和时间
ordersidmember_id订单表,主订单信息
order_itemidorders_id、passenger_id每张票的乘客与航段详情

还有一点必须注意,订单号不要用数据库自增ID,展示给用户时容易被猜到业务量,并且并发插入时也容易冲突。我用的是时间戳+随机数组成的业务订单号(比如202506 08123015 + 6位随机数),这样即便同一秒内产生多个订单也不会重复,用户体验也友好。这个细节虽然小,答辩时讲出来会显得你做了充分的业务思考。

2.2 订单状态机:用状态机代替一堆if-else

订单状态是票务系统里最容易写乱的地方。刚开始我的订单表只有一个status字段,然后在代码里到处判断订单等于已支付才能申请退票这种逻辑,结果写了一堆散落的判断条件,后来调试时经常出现状态错乱的情况。后来老老实实画了一张订单状态图,把整个状态流转梳理清楚之后,写代码就轻松了。

正常流转是:创建订单时状态为待支付,支付成功后变已出票,用户申请退票后变退票中,管理员确认退款后变已退票。异常流转有两条:用户下单后长时间不支付,系统自动关单,回到初始态并释放锁定库存;支付环节调用失败导致订单超时,同样需要进入关闭状态。这两个异常分支的订单必须在后台提供一个定时扫描的任务,把超过30分钟未支付的订单改为关闭状态,并把航班表的余票数量加回去,否则会出现有人占到位置久久不付款、真正想买的人买不到的尴尬情况。

状态机的好处体现在代码层面。我最开始的做法是数据层存状态字符串,服务层写一堆if判断,后来用了一个简单的枚举类OrderStatusEnum,将状态流转规则封装在一个可复用的方法里,任何状态下只允许合法的目标状态发生迁移。这样不仅逻辑清晰,答辩时还能顺手引出“状态模式”这个话题——甚至你可以真的用状态模式重构一遍最核心的“订票状态流转”,为论文增加一个设计模式的讨论点,这在本科毕设里是一个加分项。

2.3 余票扣减和并发控制,这是全系统最硬核的环节

余票扣减的并发控制是整个系统里最有技术含量的地方,也是评委最喜欢追问的一个点。想象一下,同一航班只剩最后两张票,三个用户同时点击购买,如果代码写成“先查询余票,剩余>0就扣减”,三个请求可能同时通过查询,然后同时执行扣减,最终结果可能就是卖出了三张票,余票变成负数。这就是典型的并发安全问题。

解决的方案有两个层次。第一层是数据库层面的原子操作,把“查询余票是否充足 + 扣减余票”合并为一条UPDATE语句,利用WHERE条件天然加行锁的特性来保证原子性,例如:UPDATE flight SET remaining = remaining - 1 WHERE id = ? AND remaining > 0,再通过这条语句影响的行数判断扣减是否成功,如果返回0说明余票不足,直接给用户返回“票已售罄”。这是最简单也最可靠的方案,架设乐观锁的变体。第二层是在事务内使用SELECT ... FOR UPDATE手动锁行,先锁定该航班的行记录,操作完再提交,这种方式适合一系列复杂操作的中控场景。毕设用第一层就够了,讲清楚原理再加一个小例子,这个问题就能轻松过关。

退票时的余票回填同样要注意:不能直接无条件加1,应该同时增加一个已售座位数之类的辅助字段,防止退票数量超过总座位数这种逻辑性错误。其实如果你把这一块做成Service层方法配合事务注解处理,整个订票、锁座、库存回补的链路就能保证要么全成功、要么全失败,不会出现扣了余票但订单没建成功的脏数据。

3. 服务端接口与核心模块实现

3.1 用户注册登录与JWT无状态认证

用户模块是移动端所有操作的前置条件。注册逻辑相对简单,前端把用户名、手机号、密码发过来,后端校验用户名是否存在、手机号格式是否正确,再把密码BCrypt加密后写入member表。这里有一个细节,用户注册之后要不要自动登录?我的做法是注册成功后直接返回Token给前端,减少一次“注册完成再跳登录页”的劣质体验。

登录鉴权用的是JWT。为什么要选JWT而不是传统的Session?因为移动端App不像浏览器那样天然持有Cookie,Session还需要维护会话存储,在分布式部署(哪怕只是演示时开了多个实例)环境下Session同步是个麻烦事,而JWT把用户信息加密放在Token里,后端无状态处理,本质上是一个声明式的认证方案。具体实现是:用户登录成功后后端生成一个包含userId、role、过期时间的Token返回给客户端,客户端拿到后存在SharedPreferences里,之后每次请求在Header里带上Authorization: Bearer token。后端用一个拦截器统一解析Token,拦截器将userId解析出来放进ThreadLocal,供后续Service层获取当前操作人。这个方案在移动端很成熟,面试和答辩聊到这块时会有很多可展开的素材。

需要特别小心的坑是Token过期时间。我一开始设置成2小时,结果演示时经常出现用户玩着玩着Token过期被踢下线,体验很不好。后来改成了7天有效期,同时服务端保留一个token_create_time字段做近7天活跃度统计,这样既有安全性也兼顾演示体验。

3.2 航班查询:多条件检索与航班详情展示

航班查询是乘客打开APP后的核心路径。查询页提供三个必要条件:出发城市、到达城市、出发日期,可选条件是舱位等级(经济舱/公务舱/头等舱)和价格排序。后端航班查询接口通过MyBatis-Plus的LambdaQueryWrapper动态拼SQL,根据前端是否传入参数来决定拼接条件,比如只选了出发城市和日期,就返回当天所有航班,再按起飞时间排序。

有一个交互细节值得分享:机票行业里航班的日期不是按自然日理解的,跨零点航班很常见。比如6月15日00:30起飞的航班,可能航班计划里写的是6月14日航段。所以数据库里建议不要用日期类型记航班日期,而是用日期时间字段记录精确的起飞和到达时间,查询时用时间区间去匹配。这块如果不注意,会出现搜索6月15号的航班,结果把6月14日23:00的航班漏掉的情况。

航班详情页还需要展示剩余票量。为了提升页面响应速度,详情接口把航班基本信息、舱位列表(价格和余票)、航线信息(预计飞行时长)一次性返回给前端,减少网络请求次数。前端把数据填充到详情页各控件,余票量显示为“仅剩3张”这种紧缺提示,少于5张时给按钮加上红色样式,用视觉变化制造紧迫感促进下单转化。

3.3 订票交易:下单、支付回调与事务一致性

订票是这个系统里最复杂的一个接口,核心流程按顺序是:接收乘客列表和航班号 -> 验证航班是否存在且有余票 -> 验证乘客信息 -> 计算订单总额 -> 锁定库存 -> 创建订单 -> 返回订单号并引导支付。

整个下单过程必须是一个事务,我在Service实现类上加了@Transactional(rollbackFor = Exception.class),确保库存扣减或订单创建失败时能全部回滚,不留脏数据。这个事务注解用起来很容易,但要注意两个坑:事务方法不能是同类内部调用(否则事务不生效)、Runtime异常才能触发回滚,Exception的一般异常需要显式指定rollbackFor。这个知识点几乎每次答辩都会被问到,必须提前吃透。

支付功能在毕设里通常做成模拟支付,毕竟没有同学真接支付宝和微信支付的商户号。模拟支付的逻辑是:当用户点击“去支付”后,弹出一个模拟支付确认框,用户确认后前端调用后端“模拟支付回调”接口,后端把订单状态从待支付改为已出票,同时记录模拟支付流水号。这块有一个严谨的做法:后端不要直接“接收支付成功”就改状态,应该在接口里带上一个订单号+随机码的防重放校验,同一个订单只允许支付成功一次,已支付的订单再次回调要返回明确错误。虽然模拟支付没有真实资金交易,但把流程做成严谨状态机的样子,对毕设的完整度提升很明显。

3.4 订单管理:列表、详情、退票与行程扩散

订单列表主要解决数据组织问题。移动端列表页采用“分页加载 + 下滑刷新”,后端通过分页插件返回第几页、每页20条,前端用RecyclerView的Adapter做一个上拉加载更多的交互。订单状态在列表上用颜色做区分:灰色待支付、绿色已出票、橙色退票中、红色已关闭,让用户一眼看到核心信息。

退票接口的业务逻辑要严谨。已支付的订单允许发起退票申请,前端提交退票原因,后端将订单状态变成“退票中”,并将退款状态置为待处理。管理员在后台看到退款申请后审核,审核通过后订单进入“已退票”,同时对应航班的余票回填。这套流程虽然没有对接真实退款通道,但状态流转完整,在论文里可以画出完整的时序图,答辩效果很好。

这里还有一个经验:订票后用户可能还想给同一航班的同行乘客加购一张票。最开始我的逻辑是禁止重复下单,结果演示时被问“同行人买票怎么办”,差点被难住。后来改成同一个用户同一个航班只能创建一笔“待支付”订单,但如果原订单已支付,允许再创建新的订单给另一个乘客加购,这样既防了恶意重复下单,又不限制合理购票。中间这个判断逻辑很值得花时间理清,它反映了真实的业务约束怎么与技术设计互相妥协。

4. Android移动端实现与体验优化

4.1 工程结构与网络请求层的封装

Android端的工程结构我采用的是标准的MVP分层:View层负责Activity和Fragment的界面渲染,Presenter层做业务调度,Model层负责数据请求和缓存。虽然现在官方更推荐MVVM+Jetpack,但毕设用MVP的好处是每层职责清晰,论文里好画图,代码也更容易讲清楚。核心目录结构是:ui包放界面代码(登录、航班列表、订单列表等一个Activity对应一个文件)、adapter包放RecyclerView适配器、api包放Retrofit/OkHttp的接口定义和网络请求封装、model包放实体类和数据源。

网络请求这块我统一封装了一个HttpClient单例,里面初始化了OkHttpClient和Gson转换器,所有API都通过ApiService接口定义。这么做的好处是,全局只需要维护一个OkHttpClient实例,可以统一设置超时时间、公共请求头和错误拦截逻辑。比如每次请求自动从SharedPreferences取出Token放进Header,这样业务代码里完全不用感知Token的存在。

移动端开发最常见的问题就是界面卡顿。性能优化这块我在开发中总结了几条硬经验:列表页的图片不要直接用原图,服务端缩略图配合Android端的图片压缩;不要在UI线程做耗时操作,所有网络请求必须走子线程,通过Handler或回调回到主线程更新UI;RecyclerView一定要用ViewHolder复用,避免每次创建新View导致的滑动卡顿。性能展示在答辩时是好素材,你可以打开Android Studio的Profiler录制一段列表滑动的CPU和内存曲线,截图放PPT里,说服力很强。

4.2 关键页面流转:从航班列表到支付成功的完整路径

页面流转设计是移动端用户体验的核心。用户打开APP第一步是首页,首页有天气插件、热门航线推荐和用户信息卡片;点“查航班”进入航班搜索页,输入出发地、目的地和日期后跳转到航班列表页;选中心仪航班进入航班详情页,看到时间、机型、舱位和价格;点击“预订”如果未登录则跳转登录页,登录后回来继续填写乘客信息;提交订单进入确认页,展示乘机人列表和总金额;点击“去支付”拉起模拟支付弹窗,支付成功后跳转订单详情页。

这个链路看起来平铺直叙,但每条跳转都要传递参数。Android页面传参最推荐的方式是用Bundle来传序列化的Java对象,比如航班对象实现Serializable接口后直接放进Intent。不建议传太多字段,避免页面间数据冗长难维护。我在开发中把航班列表页和详情页之间通过一个Flight对象直接传递,订单确认页则只传订单ID,详情数据通过接口重新拉取——因为这个页面可能有几秒钟的延迟,重新拉取能保证是最新状态且不需要额外传一大堆参数。

4.3 状态同步与用户体验细节打磨

移动端最影响观感的部分是空状态、加载中状态和异常状态的处理。起初开发时列表加载失败就只弹个Toast,用户根本不知道发生了什么。后来统一改成了四种状态:加载中显示转圈动画,加载成功显示内容列表,加载失败显示失败图和“重试”按钮,数据为空显示空插图和提示文案。每种状态都是一个独立的View模板,在布局里共用一个内容区域,通过状态枚举切换。这一个改动让整个APP完成度提升了一个档次,答辩演示时评委看到的不是裸奔的“网络错误”文字,而是一个完整的产品体验。

另外一个很容易被忽略的细节是下拉刷新。Android原生下拉刷新组件SwipeRefreshLayout很好用,但注意嵌套RecyclerView时刷新和列表滚动手势会有冲突,需要留意调用setNestedScrollingEnabled(false)。这个坑我当时查了一下午才搞定,这里先记下来,后面避坑清单里还会提到。

5. 系统测试、部署与常见问题排查

5.1 功能测试用例设计与执行记录

毕设论文里测试章节是凑字数主力,但不代表可以瞎写。测试设计要有层次:单元测试测Service层的业务方法,接口测试用Postman测RESTful接口,移动端再手工配合模拟器跑全流程。最核心的测试用例我列一份样板出来,你可以照抄修改:

编号测试模块测试步骤预期结果实测结果
TC-001注册提交已存在的用户名提示用户名已被占用通过
TC-002登录密码错误提示密码错误通过
TC-003航班查询输入不存在城市的航班返回空列表与友好提示通过
TC-004下单余票仅剩1张,两个用户同时下单只有一个成功,余票不超卖通过
TC-005支付重复回调同一订单第二次回调被拒,订单状态不变通过
TC-006退票已出票订单发起退票状态变退票中,余票回填通过
TC-007权限普通用户调用管理接口返回403无权限通过

有了这张表,答辩时老师问“你做过什么测试”,你可以直接拿出记录表展示,比自己空口说“测过了”有说服力得多。测试过程中如果发现Bug,截图保存,论文中放一张“缺陷记录与修复”表格,这也是很有说服力的工作量证明。

5.2 部署到云服务器,让系统随时可演示

毕设答辩最尴尬的场景是打开电脑连不上数据库、项目跑不起来。强烈建议提前把项目部署到一台云服务器上(阿里云或腾讯云的学生机都很便宜,一个月几十块),把MySQL、Java环境、打包好的Jar包部署好,让APP连到公网地址上。这样答辩现场只需要给手机连上同一个网络,打开APP就能正常演示,再也不用担心笔记本乱装环境的问题。

部署有几个关键点:MySQL要设置允许远程连接,注意修改云服务器的安全组策略放行3306和8080端口;Spring Boot的配置文件要改成生产环境配置,数据库地址和账号密码不再用localhost,用环境变量覆盖;后端接口的跨域配置也得改,移动端没有浏览器同源限制所以不存在跨域,但如果是Web演示端就需要配置CorsFilter。还有一个容易被忽略的问题,就是Android模拟器和真机的网络环境不同,模拟器的10.0.2.2才能访问宿主的localhost,真机要用局域网IP或云服务器公网IP,这个问题我见过太多人卡很久。

5.3 毕设答辩高频问题与避坑速查表

答辩时评委最爱从项目里揪的几个问题,提前准备好答案,基本就稳了。我按实际经历整理了一份高频问题清单,照着准备,应对提问绰绰有余:

  • “为什么用JWT,Session不好吗?”回答思路:移动端无状态、支持分布式、避开了Session共享的问题,同时JWT本身带有效期,安全性可控。
  • “余票扣减怎么保证不超卖?”回答思路:数据库原子UPDATE + 影响行数判定,必要时加行锁或悲观锁兜底,用测试数据证明并发压测结果。
  • “支付是模拟的,和真实支付有什么区别?”回答思路:模拟支付省去了商户号和资质申请,但接口设计完全参照真实支付回调模式,替换为真实网关时只需要替换支付通道适配层。
  • “订单超时自动关闭怎么做的?”回答思路:定时任务扫描超时未支付订单,关闭订单并回补余票。升级思路是延迟队列,但毕设定时任务完全够用。
  • “项目有哪些可扩展的地方?”回答思路:增加消息推送(航班动态提醒)、引入消息队列削峰、对接真实支付和短信验证码服务、会员积分体系。

还有一些我在开发和答辩过程中踩过的坑,现在整理成速查表分享给你,能为你省去很多盲目排查的时间:

坑位描述症状解决方案
Lombok依赖与JDK版本不匹配编译报错找不到getter/setter升级到兼容新JDK的Lombok版本,或直接用IDEA生成代码
MySQL连接串时区问题插入的时间数据和本地时间差8小时连接URL加serverTimezone=Asia/Shanghai
前端无法连接本地后端真机访问localhost失败真机改用局域网IP,模拟器用10.0.2.2
订单重复创建网络重试导致重复下单下单接口增加幂等键,订单号唯一索引兜底
Android列表卡顿RecyclerView滑动掉帧启用ViewHolder复用、图片压缩、数据分页加载
事务不生效异常后数据还是变了检查是否同类内部调用、rollbackFor是否配置
跨域报错Web端请求接口被拦截服务端配置CorsFilter,放行实际来源
服务器端口不通APP连不上服务检查云服务器安全组和防火墙放行相关端口

6. 论文写作、答辩演示与最终经验总结

论文写作这块简单提一下结构:摘要、绪论(背景与意义)、需求分析(用例图)、系统设计(架构图、E-R图、模块设计)、系统实现(核心功能截图+代码片段)、测试(用例表+结果)、总结与展望。图表是论文的门面,必画的四张图是系统架构图、整体用例图、数据库E-R图和订单状态图,这四张图能直接决定评委对你系统理解程度的第一印象。画图工具推荐ProcessOn或draw.io,在线用、自动保存,效率很高。截代码时不要大段粘贴,只需截核心方法的核心片段,并在文字里说清楚这段代码解决的问题。论文查重时注意不要大段粘贴网上的博客总结,用自己的话概括技术方案,重复率会低很多。

答辩演示前有一件事非常重要:准备一台备用演示机。手机上装好APK并且提前登录好一个测试账号,做好几条测试数据,也能直接扫码下载。最坏的情况是现场网络突然抽风,所以演示机上还要装好真机Wi-Fi热点切换到手机流量的能力。演示流程按用户视角走一遍:打开APP、登录、查航班、下单选乘客、提交订单、模拟支付、查看已出票订单、发起退票,大概三分钟搞定。然后再切到管理端界面,展示航班管理、订单监控和退票审核功能,全程连贯。如果时间充裕,还可以放开网络抓包工具(如Charles)现场展示请求和响应的数据包,评委看到这一手操作基本都会满意。

这个项目后续还能怎么扩展?我在完成毕设之后想了几条路:接入真实支付网关(支付宝当面付或微信Native支付);增加航班动态推送(Android推送用极光或厂商通道);部署微服务化(拆分用户中心、订单中心、航班中心三个独立服务);接一个Reids做热点航班缓存,降低数据库压力;管理后台可以补一个图表统计模块,分析每日订单量和热门航线。如果你的目标是毕设答辩拿优或者面试有拿得出手的项目经历,从这些方向里挑一两个做完写进简历,分量立刻不一样。

最后分享一个我个人的实操体会:做毕设最大的敌人不是技术难点,而是进度管理。别想着最后两周冲刺写完,航空票务这种带订单、库存、权限的完整项目,功能联调的时间往往超出你的预期。我当时从列需求、建库表、搭后端骨架到端上能跑通核心流程,前后花了大概六周,其中“并发扣减”和“Android状态同步”两个地方各卡了两三天。把这个时间预算打在计划里,每天保证至少两个小时的有效开发时间,进度就会从容很多。项目做到位了,答辩本身其实是水到渠成的事,因为你亲手完成了一个从0到1的完整产品,每一行代码都能讲出设计和取舍的理由,这本身就是答辩最好的底稿。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询