毕设辅导做多了之后有个很明显的体感:论题名单里“社区便利店购物”这类项目永远不缺,难的不是把商品列表和购物车写出来,而是你能不能把“下楼买东西”这件日常到不能再日常的事,完整地转译成一套前后端能协作、数据库能闭环、答辩能讲清楚的生产系统。最近我刚带完一个基于SpringBoot的社区便利店购物平台系统项目,小程序端叫“优购在线”,整体的设计、联调、文档到现在都保留在一套可交付的流程里。这篇就把背后考虑过的业务取舍、数据建模和踩坑过程整理出来,给正在做类似毕业设计或者自己想搭一个全栈练习项目的朋友一点参考。
这个系统面向的是典型社区便利店场景:店铺不大、人流量集中在饭点前后、顾客住得近、客单价不高、复购率却很稳定。比起大而全的电商平台,它更像一个“让附近几百米的人提前下单、到店自提或者叫店员送一下”的接单工具。所以在做方案阶段,我没有直接把传统商城项目照搬过来,而是围绕社区场景把范围收缩到了“选品—下单—支付—备货—签收”这一条主线,再把店主需要的商品、订单管理能力放进后端管理界面。技术栈上也尽量贴近毕设主流的SpringBoot加小程序组合,保证代码结构清晰、演示方便、文档也好展开。
1. 先想清楚:便利店小程序的“业务闭环”到底在哪
1.1 从收银台到后台,系统被“角色”切成了两半
社区便利店数字化以后,最重要的不是做一个看起来很唬人的商城首页,而是还原门店每天发生的“人货场”关系。顾客站在货架前,挑东西、问价、买单,这套动作被线上化以后,就变成了两个截然不同的角色入口。
第一个入口是顾客端的微信小程序“优购在线”。用户不需要下载App,微信里扫一下就能打开。他们在这个端上做的是:看店铺里实际有货的商品、按分类找东西、把酸奶和泡面丢进购物车、选择自提还是配送、下单以后查看订单走到哪一步。第二个入口是平台管理后台,主要给店主或者收银员用。店员在这个端上维护商品上下架、改价格、调整库存、处理顾客提交的新订单,并且把“已支付”的订单改成“备货中”“待自提”或“配送中”,直到顾客签收。
只从功能清单来看,这套东西确实不复杂,但它有个容易被忽略的关键点:订单状态。便利店最怕的就是顾客下单后发现缺货或者店员漏看,所以整个系统都在围绕“订单状态的每一次变更要有迹可循”来设计。顾客下完单看到的是“待支付”,支付成功变成“待接单”,店员点一下“接单”之后又进“备货中”,最后“待自提/配送中”再到“已签收”。这一个状态机的闭环,基本上就是整套业务运转的主干。
1.2 毕设里为什么要额外做“小程序端”这一半
不少学生会问,既然有SpringBoot后端,为什么还要再搭一个小程序前端?直接用管理后台下单不行吗?这里有个非常现实的理由——毕设评审老师的关注点不仅是功能做没做出来,还包括你站没站在真实应用场景里理解系统边界。
如果用纯Web管理端做顾客购物,整个项目会退化成普通的CRUD练习;而引入微信小程序,则额外覆盖了微信登录鉴权、小程序端音频限制规则、跳转配置、以及和第三方平台(微信)的双端联调。这些都是将来在企业里做全栈开发绕不开的内容,同时它也在文档和演示视频里变成容易表现增量功能的部分。用户在手机上打开微信、点进“优购在线”下单,这个过程比打开电脑浏览器访问一个后台系统更有说服力,也更好展示。
1.3 哪些功能被我有意“砍掉”了
这可能是很多同学做系统时最纠结的地方。便利店购物,听起来要不要做优惠券?要不要做会员等级?要不要接入物流查询?我当时的判断是:要克制。
社区便利店采购决策通常是几块钱到几十块钱,顾客看中的是“近”和“方便”,如果引入复杂的营销系统,购物车价值反而会淹没在无休止的规则判断里。毕设答辩时间有限,如果功能遍地开花但每块都浅尝辄止,老师几个追问就会露馅。所以这套系统里只保留了用户最刚需的部分:用户管理、分类浏览、关键字搜索、购物车、订单、地址管理、支付模拟、商品管理、库存管理、订单处理和基础统计。把一个高频链路做深做透,远比堆二十张表要更有价值。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从微信登录到订单签收:主链路实现中的取舍与步骤
2.1 微信登录不是“输入用户名密码”,而是code换身份
做小程序端第一件事就是处理登录。和Web端不同,微信小程序里很少让用户去注册登录账号,常见的做法是用微信官方提供的 wx.login() 接口拿到一个临时code,再把code发到SpringBoot后端,由后端调用微信的 code2Session 接口换取 openid 和 session_key。openid 在小程序应用范围内是用户唯一标识,所以用它作为用户的业务主键再合适不过。
代码上大致是这样:
java复制@PostMapping("/wx/login")
public Result<String> wxLogin(@RequestBody WxLoginDTO dto) {
// dto.getCode() 来自小程序端 wx.login 的成功回调
String url = "https://api.weixin.qq.com/sns/jscode2session" +
"?appid=" + wechatProperties.getAppId() +
"&secret=" + wechatProperties.getAppSecret() +
"&js_code=" + dto.getCode() +
"&grant_type=authorization_code";
String response = restTemplate.getForObject(url, String.class);
JSONObject jso
