news 2026/10/10 6:47:49

微信小程序+SSM客运售票系统源码部署与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
微信小程序+SSM客运售票系统源码部署与避坑指南

简介:一套面向微信小程序开发者、基于SSM(Spring+SpringMVC+MyBatis)框架的客运自助售票系统完整源码包,涵盖前端小程序页面、后台管理Vue界面、Java服务端以及数据库脚本和配套论文,适合学习微信小程序全栈开发、Java Web整合或作为毕业设计参考。资源共1276个文件,压缩包约14.87MB,其中包含231个PNG图片、187个JS脚本、140个Vue组件、127个Java类、96个WXSS样式、94个WXML页面,以及SQL脚本、XML配置、JSON数据等,目录结构清晰,覆盖从界面展示到持久化存储的完整链路。目前已有77人浏览学习。包内附带安装运行脚本与项目配置文件,便于快速部署演示;论文部分详细梳理了系统设计思路、接口定义和前后端交互逻辑,有助于理解车次查询、选座、支付等典型业务模块的实现细节,是一份兼顾工程实践与文档规范的学习资料。

1. 微信小程序 + SSM 的客运自助售票:整站源码到手后先别急着跑

客运自助售票小程序这类整站源码,最常见的拿法是从某个压缩包里解压出一堆 Java 文件、XML 配置、SQL 脚本和一篇论文。很多人第一反应是赶紧用 IDEA 打开后端、用微信开发者工具打开小程序,结果往往被数据库密码、Tomcat 版本、小程序域名校验卡住一整天。这套系统的本质是“小程序做界面、SSM 做业务、MySQL 存订单”的三段式结构,适合毕业设计、课程设计,也适合中小客运站快速搭一个内部原型。它值不值得改,取决于你愿不愿意把 SSM 的配置逻辑和微信小程序的登录态机制吃透。本文按“拆架构 → 本地跑通 → 改业务 → 避坑 → 能演示”的顺序,把整条链路里最常见的卡点一次讲完。

2. 先把系统拆开:SSM 三段架构、小程序端与数据库设计的门道

2.1 为什么客运售票用 SSM 而不是 Spring Boot:选型的真实理由

很多源码仍然选择 SSM(Spring + SpringMVC + MyBatis)而不是 Spring Boot,不是因为作者不会 Boot,而是因为这类项目要兼顾“看得见配置”和“论文好写”。SSM 的每个环节都能在 XML 里找到对应关系:Spring 管 Bean 和事务,SpringMVC 管 URL 到 Controller 的路由,MyBatis 管 SQL 与 Java 对象的映射。对于客运售票这种业务,无非是班次查询、余票扣减、订单生成、状态流转,SSM 完全扛得住。

相比之下,Spring Boot 把数据源、事务管理器、视图解析器都自动配置好了,新手反而看不懂“为什么加一个注解就能连上数据库”。如果项目论文里需要画框架图、写“系统采用三层架构设计”,SSM 的 Controller / Service / Mapper 三层结构天然对应。另一个现实原因是老项目依赖的 jar 包和 JDK 版本在 Boot 3.x 里可能不兼容,而 SSM 项目基本都按 JDK 1.8 来写,找运行环境更容易。

我一般会先看压缩包里的 pom.xml 和 web.xml。如果 web.xml 还在且里面有 SpringMVC 的 DispatcherServlet 配置,那基本就确定是传统 SSM 工程,部署方式也是打 war 包扔进 Tomcat,而不是 Boot 那种直接 java -jar。这一步判断很重要,因为后面导入 IDEA 和启动方式完全不同。

2.2 小程序端与后端的分工:谁管页面、谁管订单、谁管支付

这套系统里,微信小程序端只做四件事:展示班次、选择座位/票数、提交订单、查看订单列表。真正干活的在后端。例如用户点“查询班次”,小程序只是把出发站、到达站、日期拼成参数发到后端,后端从 MySQL 查出结果返回 JSON,小程序再用 wx:for 渲染列表。订单的生成、余票的扣减、支付状态的修改,全部由 SSM 后端完成,小程序不做任何计算。

这种分工决定了前后端的接口设计风格。大部分 SSM 接口返回的是统一的 JSON 结构,比如 { code: 0, msg: "ok", data: {...} }。小程序端在 wx.request 的 success 回调里先判断 code,再取 data。有些源码会把返回结构写得不一致,有的接口直接返回数组,有的返回对象,联调时特别容易翻车。

支付是另一个要提前想清楚的点。个人主体的小程序没有微信支付权限,所以源码里通常做一个“模拟支付”按钮:提交订单后直接调用一个后端接口,把订单状态从“待支付”改成“已支付”。真实项目里这个接口应该是微信支付回调地址,但现在绝大多数课设和毕设都停在模拟阶段。我的建议是保留这个模拟接口,同时在后端注释清楚真实支付需要校验签名和回调幂等,论文里也能多写一章。

2.3 数据库表设计:从班次表到订单表,余票字段放在哪

客运售票的核心表一般有五张:用户表(存储微信用户的 openid)、站点表(出发站和到达站)、班次表(车次、时间、票价、余票)、订单表、乘客表(购票时填写的乘车人)。有的系统会把站点直接写成班次里的两个字符串,省一张表;但如果要做“查某个站有哪些车”这种列表,单独的表会好写很多。

余票字段是关键。常见做法是在班次表里放一个 remain 字段,每次下单把 remain 减 1。看起来简单,但并发下单时容易超卖。所以后面第 4 章我会重点讲,UPDATE 语句里必须带 remain > 0 这个条件,而不是先在 Java 里查出余票再判断。另一种做法是放 sold_count(已售数量),配合总票数计算余票,但这需要额外维护总票数字段。对于演示型系统,remain 更直观。

订单表的状态字段通常用 tinyint,0 待支付、1 已支付、2 已取消、3 已退票。这样的数字状态在后端枚举里定义好,小程序端拿到后转换成“待支付”“已支付”等文字。注意有的源码会混用字符串和数字,比如字段叫 status,有的地方赋 "0",有的地方赋 0,导致判断失败。我在拿到 SQL 脚本后第一件事,就是把所有状态字段的类型和默认值过一遍,避免后面改得头皮发麻。

3. 把整站源码跑起来:本地环境、SQL 导入与前后端联调

3.1 环境清单与版本搭配:JDK、Tomcat、MySQL、微信开发者工具

SSM 项目是老技术栈,环境版本不能一味求新。我常用的搭配是:JDK 1.8、Tomcat 8.5、MySQL 5.7、Maven 3.6、微信开发者工具稳定版。这套组合兼容性最好,踩坑最少。如果你本机装的是高版本 JDK,比如 17 或 21,SSM 项目在启动时容易报 UnsupportedClassVersionError 或反射相关错误,因为 CGLIB 和 Spring 老版本不认新 JDK 的字节码。

MySQL 也建议用 5.7,不要用 8.0+。8.0 的驱动类名变成了 com.mysql.cj.jdbc.Driver,而很多 SSM 源码里写的是 com.mysql.jdbc.Driver,虽然 8.0 驱动仍然兼容这个类名,但时区问题会让连接报错。如果只有 MySQL 8.0 可用,需要把连接串加上 serverTimezone=Asia/Shanghai,并且把驱动换成 mysql-connector-java 8.x。

微信开发者工具没有版本强约束,但要注意“不校验合法域名”这个开关在每次打开项目时会默认关闭,调试时如果忘了勾,请求 http://localhost:8080 会被拦下来。下表是这套系统运行的基础环境清单:

组件推荐版本说明
JDK1.8SSM 老项目最稳,避免高版本反射问题
Tomcat8.5支持 Servlet 3.1,与 Spring 4.x 兼容
MySQL5.7字符集 utf8mb4,避免中文乱码
Maven3.6依赖下载,配阿里云镜像加快速度
微信开发者工具稳定版调试小程序前端,需勾选本地域名校验跳过

3.2 导入后端源码到 IDEA:Maven 配置与项目结构说明

拿到源码后,先看根目录有没有 pom.xml。有就是 Maven 工程,用 IDEA 的 Open 直接选根目录,等 Maven 自动下载依赖。如果压缩包里没有 pom.xml,而是一堆 lib 目录放 jar 包,那就是传统 Web 项目,需要手动添加 jar 包到 WEB-INF/lib 下。现在的整站源码绝大多数是 Maven 工程,我按 Maven 方式处理。

pom.xml 里的核心依赖通常是这样的:

<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.18.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.18.RELEASE</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> </dependencies>

这里最关键的是 Spring 版本别乱升到 5.x,因为 Spring 5 最低要求 JDK 8 且部分 API 有变动,老项目里的配置类可能不兼容。MyBatis 用 3.4.x 就好,3.5.x 某些版本对 mapper 接口的绑定方式有调整。导入后右键 pom.xml 选择 Maven -> Reimport,让 IDEA 下载依赖。下载过程中要留意右下角进度条,经常有人还没下完就启动,结果报 ClassNotFoundException。

配置国内镜像可以加快下载,在 Maven 的 settings.xml 里加入阿里云镜像:

<mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <url>https://maven.aliyun.com/repository/public</url> </mirror>

这段配置的作用是把所有 Maven 中央仓库请求转发到国内镜像,避免下载 jar 包超时。注意 mirrorOf 里的 * 表示所有仓库都走镜像,如果项目里有私有仓库,这个配置会把私有仓库请求也拦下来,一般个人项目无所谓。

3.3 初始化 sql 脚本:建库、导入、改数据库连接

源码包里的 sql 脚本通常是 xxx.sql,里面包含 CREATE DATABASE 和 CREATE TABLE 语句。不要直接在 Navicat 里图形化双击运行,我一般用命令行导入,思路更清晰。先登录 MySQL,然后执行:

mysql -u root -p

接着在 MySQL 命令行里创建数据库并导入:

CREATE DATABASE IF NOT EXISTS bus_ticket DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE bus_ticket; SOURCE /path/to/bus_ticket.sql;

SOURCE 后面写脚本的绝对路径。用 utf8mb4 而不是 utf8,是因为乘客姓名和站点名里如果有生僻字或 emoji,utf8 存不下会变问号。导入完成后,用 SHOW TABLES; 查看表是否生成成功。常见问题是脚本里本身带着 DROP TABLE 语句,如果数据库名不对,会导到别的库里。

改数据库连接是启动前最后一步。在 src/main/resources 下找到 jdbc.properties 或 db.properties:

jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/bus_ticket?useUnicode=true&characterEncoding=utf8mb4&useSSL=false jdbc.username=root jdbc.password=123456

这里的 password 要改成你本机 MySQL 的密码。url 里的 useSSL=false 是为了避免 MySQL 5.7 与 JDBC 驱动握手时的 ssl 警告。characterEncoding=utf8mb4 是配合数据库表字符集的,如果只改数据库不改连接串,查询结果里中文仍然是乱码。

提示:如果本机 MySQL 密码里有特殊字符如 @、#,需要在 properties 文件里用反斜杠转义,或者直接改成简单密码。这个文件里出现问题,启动时只会报 Access denied,很多人查半天查不到。

3.4 启动后端与小程序端联调:URL 配置与开发者工具中的域名校验

后端是 war 包部署到 Tomcat。在 IDEA 里配置好 Tomcat 后,点击运行,控制台出现类似 “INFO: Server startup in 6000 ms” 就说明启动成功。先用浏览器试一下后端接口,比如访问:

http://localhost:8080/api/shift/list?startStation=北京&endStation=上海&date=2025-06-01

如果返回一段 JSON,说明后端接口正常。注意端口号不一定是 8080,要看 Tomcat 配置和项目 context path。有的项目设置了 context path 为 /bus,那访问地址就变成 http://localhost:8080/bus/api/...

小程序端联调时,打开项目下的 app.js,找到类似这样的代码:

const BASE_URL = 'http://localhost:8080/bus';

如果后端端口或 context path 不一致,这里就是第一个要改的地方。建议把 BASE_URL 单独放在一个 config.js 文件里,后面切换线上地址方便。

微信开发者工具里,在“详情 -> 本地设置”勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”。因为后端跑在本地 http 服务上,小程序默认只允许请求 https 和已备案域名。勾选后就能在开发者工具里直接调本机接口。别忘了手机预览时需要真机调试,且手机和电脑要在同一局域网,BASE_URL 要改成电脑的局域网 IP,比如 http://192.168.1.8:8080/bus。

4. 核心业务逻辑与参数调整:购票、余票、订单状态怎么改

4.1 查班次与余票:SQL 的条件查询与日期处理

客运售票最核心的查询是“按出发站、到达站、日期查班次”。后端 Controller 接收三个参数,传给 Service,最终落到 MyBatis 的 Mapper XML。常见写法是:

<select id="findShifts" parameterType="map" resultType="com.example.pojo.Shift"> SELECT * FROM shift WHERE departure = #{startStation} AND arrival = #{endStation} AND DATE(depart_time) = #{date} AND remain > 0 ORDER BY depart_time ASC </select>

这里 #{date} 会替换成 PreparedStatement 的占位符,而不是直接拼 SQL,能防止注入。date 参数在小程序端传来的是 “2025-06-01” 这种字符串,DATE(depart_time) 会把数据库里的时间字段转成日期再比较。如果 depart_time 存的是 datetime,直接 equals 肯定查不到,必须用 DATE() 函数。

有一个容易踩坑的点:如果出发站和到达站字段允许为空,比如“查所有从北京出发的车”,SQL 里的条件就要用动态判断。简单做法是 Service 层判断参数为空时调用不同 Mapper 方法,或者用 MyBatis 的 if 标签:

<select id="findShifts" parameterType="map" resultType="com.example.pojo.Shift"> SELECT * FROM shift WHERE 1=1 <if test="startStation != null and startStation != ''"> AND departure = #{startStation} </if> <if test="endStation != null and endStation != ''"> AND arrival = #{endStation} </if> AND DATE(depart_time) = #{date} AND remain > 0 ORDER BY depart_time ASC </select>

WHERE 1=1 是 MyBatis 动态 SQL 的常见写法,避免第一个 if 条件前多出一个 AND。虽然有人觉得 1=1 影响性能,但在 MySQL 里优化器会直接忽略,不影响实际执行。这里真正影响性能的是 DATE(depart_time) 对 depart_time 字段做了函数运算,导致索引失效。如果班次表数据量大,建议在数据库里单独存一个 depart_date 字段,查询时直接等值匹配。

4.2 下单与扣余票:事务控制是命门

下单流程看起来简单:生成订单、扣减余票。但如果代码是“先 select 余票,判断大于 0,再 update 减 1,最后 insert 订单”,两个用户同时下单时可能同时查到余票为 1,然后都执行减 1,最终余票变成 -1,这就是超卖。解决方式有两点:事务保证原子性,UPDATE 条件防止并发。

先看 Service 层代码:

@Service public class OrderService { @Autowired private ShiftMapper shiftMapper; @Autowired private OrderMapper orderMapper; @Transactional(rollbackFor = Exception.class) public boolean createOrder(Order order) { // 1. 扣减余票,条件必须带 remain > 0 int updated = shiftMapper.decreaseRemain(order.getShiftId()); if (updated == 0) { throw new RuntimeException("余票不足"); } // 2. 生成订单 order.setStatus(0); // 待支付 orderMapper.insertOrder(order); return true; } }

对应 Mapper XML 里的扣减语句:

<update id="decreaseRemain"> UPDATE shift SET remain = remain - 1 WHERE id = #{shiftId} AND remain > 0 </update>

关键点:UPDATE 成功后 affected rows 如果不为 1,说明余票已经为 0,直接抛异常。这个“检查与扣减在一条 UPDATE 里完成”的思路,比先查再改更安全。配合 @Transactional,如果第二步 insert 失败,第一步的 UPDATE 会自动回滚,余票不会无缘无故少一张。

事务注解要放在 public 方法上,而且这个类要被 Spring 扫描到。很多人遇到的翻车现场是:事务明明加了,但方法内自己 try-catch 把异常吃掉了,Spring 看不到异常就不会回滚。所以不要在事务方法内部捕获异常后吞掉,要么向上抛,要么手动 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()。

参数调整方面,有的源码会把余票扣减写在下单前,有的写在下单后。我建议先扣减再插入订单,因为插入订单需要订单号,而订单号生成时可以带上余票扣减结果。如果先插入订单再扣余票,扣减失败时订单还会留在表里,需要额外清理。

4.3 模拟支付与订单状态机:不要真打支付接口

支付环节是整套系统里最容易被问“为什么不能直接扫码付款”的地方。个人主体小程序没有微信支付权限,所以源码几乎都是模拟支付。常见设计是预留一个 payController,前端调用后直接把订单状态改成已支付:

@RequestMapping("/pay") @ResponseBody public Result pay(@RequestParam String orderNo) { Order order = orderMapper.findByOrderNo(orderNo); if (order == null) { return Result.error("订单不存在"); } if (order.getStatus() != 0) { return Result.error("订单状态不正确"); } order.setStatus(1); // 已支付 orderMapper.updateStatus(order); return Result.ok(); }

这段代码首先校验订单存在,再校验状态是待支付,避免重复支付把状态改乱。如果后续要接真实支付,这个接口应该替换成微信支付回调地址,回调里要验签、查单、判断金额一致,并且处理幂等——接下来第 6 章会细说。

订单状态机的完整流转是:待支付(0) 可以变成 已支付(1) 或 已取消(2);已支付(1) 可以变成 已退票(3);已取消(2) 和 已退票(3) 是终态。源码里如果没有定时任务清理超时订单,可以在启动类里加一个简单定时器,每分钟查一次超过 15 分钟未支付的订单,改成已取消,同时把余票加回来。恢复余票时要注意,如果用户已经支付,就不能简单加回来,必须先判断状态。

5. 整站源码落地中的常见问题与排查:从启动报错到小程序白屏

5.1 启动 Tomcat 报 ClassNotFoundException:依赖没下全与 Maven 镜像

现象:启动 Tomcat 时控制台出现 java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener,或者 NoClassDefFoundError。

原因:Maven 依赖没有完全下载,或者 IDEA 没有执行 Reload All Maven Projects。SSM 源码的 pom.xml 依赖很多,网络不好时会出现 jar 包下载不完整,IDEA 的本地仓库里留下 .lastUpdated 文件,导致后续怎么重新下载都失败。

解决:先执行 Maven 的 clean,然后右键项目 Maven -> Reimport。如果还是不行,删除本地仓库里所有 .lastUpdated 文件后重新下载。在命令行进入项目目录执行 mvn clean compile,看到 BUILD SUCCESS 再回 IDEA 部署。另一个原因是本地仓库里有旧版本的 jar 包和 pom 里声明的不一致,可以用 mvn dependency:tree 查看实际依赖版本。

5.2 小程序 request 请求失败:http 不是 https 与本地域名校验

现象:小程序发起请求后,控制台报 “request:fail fail url not in domain list”,或者只看到 fail 没有具体原因。

原因:小程序默认要求请求地址是 https 且域名已备案。本地调试用的是 http://localhost:8080,不属于合法域名,开发者工具默认会拦截。另一个原因是工具版本更新后,“不校验合法域名”选项默认不勾选。

解决:在微信开发者工具的“详情 -> 本地设置”里勾选“不校验合法域名”。如果手机真机预览,需要点右上角菜单里的“开发调试”打开调试模式,或者把后端地址改成局域网 IP。注意真机调试时,localhost 指向手机本身而不是电脑,必须改成电脑的局域网 IP,否则请求会失败。另外检查 app.js 里 BASE_URL 末尾有没有多一个斜杠,有时尾斜杠会拼出 http://localhost:8080//api 这种地址,被服务器拒绝。

5.3 数据库中文乱码:连接串缺 characterEncoding 与表字符集

现象:前端页面显示图书名称、站点名全是问号,或者控制台打印 SQL 结果中文正常但小程序里乱码。

原因:数据库表字符集不是 utf8mb4,或者 JDBC 连接串没有指定 characterEncoding。MySQL 5.7 默认字符集可能是 latin1,中文存进去就变成乱码。连接串里的 characterEncoding 只影响客户端和服务端的通信编码,如果表本身是 latin1,写入时还是会丢字节。

解决:先把表和数据库改成 utf8mb4,执行 ALTER TABLE shift CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 再改 JDBC 连接串加 characterEncoding=utf8mb4。改完必须重启 Tomcat,因为连接池在启动时就会读取编码参数。如果已经乱码的数据,需要先删除后重新导入 SQL 脚本,不要试图直接转码。

5.4 下单不扣余票、超卖:事务没生效与 MyBatis 更新返回值

现象:接口调用成功,订单生成了,但余票数量不变;或者高并发测试时余票变成负数。

原因:最常见的三个:@Transactional 注解所在的类没有被 Spring 扫描到;方法内部 try-catch 吞了异常;UPDATE 语句没有带 remain > 0 条件。还有一个隐蔽原因是在同一个类里通过 this 调用事务方法,代理不生效。

解决:确认注解在 Spring 扫描的包路径下,并且类名上有 @Service 或 @Component。不要在方法内 catch(Exception e) 后不抛出。UPDATE 语句写成 SET remain = remain - 1 WHERE id = #{shiftId} AND remain > 0,且用 int updated = mapper.decreaseRemain(...) 判断更新行数。如果事务不生效,可用 @Autowired 注入自身代理,或者把事务方法拆分到另一个 Service 类里。

5.5 微信登录拿不到 openid:code2session 接口参数错误

现象:调用登录接口后,后端返回 null 或报 “errcode”:40029,“errmsg”:“invalid code”。

原因:前端 wx.login 拿到的 code 只能使用一次,且有效期两分钟。有些源码把 code 放在 URL 参数里,被某些转义规则吃掉;或者后端用了错误的 appid 和 secret。还有可能在开发者工具里测试时,用的是测试号而不是真实小程序的 appid,导致 code2session 校验失败。

解决:先确认后端日志里打印的 code 是否和前端传给 wx.request 的一致,排除参数没传到位。然后在微信公众平台里核实 appid 和 secret 是否正确,并把它们放在后端配置里,不要写在小程序前端代码里。code2session 的请求格式是固定的,把地址里的 appid、secret、js_code 替换成自己的值即可。如果只是本地调试,可以在后端临时返回一个 mock openid,测试业务流程走通后再接真实登录。

6. 从“能跑”到“能演示”:补上订单号、参数校验与演示细节

6.1 订单号生成器换成业务友好的规则

源码里常见的订单号是 System.currentTimeMillis() 拼上随机数,但这样看起来不像真实票务系统。我一般会改成日期加业务前缀加流水号:

public static String generateOrderNo() { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); String prefix = sdf.format(new Date()); String suffix = String.format("%04d", new Random().nextInt(10000)); return "T" + prefix + suffix; }

订单号规则改成 T + 时间戳 + 四位随机数,演示时更容易看清下单时间。如果要多机部署,可以用 Redis 自增或数据库序列,但课设项目本地单机运行,这个写法足够。

6.2 用注解校验参数,代替一堆 if

原代码里 Controller 可能写了很多 if (xxx == null) 然后返回错误提示。可以换成 Spring 的校验注解,让代码更干净:

@RequestMapping("/create") @ResponseBody public Result create(@RequestBody @Valid OrderVO orderVO, BindingResult result) { if (result.hasErrors()) { return Result.error(result.getFieldError().getDefaultMessage()); } ... }

在 OrderVO 里字段上加 @NotBlank 和 @NotNull,消息提示能直接透传给小程序。这是演示时的一个加分项,也能减少回调里肉眼排查参数错误的时间。

6.3 演示技巧:热门班次提前造数据、接口别裸奔

演示前用脚本造一批“有规律”的班次数据,比如早上 8 点、9 点整点发车,票价是整数,余票留个位数。这样现场查询时一眼能看出余票变化。另一个技巧是给后端接口加一个简单的登录校验拦截器,排除开发期的裸奔状态。先用 HandlerInterceptor 拦截 /api/order/**,统一校验 header 里的 token,课设展示时能讲清楚“权限控制怎么做的”。

我当初调试这个项目时,最深的教训是没有先确认 MySQL 字符集就导入数据,结果站点名全变问号,返工重导了一遍。后来我养成一个习惯:任何 SSM 项目拿到手,先看 jdbc.properties、再执行 SQL 脚本、然后启动后端,最后才碰小程序,顺序不乱套。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 6:47:40

React Native跨平台状态管理:单向数据流与鸿蒙适配实践

做React Native开发这几年&#xff0c;我越来越觉得“单向数据流”不是会议室里喊的口号&#xff0c;而是真正能减少半夜修Bug次数的一条设计原则。最近我把一个游戏卡片应用GameCards从Android、iOS两端扩展到鸿蒙设备上跑&#xff0c;顺手把整个状态管理重新捋了一遍&#xf…

作者头像 李华
网站建设 2026/10/10 6:47:40

原生JS实现响应式右侧悬浮客服插件:移动端适配与状态管理全攻略

简介&#xff1a;这是一份面向前端开发入门者与需要快速部署在线客服功能的网站维护者的轻量级插件&#xff0c;解决网页右侧悬浮客服入口在不同屏幕尺寸下的自适应适配问题。zip包共3个文件、约12KB&#xff0c;含主页面index.html、交互脚本kefu.js及一张客服图标png&#xf…

作者头像 李华
网站建设 2026/10/10 6:47:32

Unity 3D模型展示实战:3D标注与拆装动画全流程

简介&#xff1a;这份资源面向Unity开发者、教学课件制作者与产品展示设计人员&#xff0c;聚焦3D模型展示中的交互呈现问题&#xff0c;涵盖模型导入优化、3D标注、环绕相机、步骤列表与拆装动画等核心知识点&#xff0c;适合具备一定Unity基础、希望提升展示类应用互动性的中…

作者头像 李华
网站建设 2026/10/10 6:47:24

C盘扩容实战:从D盘借空间给系统盘,无损分区工具操作指南

1. 为什么C盘总是先满&#xff0c;以及扩容前必须想清楚的几件事但凡用过几年电脑的人&#xff0c;大概率都经历过C盘飘红的绝望。系统盘就像家里的玄关&#xff0c;进门出门都得从这儿过&#xff0c;各种软件默认往这儿装、临时文件往这儿堆、系统更新往这儿塞&#xff0c;时间…

作者头像 李华
网站建设 2026/10/10 6:47:16

macOS 进程排查:功能组中只有 Running 状态,App 是如何被拉起的?

大概一年前&#xff0c;我在一台 Mac 上遇到一个挺诡异的现象&#xff1a;某个 App 的窗口都没出现在 Dock 里&#xff0c;进程却一直活着。我用ps看了一眼它的 functional group&#xff0c;发现这个功能组里只有一个进程&#xff0c;状态一直是 R。正常情况下&#xff0c;一个…

作者头像 李华
网站建设 2026/10/10 6:47:08

Apache Pulsar PIP-91 深度解读:将 Lookup 超时从 Operation 超时中分离

消息队列流处理后端微服务消息路由 【免费下载链接】pulsar Apache Pulsar - distributed pub-sub messaging system 项目地址&#xff1a; https://gitcode.com/gh_mirrors/pu/pulsar 点击查看 免费下载 导读 PIP-91&#xff08;PIP-91: Separate lookup timeout from opera…

作者头像 李华