做这个“大学生家教平台”项目之前,我一直觉得它只是一个标准的 CRUD 堆积,直到真正把 Spring Boot 和微信小程序两条线串起来,才发现里面值得抠的细节比想象中多得多。无论你是拿它当毕业设计,还是想当成一个完整的全栈练手项目,这套组合都能让你在最短的时间内体验到一个真实商业项目从需求到上线的完整链路。这篇文章我就把整个过程拆开来讲,包括需求规划、表结构设计、微信登录闭环、订单匹配逻辑、支付集成、上线踩坑,最后再补一块我在实际开发中总结出来的排错经验,希望能帮你少走弯路。
1. 项目概述与需求拆解
1.1 面向的用户群体与核心痛点
大学生家教平台本质上是一个连接“有家教需求家庭”和“有空闲时间的大学生老师”的信息撮合平台。用户角色很清楚:家长/学生端负责发布找家教需求,大学生端负责提交可教科目、设定时薪、接受订单。如果你只把平台当成一个列表加详情页,那就想简单了,家教的场景里有几个非常关键的痛点需要我们优先解决。
第一个痛点是信息不透明。家长不知道怎么快速找到靠谱的大学生老师,大学生老师也不太容易找到精确匹配科目和距离的需求。所以平台不能只做一个“信息流”,必须要有科目筛选、区域筛选、按价格排序、按评价排序这类能力。第二个痛点是信任问题。线下交易一旦出现纠纷,平台就不存在了,所以必须引入微信登录实名身份、家长/学生端对老师地址的模糊匹配、订单完成后的双向评价,以及最核心的“第三方担保”机制,即便个人毕设不做真实支付,也要把订单状态机和退款流程设计出来。
第三个痛点其实是运营层面,容易被开发者忽略:平台管理员需要看到每天新增了多少需求、多少老师入驻、完单率是多少。如果连统计报表都没有,整个平台就像没有方向盘的车。所以我建议哪怕做毕设,也一定要把后台统计页面加上,简单几个图表就行,这让评委和用户都觉得系统是完整的。
1.2 功能模块边界:先做减法再做加法
很多同学一开始就把功能表拉得特别长:拼团、优惠券、直播、在线课堂……这是典型的需求失控。我强烈建议把整个平台切分成“最小可行版本”和“二期扩展”两层。
最小可行版本里只需要六块功能:
- 用户模块:微信授权登录、身份选择(家长/学生/大学生老师)、个人资料维护;
- 科目与老师展示模块:按科目/区域检索老师列表;老师可以上架个人可教课程、设置时薪、填写教学经历;
- 需求发布模块:家长填写孩子年级、薄弱科目、期望时薪、可上课时间段;老师端可以对感兴趣的需求发起报名或预约;
- 订单模块:家长选择老师并生成订单,订单覆盖预约、进行中、待评价、已完成、已取消等状态;
- 评价与收藏模块:订单完成后双向评价;家长收藏常联系的老师;
- 管理后台:对用户、科目、订单进行管理,并展示核心统计数据。
二期再考虑优惠券、讲义资料下载、在线小程序内支付、社区问答等。把边界划好,开发周期会明显缩短,代码结构也不会被各种异常逻辑撑爆。
1.3 为什么选“微信小程序 + Spring Boot”而不是其他组合
我可以说一个很实际的选择逻辑:微信小程序是目前触达用户成本最低的移动端形态,不需要安装,用完即走,而且家长群体对微信的接受度非常高,不需要额外教育用户。Spring Boot 则是 Java 后端里迭代效率最高的框架之一,它的自动装配、Starter 生态和成熟的社区,能让本项目从零到一跑起来的速度远快于传统 SSM。
如果你纠结要不要用 Vue 做后台管理,我的建议是:后台直接用 Spring Boot 自带的模板引擎渲染也可以,但更推荐开发一个独立的前后端分离管理端。我在实际项目里用的是 Spring Boot 提供 REST API,配合一个轻量级的 Vue 管理端来管后台数据,这样不仅能在答辩时展示前后端分离的架构能力,也为以后扩展桌面端和 App 端保留了接口兼容性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构与数据库设计
2.1 后端技术栈明细与版本选型
写 Spring Boot 项目时,第一步被问得最多的就是“用哪个版本”。我个人的建议是:如果你参考了很多网上的旧教程,或者想复现别人现成的代码,优先选 Spring Boot 2.7.x,搭配 JDK 1.8 或者 JDK 11。因为很多现成工具包和教程都是基于 javax 命名空间写的,而 Spring Boot 3.x 已经迁移到了 jakarta,导致不少老项目在升级时出现满屏的 ClassNotFoundException。
如果你的项目是全新的,并且愿意自己处理这些坑,也可以直接上 Spring Boot 3.x + JDK 17。这个组合启动更快,安全补丁也更及时。下面是本项目我用到的核心依赖清单:
| 组件 | 选型 | 说明 |
|---|---|---|
| 核心框架 | Spring Boot 2.7.18 | 生态稳定,教程多 |
| ORM 框架 | MyBatis-Plus | 减少写 SQL 的工作量 |
| 数据库 | MySQL 8.0 | 支持 JSON 字段,方便存储扩展信息 |
| 缓存 | Redis | 存验证码、临时 token、热点老师信息 |
| 权限认证 | JWT + 拦截器 | 无状态,适合小程序端 |
| 接口文档 | Knife4j | 生成调试用的 Swagger 文档 |
| 工具包 | Hutool | 生成订单号、转换对象 |
| 实时通知 | Spring WebSocket | 订单状态变化推送给对应端 |
版本问题真的会让人崩溃。我记得有一次项目里引入了某个工具类库,它在 Spring Boot 2.x 下跑得很好,结果重新建了一个 3.0 新项目后直接报错,找了一圈才发现是 javax 和 jakarta 不兼容。我的建议是:搭新项目之前,先去 Maven 仓库看一眼依赖的 Spring Boot 版本区间,不然很容易被各种隐性问题折磨一下午。
2.2 小程序端技术选型与项目结构
微信小程序端有两种主流的实现方式:原生小程序和 UniApp。如果你只是希望快速完成单个微信小程序,原生小程序就够用;如果你以后想向支付宝小程序、抖音小程序多端发布,就用 UniApp 编译一套代码。我选择的是原生小程序,原因是调试方便,微信原生 API 的文档最全,出问题也更容易搜索到解决方案。
小程序的页面结构大致分四类:
pages/index:首页,展示推荐老师和今日需求;pages/teacher:老师详情、可教课程、历史评价;pages/order:订单列表、订单详情、状态流转操作;pages/user:用户中心、个人资料、收藏记录、统计信息。
在目录上,把 utils/request.js 单独抽出来作为全局请求封装很重要。每个请求都自动带上 Authorization 头,遇到 401 时自动重新走一次微信登录逻辑,这样后面的业务代码会清爽很多。
2.3 数据库表设计,一个表都不能浪费
这个项目的核心表我建议这么分:用户表、老师信息表、家长/学生信息表、科目表、需求发布表、课程表、订单表、评价表、收藏表、消息通知表、系统配置表。这里不铺开所有表,单独说三个设计上最容易踩坑的点。
第一,用户表不要试图把所有身份信息都揉在一张表里。我把公共信息如头像、昵称、手机号、角色类型放在 user 表,把老师特有信息如大学、年级、辅导经历、可授课时间放在 tutor_info 表,家长/学生端的信息放在 parent_info 表。这样做的好处是后续如果做 App 端或者 PC 端,身份字段可以继续复用。
第二,订单表必须包含状态和时间流转字段。除了常规的 order_status,我建议增加 create_time、pay_time、start_time、end_time、complete_time、cancel_time。老师迟到还是家长取消,后台一查时间线就非常清楚,也能为以后做纠纷判定留下数据依据。
第三,评价表要和订单一对一关联。为了避免同一个订单被刷好评,我给订单表加了 review_status 字段,只有为 0 表示未评价,当评价提交后更新为 1。接口层再对用户权限做一次校验,只有订单关联的双方才可以提交评价。
下面给出订单表和老师信息表的简化建表参考,实际项目里可根据需要再加字段:
sql复制CREATE TABLE `t_order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`order_no` varchar(64) NOT NULL COMMENT '业务订单号',
`parent_id` bigint(20) NOT NULL COMMENT '家长用户ID',
`tutor_id` bigint(20) NOT NULL COMMENT '老师用户ID',
`subject_id` bigint(20) NOT NULL COMMENT '科目ID',
`begin_time` datetime DEFAULT NULL COMMENT '预计上课开始时间',
`end_time` datetime DEFAULT NULL COMMENT '预计上课结束时间',
`total_fee` decimal(10,2) NOT NULL COMMENT '总课时费',
`order_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0待接单 1已预约 2授课中 3待评价 4已完成 5已取消',
`review_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未评价 1已评价',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `t_tutor_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`real_name` varchar(50) DEFAULT NULL,
`university` varchar(100) DEFAULT NULL COMMENT '大学名称',
`grade` varchar(50) DEFAULT NULL COMMENT '年级',
`subjects` varchar(200) DEFAULT NULL COMMENT '可教科目,逗号分隔',
`hourly_rate` decimal(10,2) DEFAULT NULL COMMENT '期望时薪',
`intro` text COMMENT '个人简介',
`auth_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未认证 1审核中 2已认证 3驳回',
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.4 接口设计与统一响应结构
接口设计直接影响小程序端的开发效率。我建议所有接口都返回下面这种统一 JSON 结构,避免前端处理异常时到处写 if:
json复制{
"code": 200,
"message": "success",
"data": {}
}
分页接口的 data 统一返回 records、total、current、size。比如老师列表接口给前端的数据结构就是下面这样:
json复制{
"code": 200,
"message": "success",
"data": {
"records": [
{
"id": 1,
"nickname": "张老师",
"university": "XX大学",
"subjects": "数学,物理",
"hourlyRate": 150
}
],
"total": 100,
"current": 1,
"size": 10
}
}
接口命名上也最好统一:资源名用复数名词,动作放在 HTTP 方法里。比如 POST /api/orders 表示创建订单,PUT /api/orders/{id}/cancel 表示取消订单。不要在 URL 里写一堆 do、handle 之类的动词,维护时会很痛苦。
3. 核心功能实现与关键细节
3.1 微信登录闭环:从 code 到 openid
微信小程序登录逻辑是所有业务的基础,也是最容易出现问题的地方。很多朋友一上来就遇到“小程序获取登录后的微信用户失败”,其实大部分情况下不是前端写错了,而是对登录流程没有一个全局理解。
登录流程拆开来看就三步:
- 前端调用
wx.login()拿到临时code; - 后端拿到
code后,调用微信接口https://api.weixin.qq.com/sns/jscode2session,并携带小程序的appid和secret; - 微信返回
openid和session_key,后端用openid去数据库匹配用户,存在则签发 JWT,不存在则自动注册并再签发 JWT。
这里有一个非常核心的点:session_key 绝对不能返回给前端,也不能存到日志里。它用于后面解密用户手机号等敏感数据,泄露了就有安全风险。后端只把 JWT 返回给前端,前端后续请求用 Authorization 头带上 JWT 即可。
具体代码如下:
java复制@PostMapping("/auth/login")
public R<String> login(@RequestBody WxLoginRequest request) {
// 1. 换 session
WxMaService wxMaService = WxMaConfiguration.getWxMaService();
WxMaJscode2SessionResult session = wxMaService.getUserService()
.getSessionInfo(request.getCode());
String openid = session.getOpenid();
String sessionKey = session.getSessionKey();
// 2. 查库或注册
User user = userMapper.selectOne(
new LambdaQueryWrapper<User>()
.eq(User::getOpenid, openid));
if (user == null) {
user = new User();
user.setOpenid(openid);
user.setNickname("微信用户_" + openid.substring(openid.length() - 6));
user.setRole(0); // 默认角色,待用户选择
user.setCreateTime(LocalDateTime.now());
userMapper.insert(user);
}
// 3. 签发 JWT
String token = JwtUtil.createToken(user.getId(), user.getRole());
return R.success(token);
}
这里要特别注意 openid 的解析过程。微信接口返回的是 openid 字段,不是 unionid,很多新手会把这两者混用。单小程序场景下只需要 openid,只有同一主体下的多个小程序或公众号需要打通身份时,才需要关心 unionid。
3.2 基于 JWT 的权限控制与登录态刷新
拿到 JWT 后,下一步就是做权限控制。我采用的是 Spring Boot 拦截器加自定义注解的方式,没有引入重型的 Spring Security,因为毕设或者中小型项目引入 Security 反而会把配置弄得复杂。
核心逻辑就两步:
- 写一个
LoginInterceptor,实现HandlerInterceptor,在预检请求放行后,解析请求头中的Authorization,解析出用户 id,放入ThreadLocal; - 写一个
@RequireLogin注解,标注在需要登录的接口上;拦截器里校验注解是否存在,如果不存在就直接放行。
示例:
java复制public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
if (handlerMethod.getMethodAnnotation(RequireLogin.class) != null) {
String token = request.getHeader("Authorization");
try {
Long userId = JwtUtil.parseToken(token);
UserContext.set(userId);
} catch (Exception e) {
response.setStatus(401);
return false;
}
}
return true;
}
}
登录态的刷新也不要忘记。微信小程序的 session_key 和前端登录状态有自己的生命周期。我建议小程序端在第一次 wx.login 后,把 JWT 的过期时间设置为 7 天,前端可以在 request.js 中统一判断返回码,如果遇到 401,就重新调用 wx.login 刷新 JWT。
还有一个细节:wx.login 的 code 有效期只有五分钟,且只能使用一次。有些用户在小程序切到后台再回来,如果前端代码写得不对,可能把同一个 code 反复提交,后端就会报错。要在前端加一个标记,确保每个 code 只请求一次。
3.3 家教需求发布与智能匹配流程
家教平台的业务核心不是简单的信息列表,而是“需求”和“老师”的撮合。我在设计时把流程分成了两步:家长发布需求,系统做推荐和排序;老师浏览需求,主动报名。
家长端发布需求时,前端会提交这些字段:年级、科目、期望时薪、上课区域、期望时间段、孩子情况描述。后端接收到之后,需要做两件事:
- 写入
t_demand表; - 触发一次匹配计算,向符合条件的老师推送服务通知或站内消息。
匹配规则不能太复杂。我常用的是“科目精确匹配 + 区域模糊匹配 + 价格区间过滤”,价格区间是老师时薪小于等于家长期望时薪的一定上浮比例。如果直接把所有老师都推送出去,反而会削弱匹配质量。
老师端报名需求后,家长端会看到报名列表。家长可以查看老师的认证资料、历史评价,然后选择其中一位进行预约。这个设计比直接让家长“抢购”老师更符合家教的实际场景,因为家长需要时间判断。
需求列表还需要考虑过期下架。我建议在后端用定时任务或 Spring Boot @Scheduled 配置一个清理任务,每 30 分钟扫描一次已超过 48 小时仍未匹配成功的需求,自动改为 已关闭,并给老师端移除该按钮。
3.4 订单状态机与支付流程
订单是这个平台里最敏感的业务。我不建议把订单状态写成一堆散乱的 if,最好用状态机来管理。状态流转长这样:
text复制待接单 -> 已预约 -> 授课中 -> 待评价 -> 已完成
待接单 -> 已取消
已预约 -> 已取消
家长创建订单后,老师会收到提醒。老师可以接单,也可以拒绝。接单后订单进入 已预约 状态,同时锁定老师接下来这段时间的排期,避免撞单。
关于支付,家庭教师平台如果走真实交易,需要对接微信支付。小程序的 wx.requestPayment 配合后端统一下单接口,具体流程是:
- 后端根据订单创建预支付订单,参数包含
appid、mch_id、openid、订单号、金额、回调地址; - 微信返回
prepay_id,后端再把这个参数和其他签名参数一起返回给前端; - 小程序端调用
wx.requestPayment,拉起收银台; - 用户支付完成后,微信服务器会异步通知我们配置的回调地址,后端在这个回调里更新订单状态。
回调处理必须做幂等。因为微信通知可能会重复发送,回调里要先查数据库,如果订单已经是 已支付 状态,就直接返回成功,不能重复更新金额和状态。这一点我在测试阶段踩过一次坑,同一笔订单被回调两次,导致数据库里的记录被重复更新。
如果不想接真实支付,也可以用模拟支付开关。比如开发环境配置一个 mockPay=true,前端点击支付按钮后直接模拟支付成功。但订单表和回调逻辑仍然要保留,这样切换正式支付时只改一个配置。
3.5 评价、收藏与消息通知
评价功能的关键不只是“评分”本身,而是防止刷评价。我的做法是:只有订单状态为 待评价 时,双方才能发起评价;评价后订单状态自动变为 已完成。接口里还要校验评价者是否为订单关联用户,避免别人代评。
收藏功能实现很简单,一张 t_favorite 表就够,包含用户 id 和老师 id 两个外键。但页面上要做一个“已收藏”状态的实时反馈。小程序端首次加载页面时,可以并行请求收藏状态接口,或者把收藏的老师 id 列表一次返回给前端,前端用 Set 判断。
消息通知模块我建议优先使用小程序的订阅消息。因为站内信的实现虽然简单,但用户不会每天都打开小程序,容易错过订单变化。订阅消息需要用户在小程序里主动授权订阅,所以可以在家长创建订单、老师接单的关键节点引导用户点击“允许通知”。
如果支付了还想要更实时的触达,可以加 Spring WebSocket,在订单状态变更时向后端在线用户推送实时消息。但这里注意,WebSocket 不适合大量持久连接,家教的订单频次不高,完全够用。
3.6 管理后台的统计报表设计
管理后台最容易做得敷衍,但从项目完整度来说,它反而是加分项。我会在后台放四张核心统计卡片:今日新增用户数、今日新增需求数、本月完成订单数、平台总交易金额。另外再放两个 ECharts 图表:
- 近 7 天订单量趋势;
- 科目需求分布饼图。
这些统计接口用一条 SQL GROUP BY 再加时间条件就能查出来,并不复杂。真正要注意的是把统计接口和普通查询分开,不要让统计业务拖慢主线上业务的性能。如果数据量大,再考虑加 Redis 缓存。
4. 开发与上线过程中的高频问题实录
4.1 小程序获取登录后的微信用户失败,到底卡在哪
这个报错我见过太多次了,而且真的是从微信公众号开发者工具到真机调试都有可能出现。报错信息里往往会带一个 appid,比如 wx1cb4398e1413dce7,很多人以为是代码问题,实际上一半以上是因为 appid 和 secret 不匹配,或者开发者服务器调用 jscode2session 的接口请求失败。
排查路径我建议按照下面这个顺序来:
- 检查小程序后台的
appid是否和前端项目里的appid一致; - 检查后端配置的
secret是否属于同一个小程序; - 检查后端是否能正常访问外网(
https://api.weixin.qq.com); - 检查后端日志,看 jscode2session 返回的错误码是多少,比如 40013 代表无效 appid,40125 代表无效 secret。
还有一个经常被忽略的点:如果你在小程序后台设置过“服务器域名”,那么前端 wx.request 请求的地址必须是 HTTPS 且已在合法域名列表中。开发者工具里勾选了“不校验合法域名”选项是能跑通,但在真机上会直接报 url not in domain list。这个问题会在下一个小节里细讲。
4.2 真机测试出现 net::ERR_CONNECTION_RESET 如何排查
真机测试时报 ERR_CONNECTION_RESET,通常意味着请求根本没有到达后端服务器,或者请求被中间某个环节拦截了。我遇到过的原因有三种:
- 后端服务只监听了
127.0.0.1,而手机访问的是局域网 IP,所以连接被重置; - 服务器防火墙没有放行对应的端口;
- 后端返回内容太大,连接被中间代理切断。
最有效的排查方法是先用电脑浏览器访问 http://服务器IP:8080/api/xxx,能通再上真机。如果电脑能通而手机不能通,就先检查服务监听地址是不是 0.0.0.0,再查看云服务器安全组是否开放了对应端口。Spring Boot 程序的启动日志里会显示 Tomcat started on port(s): 8080 (http) with context path '',上面没有绑定具体 IP 就是正确的。
4.3 Spring Boot 版本太高,反而踩了一堆兼容坑
“Spring Boot 版本太高”这件事,真的不是玩笑。Spring Boot 3.0 带来了全面转向 jakarta 命名空间的改动,这意味着不少第三方依赖,尤其是一些老牌的 MyBatis 增强组件,在迁移时会出现兼容问题。
如果你准备用最新版 Spring Boot,建议先确认这几个点:
- MyBatis-Plus 是否支持 Spring Boot 3 的
spring-boot-starter-jdbc; - 项目中是否用到了
javax.servlet,需要替换成jakarta.servlet; - 定时任务注解
@Scheduled是否正常工作。
我当时为了省事,直接选了 Spring Boot 2.7 的最后一个发行版,既保留了对旧依赖的兼容性,又能拿到一些漏洞修复。如果你不是为了尝鲜,没有必要一上来就上 3.x。
这里顺手提一句循环依赖。Spring Boot 2.6 之后默认禁止循环依赖,如果 A 服务里注入了 B 服务、B 服务里又注入了 A 服务,启动时会直接报错。我在早期写代码时经常图方便互相注入,后来规范是“尽量单向依赖,必须循环时通过 @Lazy 延迟注入解决”。
4.4 域名、证书与合法域名配置
小程序上线必须使用 HTTPS 域名,这是很多第一次做小程序的人容易忽略的硬要求。你需要准备一个已经备案的域名,并给该域名配置 SSL 证书。如果使用腾讯云,可以直接申请免费的 TrustAsia 证书,有效期一年,一年后记得重新签发。
配置完成后,要在微信公众平台小程序后台的“开发管理-开发设置-服务器域名”里添加 request 合法域名。这里有一个非常坑的点:开发环境调试用的 localhost 不需要配置到合法域名,但真机预览时不能使用 localhost,必须用局域网 IP 或线上域名。如果项目还没上线,又想在真机上预览,有两个办法:
- 在开发者工具里勾选“不校验合法域名”,但真机预览时仍可能失败;
- 把后端接口地址改成局域网 IP,然后在开发者工具里点击“真机调试”,让手机和电脑处于同一局域网。
这只是开发期的临时方案。正式上线前一定要把接口切到线上 HTTPS 域名,并在小程序后台配置好。
4.5 支付相关资质与审核注意点
如果准备在小程序内接入微信支付,需要先完成微信商户号的申请,并且小程序的主体要和商户号主体一致,否则无法正常拉起支付。个人主体的小程序目前不能申请微信支付,只能使用个人码等替代方案,但这就不属于“小程序支付”了。
审核时还要特别关注隐私协议。小程序在获取用户手机号、位置、头像昵称等敏感信息前,都必须声明隐私保护指引,并且在小程序管理中配置对应的用户隐私保护指引。如果不配置,审核会被打回,甚至部分 API 在线上也无法正常调用。建议在开发阶段就提前把隐私协议文案准备好,避免上线前手忙脚乱。
5. 部署上线与后续迭代优化
5.1 服务器环境初始化与后端打包部署
我习惯把后端打包成 Docker 镜像来部署。这样不仅方便回滚,也能让环境保持一致。如果你的服务器是 CentOS 或 Ubuntu,装好 Docker 和 Docker Compose 后,可以按下面这个流程走:
- 用 Maven 执行
mvn clean package打成 jar 包; - 写
Dockerfile,基于openjdk:8-jre-alpine或eclipse-temurin:17-jre构建镜像; - 通过
docker compose up -d拉起 MySQL、Redis、后端服务; - 用 Nginx 反代后端接口,并配置 HTTPS 证书。
后端接口建议不直接在公网暴露端口,而是只允许 Nginx 访问后端容器的内部端口,通过 Nginx 将 /api 路径转发到 Spring Boot 服务。这样做一方面方便统一处理 HTTPS,另一方面也能减少被扫描攻击的风险。
5.2 小程序发布与版本更新
小程序端开发完成后,先在开发者工具里点击“上传”,然后到微信公众平台提交审核。审核通常需要几个小时到一天。审核前可以用体验版邀请几位真实用户测试一遍,重点检查登录、下单、支付回调、订阅消息这几个核心链路。
发布后还要考虑版本更新的问题。小程序更新不是实时的,一部分用户可能还在使用旧版本。如果想要强制更新,可以在小程序启动时调用 wx.getUpdateManager,检查到新版本后弹出“重启小程序”的提示。这个小功能不复杂,但体验提升非常明显。
5.3 运营期数据监控与功能迭代方向
上线后要关注的核心指标不是用户数,而是“撮合成功率”和“完单率”。如果用户注册量不少,但发布需求后没有老师响应,问题可能出在老师数量不足或者匹配排序不够合理。
后续迭代可以优先考虑几个方向:
- 增加老师资质审核:上传学生证或教资证明,提升家长信任度;
- 增加“试听课”概念:支持首单低价体验,降低家长决策门槛;
- 增加“老师排班日历”:让家长直接选择老师空闲时间,减少沟通成本;
- 增加“附近需求”地图模式:方便老师按距离快速过滤需求。
这些功能都建立在你已经有一个清晰数据模型的基础上,迭代起来只是增加接口和页面,不会推倒重来。
6. 我的个人实操体会
把整个项目从头到尾写一遍,我最想强调的一点是:不要小看“搭架子”这件事。有些同学喜欢上来就写业务代码,结果做到一半发现登录拦截和错误码设计没统一,前后端联调时天天被各种格式问题拖后腿。我后来把所有接口都统一格式,把 JWT 拦截器、全局异常处理放在项目第一天就做好,后面开发效率真的提升非常明显。
另外一个让我印象很深的点是,小程序的 wx.login 和 request 是有时序依赖的。我第一次写前端时,直接在页面 onLoad 里同时发登录请求和业务请求,结果业务请求先到后端,后端因为没拿到登录态直接返回 401。现在我会把所有请求都放到 request.js 这个统一封装里,请求前先检查是否已有 JWT,没有就等登录完成再发业务请求。
最后再说一个小技巧:你在做老师排序和需求推荐时,不用一开始就上复杂算法,用“精准匹配 + 基础分数”就能达到很好的效果。比如设置匹配分,科目一致加 50 分,区域一致加 30 分,有完单评价加 20 分,按分数倒序展示。这套逻辑简单,效果直观,也方便你在答辩时讲清楚推荐逻辑,这才是毕设的价值所在。
如果这个项目的流程你已经完全跑通,后面再往里面加优惠券、拼单、在线教学视频,都只是增加模块的事情。核心的登录鉴权、订单状态机、支付回调、数据统计框架不会变。希望这篇文章能给你一个清晰的地图,照着走,少踩几个坑。
