首页 / 资讯中心 / 文章详情

基于微信小程序的首饰商城系统毕设实战:从技术选型到答辩避坑

基于微信小程序的首饰商城系统毕设实战:从技术选型到答辩避坑 ★ FEATURED ARTICLE
写在前面的几句大实话每年毕设季“微信小程序 Java 商城”类题目都是绝对的大热门。你拿到“基于微信小程序的首饰商城系统”这个题目说明学校或者导师给了你一个非常经典、非常稳的切入点前端是小程序后端是 Java业务是电商。这个组合覆盖了从前端交互到后端接口、从数据库设计到部署上线的完整链路既能体现工作量又不会太难到做不出来。但我带过不少做类似题目的学生发现大家最常陷入的困境是功能做出来了答辩被问几句就露馅或者代码堆了一堆结构却乱得连自己都看不懂。所以这篇文章我不想只给你一份“能跑的代码”而是想从一个过来人的角度把这个项目从选题拆解、技术选型、核心设计到实操步骤、常见坑点完整地过一遍。你能照着它把项目做出来还能在答辩时说得清楚、站得住脚。1. 项目定位与核心需求拆解1.1 一个“看起来普通”的毕设题老师在考什么很多同学拿到这种“商城系统”题目第一反应就是这不就是一个加购物车、下单、支付的 CRUD 吗如果你抱着这种心态去做那大概率做出来的东西就是一张表套一张表答辩时一问业务逻辑就卡壳。实际上导师给你这个题目的核心目的是要考核三件事第一你懂不懂工程化结构。不是说你写了多少个接口而是你的项目分层是否清晰Controller、Service、Mapper 是否各司其职配置是否合理异常是否统一处理。第二你懂不懂电商的核心流程。商品 SPU/SKU 怎么设计购物车怎么算库存订单状态怎么流转支付回调怎么处理这些是商城系统的灵魂也是答辩时老师最喜欢追问的地方。第三你懂不懂小程序端的特殊性。微信小程序的登录不是传统的账号密码它有自己的一套 wx.login code 换 session 的机制手机号获取有专门规范底部 TabBar、顶部导航栏高度这类细节虽然不起眼但能看出你是否真的跑过真机调试还是只在模拟器里看过效果。说白了这个题目不是让你“做一个网页版的淘宝”而是让你用微信小程序这个载体把 Java 后端能力完整地串起来。1.2 功能清单别一上来就写代码我做项目的习惯是先列功能清单再画页面草图最后才是动手写代码。很多同学跳过前两步直接开写结果写到一半发现表结构不对回头改起来极其痛苦。一个能满足答辩需求的“首饰商城系统”至少应该包含以下功能模块模块功能点说明用户端小程序微信登录、手机号绑定、个人中心登录是电商的基础个人中心展示订单入口商品模块商品列表、商品详情、分类筛选、搜索首饰商品需要体现材质、克重、规格等属性购物车加入购物车、修改数量、删除、批量结算购物车是订单的前置步骤注意库存校验订单模块确认订单、提交订单、订单列表、订单详情订单状态至少要有待付款、已付款、已发货、已完成、已取消管理端后台商品管理、分类管理、订单管理、用户管理后台可以用 Web 页面也可以用小程序管理端建议用 Web支付模块微信支付下单、支付回调、退款可选毕设阶段可以用模拟支付代替真实支付但流程要完整这里我特别想说一下“管理端”。有的同学觉得小程序商城只要前端部分就够了后台随便拿数据库手动改数据。这不行。导师一定会问“你的商家怎么上架商品”“订单怎么发货”所以管理端是必须的。考虑到工作量管理端做成一个简单的 Web 页面Vue Element UI 或者直接用 Thymeleaf 模板都行重点在后端接口的一致性。2. 技术选型与工程结构设计2.1 技术栈选择为什么是这套组合先说选型这是毕设文档里必须写清楚的部分也是答辩老师一定会看的部分。前端小程序端原生微信小程序。不是不能用 uni-app但原生小程序有一个最大优势——它能让老师一眼看出你对微信小程序的 API 是熟悉的而不是套了一个跨端框架来糊弄。原生小程序的 WXML、WXSS、JavaScript 语法本身就很简单学习成本不高调试也直接。后端Spring Boot MyBatis Plus MySQL。这个组合在目前的 Java 毕设里几乎是事实标准了。Spring Boot 负责提供接口和依赖管理MyBatis Plus 负责数据库操作而且它有一个非常实用的能力根据实体类自动生成建表 SQL这在毕设阶段能省下大量手工维护数据库脚本的时间。具体来说可以用 MyBatis Plus 的TableInfoHelper.initTableInfo配合MybatisSqlRunner或者在启动阶段用ISqlRunner执行 DDL把实体类上的TableName、TableField注解映射成对应的表结构。虽然生产环境不建议这么干但在演示阶段这个“自动化”本身就是加分项。管理端Vue 2 Element UI 或 Spring Boot Thymeleaf。如果时间紧张我建议直接用 Thymeleaf Bootstrap前后端不分离写起来快逻辑也简单。如果时间充裕用 Vue 会显得更现代但要注意跨域、打包等问题会增加不少工作量。选型背后的逻辑很简单你要在有限的时间内完成一个“看起来完整、说起来清楚”的项目而不是追求技术栈的新奇程度。用主流技术遇到问题好查资料答辩时老师也认可。2.2 后端分层与数据库设计的关键决策工程结构上我推荐按这种分包方式com.example.jewelry ├── controller # 接口层只做参数接收和结果封装 ├── service # 业务逻辑层核心判断都在这 ├── mapper # 数据访问层MyBatis Plus 的 Mapper 接口 ├── entity # 实体类和数据库表一一对应 ├── dto # 数据传输对象接收前端参数、返回前端数据 ├── vo # 视图对象给前端展示的字段 ├── config # 配置类如拦截器、全局异常处理 ├── common # 通用类如统一返回结果、状态码、工具类 └── utils # 工具类如 JWT 工具、订单号生成分包的核心原则是Controller 里不写业务逻辑Service 里不写 SQLMapper 只管数据访问。很多同学喜欢在 Controller 里直接调用 Mapper代码量确实少但答辩时老师一翻项目就露馅了。分层清晰不仅是给老师看的也是你自己后期维护的基础。再讲数据库设计。商城系统的表不用太复杂但几张核心表的关系必须理清-- 用户表 CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, openid VARCHAR(64) UNIQUE, -- 微信 openid nickname VARCHAR(64), avatar VARCHAR(255), phone VARCHAR(20), create_time DATETIME ); -- 商品表SPU CREATE TABLE product ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(128), category_id BIGINT, -- 分类外键 main_image VARCHAR(255), detail_images TEXT, -- JSON 数组字符串 description TEXT, status TINYINT, -- 上架/下架 create_time DATETIME ); -- 商品规格表SKU CREATE TABLE product_sku ( id BIGINT PRIMARY KEY AUTO_INCREMENT, product_id BIGINT, -- 关联商品 spec VARCHAR(128), -- 如 金重5g 圈口16号 price DECIMAL(10,2), stock INT ); -- 购物车表 CREATE TABLE cart_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, sku_id BIGINT, quantity INT, checked TINYINT, create_time DATETIME ); -- 订单表 CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(64) UNIQUE, -- 业务订单号 user_id BIGINT, total_amount DECIMAL(10,2), status TINYINT, -- 状态机 receiver_name VARCHAR(64), receiver_phone VARCHAR(20), receiver_address VARCHAR(255), pay_time DATETIME, create_time DATETIME ); -- 订单明细表 CREATE TABLE order_item ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_id BIGINT, product_id BIGINT, sku_id BIGINT, product_name VARCHAR(128), spec VARCHAR(128), price DECIMAL(10,2), quantity INT );这里有两个容易犯的错误我重点提醒一下第一订单金额不要从购物车传到后端就直接用后端必须根据 SKU 价格重新计算一遍否则用户改个前端参数就能“低价购买”这是红线问题。答辩时老师很可能故意问“金额怎么保证正确”。第二库存扣减时机要放在“提交订单”时而不是“加入购物车”时。用户加购但不下单库存不应该变化只有订单提交成功才进行库存扣减。扣减时用UPDATE product_sku SET stock stock - #{quantity} WHERE id #{skuId} AND stock #{quantity}通过 SQL 条件判断避免超卖而不是先在 Java 里查出来再判断。2.3 通用能力分页、鉴权、异常处理的提前规划这三个“通用能力”很多人会忽略但恰恰是答辩时的高频考点。分页商品列表不可能一次性查出所有记录。MyBatis Plus 自带分页插件加一个MybatisPlusInterceptor配置即可。前端小程序用onReachBottom触底加载下一页这是小程序端的标准操作。鉴权小程序端每一个需要用户身份的接口都应该携带 token。登录流程拿到 token 后后续请求统一放在 header 里。后端用一个拦截器HandlerInterceptor统一校验白名单之外的接口必须登录才能访问。这样设计的好处是你不需要在每个 Controller 里手写“判断是否登录”代码干净也好讲。异常处理用RestControllerAdvice做一个全局异常处理类分别处理业务异常如库存不足、参数校验异常、系统异常。规范地返回{code: 500, message: 库存不足}而不是让前端收到一段乱七八糟的堆栈信息。这些通用能力实际上是在帮你把项目的“下限”抬高。3. 核心模块实现要点从登录到下单3.1 微信登录与手机号授权小程序身份体系怎么搭小程序的登录逻辑和传统 Web 完全不同很多人第一次做都会懵。我来理一下流程用户打开小程序前端调用wx.login()获取一个临时code把这个 code 发给后端。后端拿着 code、appid、appsecret 去请求微信的接口换回来openid和session_key。openid 是用户在当前小程序下的唯一身份标识。后端查数据库如果有这个 openid 就直接登录没有就注册一个新用户。然后后端生成一个自定义 token推荐用 JWT返回给前端前端把 token 存进wx.setStorageSync。后续请求携带这个 token后端通过解析 JWT 得到用户 ID。写清楚这段逻辑是答辩的“送分题”因为它体现的是你对微信生态登录机制的真实理解而不是随便用个账号密码表糊弄。再说手机号获取。微信官方要求“获取手机号”必须通过button open-typegetPhoneNumber触发用户主动点击授权。后端通过前端传来的code换取手机号但要注意2023 年以后微信将手机号快速验证组件调整为付费接口个人主体小程序无法直接调用。所以毕设阶段我的建议是保留这个入口但用模拟数据处理。也就是前端仍然用getPhoneNumber触发授权流程后端收到后记录一个“已授权手机号”的状态具体号码可以来自一个模拟回调或者干脆让用户在个人中心手动填写。你在论文里注明“真实环境需要企业主体及开通相关权限”这就够了。3.2 商品展示与 SKU 设计首饰商品的特殊性首饰类商品和普通商品最大的区别在于它有很多“规格”维度。黄金首饰要区分克重、圈号项链要区分链长戒指要看手寸。如果只设计一个商品表加一个price字段那“同款不同圈号不同价格”就根本无法实现。所以要拆 SPU 和 SKU 两层。SPU 是商品抽象比如“足金复古花戒”SKU 是具体规格比如“金重3.5g 圈号12号 价格3299”。前端商品详情页展示 SPU 信息同时加载该商品下所有 SKU 列表用户选择规格后前端展示对应 SKU 的价格和库存。加入购物车时传的是skuId和数量而不是productId和数量。这样做的好处很直接订单明细和购物车都只关联 SKU价格锁定在 SKU 上从源头保证价格一致。答辩时你讲出“SPU/SKU 分离设计”这几个字老师就会觉得你确实是设计过电商系统的而不是只会抄代码。3.3 购物车与订单状态机电商系统的骨架购物车模块在实现上要注意一个细节每次加购、改数量前端都要发请求给后端后端做库存校验而不是纯粹在前端计算。购物车表用user_id sku_id做唯一索引如果已经存在就累加数量否则插入新记录。批量结算时前端传一个cartItemIds数组后端遍历校验库存和价格然后生成订单。订单模块是整个系统最核心的部分因为它涉及状态流转。我的设计是五态模型待付款(0) - 已付款(1) - 已发货(2) - 已完成(3) 待付款(0) - 已取消(4)订单状态更新不能随意跳转。比如“待付款”只能变成“已付款”或“已取消”“已付款”只能变成“已发货”。这里我建议用一个状态枚举每次更新时做前置状态校验public enum OrderStatus { WAIT_PAY(0, 待付款), PAID(1, 已付款), SHIPPED(2, 已发货), FINISHED(3, 已完成), CANCELLED(4, 已取消); private final int value; // 构造方法、getter... }更新 SQL 里加上WHERE status #{expectStatus}这样即使并发请求过来也不会把状态改乱。答辩时能讲清楚状态机的“前置校验”比你在答辩 PPT 里放十张架构图都有说服力。3.4 支付与退款流程的实现思路真实对接微信支付需要商户号、API 证书、回调域名等一堆前置条件学生个人主体基本拿不到。所以这里我建议做“模拟支付 预留真实支付接口”的思路。具体做法前端“去支付”按钮调用后端的支付接口后端生成一笔模拟支付记录然后直接调用支付成功回调逻辑——对应一个OrderService.paySuccess(orderNo, payNo, amount)方法。这样做的价值是你的代码结构完全按照真实微信支付来设计回调逻辑、幂等校验防止回调重复处理导致状态覆盖、金额校验都有真实场景的考虑。未来如果有了商户号只需要把“模拟支付”部分替换成真实的wx.requestPayment参数获取即可。退款逻辑同理管理端发起退款后端更新订单状态为已退款并记录退款流水。这块在毕设里属于“可选增强”但不建议完全不做哪怕只写一个接口也能说明你考虑到了售后环节。4. 避坑实录与常见问题排查4.1 高频问题速查表这部分是真正从实际调试中“踩”出来的经验。很多问题不是逻辑复杂而是细节太隐蔽我把最常见的问题整理成一个表格你做到时遇到直接对照现象原因解决办法wx.request 请求报 400域名没有在小程序后台配置或本地调试没开“不校验合法域名”开发工具里勾选“不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书”真机调试需在后台配置 request 合法域名登录接口报 appid 或 secret 错误appid、secret 配置错误或使用的是测试号检查小程序后台的 AppID 和 Secret 是否一致注意 Secret 只能查看一次真机上图片加载不出来模拟器正常图片是本地路径或后端图片域名未配置白名单图片地址必须为 HTTPS 网络地址且域名需在小程序后台配置为“downloadFile 合法域名”订单状态显示不对状态流转没有做前置校验或前后端状态枚举不一致统一以后端状态枚举为准前端只做展示映射提交订单后库存没减少提交订单和库存扣减没放在同一个事务里Service 方法加Transactional库存扣减失败要回滚订单微信登录 code 换 session 偶尔失败没有处理 code 失效的重试逻辑code 一次性有效且有效期短失败时前端重新wx.login获取新 code优惠价或积分功能金额对不上前端传金额到后端后端没有重新计算后端必须基于数据库中的 SKU 价格和数量重算订单金额小程序顶部导航栏高度不对不同机型胶囊位置不同用wx.getMenuButtonBoundingClientRect()获取胶囊位置再根据wx.getWindowInfo()的系统状态栏高度计算不要写死 44px管理端跨域报错后端未配置 CORSSpring Boot 里加WebMvcConfigurer配置跨域放行这里我想单独说一下“顶部导航栏高度”这个问题。小程序页面如果是自定义导航栏有些商城类小程序为了好看会自定义顶部样式那它的高度不能写死。不同机型的状态栏高度不同普通 Android 是 20~24pxiPhone X 及以上是 44px 左右但胶囊按钮的位置也随机型变化。正确做法是在app.js的onLaunch里计算一次存到globalDataconst windowInfo wx.getWindowInfo() const menuInfo wx.getMenuButtonBoundingClientRect() const navBarHeight (menuInfo.top - windowInfo.statusBarHeight) * 2 menuInfo.height拿到这个值之后所有自定义导航栏的页面都用{{navBarHeight}}作为高度。这个细节虽然小但真机调试时一旦显示错位观感极差答辩演示也会减分。4.2 答辩时最容易被抓的五个问题我参与过一些毕设答辩的旁听发现老师翻来覆去问的就是这几个方向你提前准备好就完全不慌。问题一你的登录是怎么实现的别只回答“调用了 wx.login”。要讲清楚前端拿 code 给后端后端用 code appid secret 换 openid查库若无则新增用户然后签发 token前端后续请求带 token后端拦截器校验。能说出 openid 和 session_key 的区别就更稳了。问题二如果用户恶意篡改下单金额怎么办回答要点后端不信任前端传的金额订单金额一定是从数据库的 SKU 价格实时计算得出只把商品 ID/SKU ID 和数量作为入参。另外购物车中的勾选状态也以后端数据为准。问题三你的数据库是怎么设计的为什么这么设计讲清楚核心表用户表、SPU 表、SKU 表、购物车表、订单表、订单明细表。强调为什么订单明细要冗余商品名称、价格快照——因为商品价格或名称后来可能改变但订单历史必须保持原样。问题四库存超卖怎么处理先说结论用数据库条件更新stock quantity保证原子性而不是先查再改。这样即使两个用户同时下单数据库层面也会保证只有一个成功。问题五你这个项目有什么不足这是个“送命题”也是“送分题”。千万不要说“没有不足”。可以说支付模块目前是模拟实现真实上线需要企业资质接入微信支付图片资源存储在本地生产环境应接入 OSS/CDN安全方面可以使用更完善的加密策略。这种回答反而会让老师觉得你有工程思维。5. 加分项与四周进度规划5.1 三个低成本高性价比的扩展点如果你时间充裕想让自己从“平均水平”里跳出来我推荐三个扩展方向按性价比排序第一个是快递单号与物流模拟。订单发货后填入物流单号用户端订单详情展示物流轨迹。不需要对接真实物流 API用一个独立表记录几个固定节点已揽收、运输中、派送中、已签收即可。这在答辩演示时非常直观因为老师自己买过东西一看就懂。第二个是管理端数据概览。管理员登录后台首页展示总销售额、今日订单数、商品总数等统计卡片。不用做复杂的 BI 报表用几个简单的 SQL 聚合查询就能实现比如SELECT COUNT(*) FROM orders WHERE status 2 AND create_time BETWEEN ? AND ?。视觉效果好而且也算是一个“数据分析”亮点。第三个是服务通知或订阅消息。下单成功后通过微信订阅消息给用户推送“订单支付成功通知”。虽然需要申请模板但毕设阶段也可以只写后端对接接口的逻辑把推送结果记录到日志里。这能体现你对微信生态消息能力的理解。这三个点都不复杂但在答辩 PPT 的“功能亮点”部分比“我会增删改查”有说服力得多。5.2 四周时间规划参考毕设时间卡的紧我按大多数人的实际节奏排个四周计划阶段时间任务第一周第1-2天完整阅读题目要求写出功能清单画出小程序端页面原型图第一周第3-4天后端工程搭建引入 Spring Boot MyBatis Plus配置数据库连接和分页插件第一周第5-7天完成用户登录接口、商品分类和商品列表接口第二周第8-10天完成商品详情、SKU 查询、购物车增删改查接口第二周第11-12天完成订单提交、订单列表、订单详情、状态流转接口第二周第13-14天小程序端框架搭建TabBar、页面路由、公共请求封装第三周第15-17天小程序端对接登录、商品列表、商品详情、购物车第三周第18-19天小程序端对接订单流程、支付模拟第三周第20-21天管理端 Web 页面商品管理、订单管理、数据概览第四周第22-23天联调修复前后端交互问题第四周第24-25天真机调试处理导航栏、图片加载、授权等兼容问题第四周第26-28天写毕业论文、整理答辩 PPT、准备演示录屏这个计划的核心是天然地把后端先做完再做前端对接最后统一联调。很多同学喜欢并行开发结果前后端各做各的对接时发现接口参数对不上浪费时间。你按这个顺序来至少不会出现“前端写完了后端还没开始”的悲剧。最后一个实在建议不管你的项目做到哪一步一定提前录一个演示视频。答辩现场网络不稳定、电脑接投影仪出问题、小程序加载超时都是常见状况有一个 3~5 分钟的录屏视频你就能在关键时刻保住演示环节的分数。微信开发者工具自带的录屏功能就能用画质也足够清晰。我在实际辅导学生时发现能把这套系统从头到尾讲清楚、并且真心理解每一行代码作用的人答辩成绩普遍都在良好以上。写代码不难难的是带着思考去写。希望这篇文章能帮你把“首饰商城系统”这个题目真正做明白而不是交一个自己都不了解的代码壳子。
阅读完成 · 觉得有帮助?
咨询建站