简介:鲜花销售微信小程序毕业设计完整项目包,面向需要完成小程序类毕设或课程设计的高校学生。资源包含用户端微信小程序与Java后端管理平台,实现首页、个人中心、用户/商家管理、鲜花信息与分类管理、管理员及系统管理等核心模块,后端基于SSM框架(Spring、SpringMVC、MyBatis),搭配MySQL 5.7数据库。压缩包共1341个文件,涵盖vue小程序页面、java后端代码、js交互逻辑、json配置、wxss/wxml样式结构以及sql数据库脚本等类型,整体大小约20.28MB,目录结构完整,便于直接导入开发工具(eclipse/idea、HBuilder X)运行调试。项目附带详细说明文档和答辩演示PPT,覆盖需求分析、数据库设计、功能实现与操作指南,可帮助快速理解前后端联调流程。目前已有85人学习参考,适合正在筹备毕业设计答辩或希望系统掌握小程序全栈开发流程的读者。
1. 鲜花销售微信小程序毕设:先看清这套完整前后端到底给你准备了什么
打开压缩包你会发现,它不是一个只能演示静态页面的 HTML 套壳,而是把微信小程序前端、后端服务、MySQL 数据库全部放进同一份工程。以鲜花销售微信小程序源码为例,这类项目在毕业设计里出现频率很高,因为业务链路足够完整:用户登录、商品分类、购物车、下单、订单列表,每一个环节都要前后端配合才能跑通。zip 里还带了 SQL 文件、说明文档和 LW 论文文档,意味着你拿到的是一套答辩级交付物,不是零散的页面片段。下面我会按拆结构、跑起来、调参数、排坑的顺序,把这份源码怎么用、哪些参数必须改、坑在哪一次说清。适合正在做小程序类毕设的同学,也适合想快速看懂一套商城小程序工程怎么组织的开发者。
2. 拆解源码结构:前端页面、后端接口与 MySQL 表是怎么咬合的
拿到 zip 先别急着导入微信开发者工具,先花十分钟把目录摸清楚,后面会少走很多弯路。一套典型的小程序毕设工程,通常包含三个部分:miniprogram 或 pages 目录放小程序前端;server 或 src 目录放后端 Java 工程;sql 或 db 目录放数据库脚本。如果这三块缺了任何一块,都不能叫"完整前后端"。
2.1 前端目录:pages、components、utils 各自在干嘛
前端大多是原生微信小程序,而不是 uniapp 或 Taro 工程,识别方法很简单:看目录里有没有 app.js、app.json、app.wxss 三个入口文件。原生工程的好处是结构直观,答辩时随便点开一个页面都能顺着生命周期讲下去。常见目录结构如下:
miniprogram/ ├── app.js ├── app.json ├── app.wxss ├── pages/ │ ├── index/ # 首页:轮播图+鲜花列表 │ ├── category/ # 分类:左侧分类右侧商品 │ ├── cart/ # 购物车:数量加减、选中结算 │ ├── order/ # 订单:订单列表与状态tab │ └── user/ # 个人中心:登录入口、地址管理 ├── components/ │ ├── flower-card/ # 商品卡片组件 │ └── number-input/ # 数量步进器组件 └── utils/ ├── config.js # 全局接口地址、AppID等配置 └── request.js # wx.request 封装pages 下每个目录就是一个页面,标准配置是四个文件:.js 写逻辑、.wxml 写结构、.wxss 写样式、.json 写页面配置。components 是复用模块,商品卡片在首页和分类页都会被引用,所以单独抽出来。utils/config.js 是你第一个要打开的文件,里面一般放着 BASE_URL(后端接口地址)、AppID、Secret 等全局常量。
这里最容易犯的错是只看页面不追数据流。你要在脑子里形成一条链路:首页 index.js 在 onLoad 里调用某个请求方法,该方法从 utils/request.js 里调 wx.request,请求打到后端 /api/flower/list,后端查 MySQL 返回 JSON,前端 setData 渲染到 wxml。这套链路能完整讲清楚,答辩的基础分就到手了。
2.2 后端工程:controller、service、mapper 的分层与接口风格
后端绝大多数情况下是 Spring Boot + MyBatis 的组合,因为这一套在高校课程里覆盖面最广,老师也容易验证。工程目录按 controller、service、mapper 三层拆开,controller 负责接收前端请求,service 写业务逻辑,mapper 访问 MySQL。一个典型鲜花项目的接口清单大概长这样:
| 接口路径 | 方法 | 作用 | 前端页面 |
|---|---|---|---|
| /api/user/login | POST | 微信登录,返回 token | user / index 登录弹窗 |
| /api/flower/list | GET | 分页查询鲜花列表 | index |
| /api/flower/detail | GET | 查询鲜花详情 | index 详情 |
| /api/cart/list | GET | 查询当前用户购物车 | cart |
| /api/cart/add | POST | 加入购物车 | index 商品卡片 |
| /api/order/create | POST | 创建订单 | cart 结算 |
| /api/order/list | GET | 查询用户订单 | order |
Controller 的写法一般很薄,只做参数接收和结果包装。下面这段是一个典型的分页查询鲜花列表的控制器代码:
@RestController @RequestMapping("/api/flower") public class FlowerController { @Autowired private FlowerService flowerService; @GetMapping("/list") public Result list(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer pageSize) { PageBean<Flower> data = flowerService.pageFlower(page, pageSize); return Result.success(data); } }这段代码的逻辑是:前端传 page 和 pageSize,后端返回统一结构 Result,里面的 data 是包括总条数和当前页数据的对象。@RequestParam 带默认值,就算前端漏传参数也不会直接报错。Result 是自定义的返回体,一般包含 code、msg、data 三个字段,code 为 0 表示成功。答辩时如果老师问"为什么前端能拿到总页数",答案就在 PageBean 这个对象里。
后端还有一个容易被忽略的点:图片处理。鲜花商品必须展示图片,常见的做法是后端做一个文件上传接口 /api/file/upload,把图片存在本地的 upload 目录,数据库只存相对路径如 /upload/flowers/rose.jpg。这意味着前端展示时必须拼接 BASE_URL,后面避坑章节会专门讲。
2.3 MySQL 表设计:用户、商品、订单、购物车的字段与关系
数据库脚本一般在 sql 目录下,文件名类似 flower.sql 或 db_flower.sql。导入后通常有 6 到 8 张表,核心表有用户表、商品表、分类表、购物车表、订单表、订单明细表,另外还有轮播图表和地址表。以商品表为例,建表语句大致如下:
CREATE TABLE `t_flower` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category_id` int(11) DEFAULT NULL COMMENT '分类id', `name` varchar(100) NOT NULL COMMENT '鲜花名称', `cover` varchar(255) DEFAULT NULL COMMENT '封面图片', `price` decimal(10,2) DEFAULT NULL COMMENT '销售价格', `stock` int(11) DEFAULT '0' COMMENT '库存', `sales` int(11) DEFAULT '0' COMMENT '销量', `status` tinyint(1) DEFAULT '1' COMMENT '1上架 0下架', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;这张表是商城类项目最典型的设计:category_id 关联分类表,price 用 decimal 而不是 float,避免金额计算出现精度误差;status 用于上下架;sales 用于按销量排序。表与表之间的关系也很清晰:购物车表通过 user_id 关联用户、flower_id 关联商品,订单主表记录总金额和状态,订单明细表再记录每个商品的单价和数量。为什么要拆订单主表和明细表?因为一个订单可能包含多束花,主表存订单整体信息、明细表存每件商品,这样既能在订单列表页只查主表,又能在详情页展示明细。多数毕设项目不会建物理外键,而是在应用层维护关系,这样增删数据更灵活,答辩时也能解释清楚。
用户表最关键的字段是 openid,它是微信用户在小程序体系内的唯一标识。登录时后端拿前端传来的 code 去微信接口换 openid,再拿 openid 查用户表,查不到就自动注册一条新用户。注意 openid 不能暴露给前端,否则会有安全隐患,后端一般只把用户 id 和 token 返回给小程序端。
3. 本地跑起来:从 MySQL 导入到微信开发者工具出首页的完整步骤
这个项目不复杂,但环境配置步骤多,顺序错了就会看到前端请求一堆报错。我建议按"数据库 → 后端 → 前端"的顺序来,因为小程序首页一加载就会发请求,后端都没起来的话,前端只会得到一堆网络错误,容易误判为代码问题。
3.1 环境准备与导入顺序
需要准备的东西不多,都是高校实验室常见的版本。为了避免版本不兼容,下表是我跑这类工程时的推荐组合:
| 软件 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8 或 11 | Spring Boot 2.x 用 JDK 8 最稳 |
| Maven | 3.6+ | 用于下载依赖和打包 |
| MySQL | 5.7 或 8.0 | 5.7 不挑驱动,8.0 需要改时区参数 |
| IDEA | 2020 以上 | 社区版够用 |
| 微信开发者工具 | 稳定版 | 导入小程序工程用 |
顺序上的坑:如果你电脑上 MySQL 之前装过且没设对密码,后端连接失败是很常见的事。先跑一下mysql -u root -p确认能进,再启动后端。另外,确认 3306 端口没有被占用,Windows 上可以用 netstat -ano | findstr :3306 查,mac 上用 lsof -i:3306。
3.2 把 SQL 导入 MySQL 并改对连接参数
找到 sql 目录下的脚本文件后,打开命令行进入 MySQL,用 source 命令导入。这里要注意:脚本里如果带 CREATE DATABASE 语句,你不用先建库;如果没有,需要手动建一个同名的库再导入。
mysql -u root -p Enter password: 你的数据库密码 source /Users/你的路径/flower.sql; show databases; use flower_shop; show tables;执行 show tables 后如果能看到 t_user、t_flower 这些表,说明导入成功。接下来打开后端工程的 src/main/resources/application.yml,把数据库连接改成你本机的配置:
spring: datasource: url: jdbc:mysql://localhost:3306/flower_shop?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&characterEncoding=utf8 username: root password: 你的密码 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8这里几个参数值得记一下:serverTimezone=Asia/Shanghai 是 MySQL 8 的必填项,不加会报 Server returns invalid timezone;allowPublicKeyRetrieval=true 解决 MySQL 8 的 RSA 公钥获取报错;characterEncoding=utf8 防止存入的中文乱码。jackson 的时间配置决定返回给前端的日期格式,如果你发现订单时间显示一串时间戳,就是少了这两行。改完这些参数,数据库这步就算完成了。
3.3 后端启动:IDEA 里 Maven 构建与端口确认
后端工程用 IDEA 打开后,等右下角 Maven 把依赖下载完,找到启动类直接运行。启动类的名字通常是 Application 结尾,比如 FlowerApplication.java,上面有 @SpringBootApplication 注解。运行后看控制台输出,出现 Tomcat started on port(s): 8080 就表示后端起来了。
不习惯用 IDEA 的话,命令行也能跑,前提是本机装了 Maven 并且配了环境变量:
cd server mvn spring-boot:run启动成功后,先用浏览器或 curl 验证一个不需要登录的接口,确认后端真的能查数据库:
curl http://localhost:8080/api/flower/list如果返回 JSON 里有 List 数据,说明后端已经正常。如果返回 404,看看接口路径是否真的叫这个;如果报数据库连接错误,回头检查 3.2 节的 yaml 配置。后端端口不是 8080 也很正常,看控制台提示改成实际端口就行,改端口在 application.yml 里加一行 server.port。
3.4 小程序端导入与 AppID 配置
打开微信开发者工具,选择"导入项目",目录选到 miniprogram 或直接选工程根目录。这里有个细节:如果工具提示"不是小程序项目",看一下目录里有没有 app.json,没有就选到包含 app.json 的那一层。AppID 可以选择测试号,不需要注册正式小程序,点击导入即可看到首页。
导入后先别急着点编译,打开 utils/config.js 确认接口地址:
// utils/config.js const BASE_URL = 'http://localhost:8080' module.exports = { BASE_URL }如果后端端口改过,这里要同步改。然后点击编译,如果首页出现了鲜花列表,说明全链路已经通了;如果图片裂了或者首页空数据,大概率是接口地址、数据库数据或图片路径拼接的问题。另外,开发阶段必须在微信开发者工具的"详情 → 本地设置"里勾选"不校验合法域名、web-view(业务域名)",否则 wx.request 请求 http://localhost 会被拦截,报出 not in domain list。
4. 必调参数与联调联试:把登录、购物车、下单串成一条线
项目跑到首页能出数据只是第一步,毕设答辩最常问的是登录和下单,这两个链路也是前后端参数最容易对不上的地方。这一章把三个核心链路依次过一遍。
4.1 登录链路:wx.login 到 code2Session 到 token
登录是小程序项目里最绕的环节,因为它涉及三次网络请求:小程序 → 微信接口 → 后端。前端先调 wx.login 拿到临时 code,再把 code 发给后端;后端拿着 code 去微信的 jscode2session 接口换 openid 和 session_key;后端用 openid 查用户表,生成 token 返回给前端。前端把 token 存进 storage,后续所有请求都带上它。
前端的登录唤起代码一般长这样:
// pages/user/user.js 登录按钮事件 handleLogin() { wx.login({ success: (res) => { wx.request({ url: BASE_URL + '/api/user/login', method: 'POST', data: { code: res.code }, success: (res2) => { if (res2.data.code === 0) { wx.setStorageSync('token', res2.data.data.token) wx.setStorageSync('userInfo', res2.data.data.userInfo) wx.showToast({ title: '登录成功' }) } else { wx.showToast({ title: res2.data.msg, icon: 'none' }) } } }) } }) }这段代码的逻辑是:wx.login 的 res.code 有效期只有五分钟且只能用一次,所以要立刻发给后端。后端返回的 token 是自定义的,常见做法是 UUID 或 JWT,存到 storage 里。注意 login 后不能直接在 success 里拿 openid,微信官方早就改了,openid 只能由后端从 code 换。答辩时如果被问到安全设计,可以说"openid 不经过前端,由后端保存并用 token 标识用户"。
后端的核心代码主要是拼请求和查表,简化后如下:
public LoginInfo wxLogin(String code) { String url = "https://api.weixin.qq.com/sns/jscode2session" + "?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code"; String body = HttpUtil.get(url); // 返回JSON String openid = JSONUtil.parseObj(body).getStr("openid"); User user = userMapper.findByOpenid(openid); if (user == null) { user = new User(openid); userMapper.insert(user); } return new LoginInfo(user, UUID.randomUUID().toString()); }这里用到的 HttpUtil 和 JSONUtil 来自 hutool 工具包,如果你的项目没引入,就改成 HttpClient + fastjson 的组合,效果一样。appid 和 secret 要改成你自己小程序账号下的值,测试号也能拿到。如果调用微信接口返回 errcode,最常见的是 40013(appid 错误)和 40125(secret 错误),去小程序后台核对一下。还有一点:code 使用后立即失效,后端要避免重复请求微信接口,否则第二次会报 code been used。
4.2 请求封装:baseUrl、token 注入、状态码处理
商城类小程序几乎每个页面都要发请求,如果每个页面都写一遍 wx.request,代码会非常冗余。所以源码里基本都会有一个封装好的 request.js,把 BASE_URL 拼接、token 注入、状态码统一处理都做掉。常见的封装长这样:
// utils/request.js const request = (url, method = 'GET', data = {}) => { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + url, method, data, header: { 'Content-Type': 'application/json', 'token': wx.getStorageSync('token') }, success: (res) => { if (res.data.code === 0) { resolve(res.data.data) } else if (res.data.code === 401) { wx.removeStorageSync('token') reject(res.data.msg) } else { reject(res.data.msg) } }, fail: (err) => reject(err) }) }) } module.exports = request这个封装用 Promise 把 wx.request 包了一层,页面里就可以用 async/await 写业务,不用陷入回调地狱。header 里放 token 是前端传身份标识最常用的方式,后端拦截器从 header 里取出校验。注意这里的字段名"token"必须和后端代码一致,如果后端用的是"Authorization"或"x-token",前端不改字段就会一直 401。另外 res.data.code 的判断要和后端 Result 一致,有的项目用 200 而不是 0,需要对上。
使用封装后,页面里的调用就简洁多了:
const list = await request('/api/flower/list?page=1&pageSize=10') this.setData({ flowerList: list.pageData })这种写法答辩演示很方便,也方便你定位问题:如果某个页面数据为空,先看 Network 面板里这个请求有没有发出去、返回什么,再决定是前端问题还是后端问题。
4.3 购物车与下单:库存校验和订单号生成
购物车接口相对简单,就是把商品 id、数量、用户 id 插到购物车表。真正有业务含量的是下单,它至少要做四件事:校验商品是否上架、校验库存够不够、生成订单号、扣减库存并创建订单主表和明细表。下单接口的事务处理是答辩的高频问题,老师看到你用了 @Transactional,基本会认为你理解了事务概念。
订单号生成代码一般是这样的:
// 后端生成订单号 String orderNo = "FL" + System.currentTimeMillis() + String.format("%04d", new Random().nextInt(10000));这段代码用时间戳加四位随机数拼出订单号,FL 前缀代表 Flower。时间戳保证不同毫秒级的订单号不重复,随机数防止同一毫秒并发时撞号。正式项目里会用雪花算法或者数据库序列,但毕设规模用这种拼接完全够,答辩时能讲清楚为什么不直接按自增 id 暴露给用户就行。
下单接口的典型逻辑如下:
@Transactional public String createOrder(OrderCreateParam param) { Flower flower = flowerMapper.selectById(param.getFlowerId()); if (flower == null || flower.getStatus() != 1) { throw new BizException("商品已下架"); } if (flower.getStock() < param.getQuantity()) { throw new BizException("库存不足"); } // 扣减库存 flowerMapper.reduceStock(param.getFlowerId(), param.getQuantity()); // 生成订单主表 Order order = new Order(); order.setOrderNo(generateOrderNo()); order.setUserId(param.getUserId()); order.setTotalPrice(flower.getPrice().multiply(BigDecimal.valueOf(param.getQuantity()))); order.setStatus(0); orderMapper.insert(order); // 生成订单明细 OrderItem item = new OrderItem(); item.setOrderId(order.getId()); item.setFlowerId(flower.getId()); orderItemMapper.insert(item); return order.getOrderNo(); }这里的逻辑用到了几个关键细节:库存扣减用 update 语句在数据库层面执行,不是先把库存查出来在 Java 里减完再写回去,避免超卖;金额计算用 BigDecimal 而不是 double;加 @Transactional 让订单主表、明细表和库存扣减在同一次事务里,任何一个失败都整体回滚。前端拿到 orderNo 后跳转订单详情或提示支付成功,这就是一套完整的闭环。订单状态一般用 0、1、2、3 表示待付款、待发货、已发货、已完成,订单列表页按状态 tab 筛选时就是查这个字段。
5. 避坑记录:鲜花销售小程序跑通前最常踩的五个坑
这一章是我把这些项目从零跑到通的过程里,遇到最多的问题汇总。基本都是环境、路径、参数不一致导致的,以及几条看似不起眼却浪费一晚上的经验。
5.1 图片 404 或一片灰:首页商品图全裂了
现象:小程序首页能显示商品名和价格,但所有图片都是灰块,打开调试器看到 image 请求状态是 404 或 failed。原因不是图片文件丢了,而是数据库里存的是相对路径 /upload/flowers/rose.jpg,前端直接拿这个路径给 image 组件加载,变成了请求"本地小程序的 /upload 目录",自然找不到。解决方式是在前端拼接后端地址前缀,通常在 utils 里导出一个静态资源地址变量:
// utils/config.js const BASE_URL = 'http://localhost:8080' const IMG_URL = BASE_URL + '/upload' module.exports = { BASE_URL, IMG_URL }页面里这样用:
<image src="{{IMG_URL}}{{item.cover}}" mode="aspectFill"></image>注意 mode="aspectFill" 也是商品图常用的属性,能让图片在固定尺寸的框里不变形地裁切展示。如果后端返回的字段已经是全路径,也就是以 http 开头,前端就不要再拼前缀,否则会出现双协议头。判断标准很简单:打印一下数据里的 cover 字段,以 / 开头就拼接,以 http 开头直接用。
5.2 登录永远失败:token 字段名对不上导致连环 401
现象:前端调用 /api/user/login 明明返回了 token,但紧接着的 /api/cart/list 等请求全部 401,或者登录接口直接报参数错误。原因一般是两个项目之间约定不一致:后端拦截器从 header 里取的是 Authorization,而前端 request.js 里写的是 token。解决是全局搜索统一字段,前后端各改一处:
// 前端 request.js 的 header 中修改 'Authorization': wx.getStorageSync('token')// 后端拦截器读取时 String token = request.getHeader("Authorization"); if (token == null || token.isEmpty()) { return "未登录"; }还有一个隐蔽情况:拦截器写了但只对部分路径生效,比如 /api/user/login 被排除了,但 /api/flower/list 没有排除且必须登录,你会发现首页的数据一会儿有一会儿没有。建议排查时先看拦截器的 exclude 名单,把公开接口列进去,其余接口统一鉴权。
5.3 MySQL 8 一启动就报时区错:Server returns invalid timezone
现象:后端启动时控制台报 com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'Öйú±ê׼ʱ¼ä',一大串乱码。原因 MySQL 8 默认时区不是 UTC+8 而 JDBC 驱动会在连接时检查,配置里没给 serverTimezone。解决就是数据源 url 加参数,前面 3.2 写过,这里再强调一下完整写法:
jdbc:mysql://localhost:3306/flower_shop?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8&allowPublicKeyRetrieval=true另外,如果项目用的 MySQL 驱动版本是 5.x 而连的是 MySQL 8,会额外报 Public Key Retrieval is not allowed,解决方案就是加上 allowPublicKeyRetrieval=true。这两个参数对刚装 MySQL 8 的同学来说是必加的,不改基本起不来。
5.4 手机预览白屏:真机连不上电脑上的后端
现象:开发工具里一切正常,但用手机扫码预览时首页空白、接口超时。原因手机上访问的是 localhost:8080,而 localhost 指向的是手机自己,不是电脑。解决是改用电脑的局域网 IP,并让手机和电脑处于同一 Wi-Fi。先查本机 IP,mac 用 ifconfig,Windows 用 ipconfig,找到 192.168 开头的地址,把 utils/config.js 里的 BASE_URL 改掉:
const BASE_URL = 'http://192.168.1.103:8080'同时要注意 Windows 防火墙可能会拦截 8080 端口的入站请求,需要在防火墙设置里放行或临时关闭。还有一个容易漏的点:开发工具详情里"不校验合法域名"的开关,手机预览时如果没打开调试,照样会拦截 http 请求。在手机上,小程序右上角胶囊菜单里打开"开发调试"再重新扫码,很多请求类问题会消失。
5.5 新增商品后列表不刷新:order by 不够明确
现象:后台或 SQL 里新插入一条鲜花,前端列表还是老数据,刷新也没变化。原因可能有两个:一是列表查询 SQL 没有加明确排序,MySQL 对相同数据的返回顺序不稳定,新数据可能排到了中间位置,前端分页缓存不更新导致看不到。解决是给列表查询加上明确排序:
SELECT * FROM t_flower WHERE status = 1 ORDER BY sales DESC, id DESC LIMIT #{pageSize} OFFSET #{offset}二是前端 onLoad 和 onShow 的逻辑问题:从详情页返回首页,onLoad 不会重新触发,如果数据只在 onLoad 里加载,就会显示旧数据。建议把加载函数放到 onShow 里执行,每次页面获得焦点都刷新一遍列表,这样演示时体验也好。改成 onShow 后注意别在每次弹窗关闭时也触发,避免请求过多。
这五条是最影响"能不能跑起来"的坑,另外像端口被占用、Maven 依赖下载慢这类环境问题,解法比较直接:端口占用用 netstat/lsof 查占用进程然后换端口,依赖慢就配 Maven 镜像源。把上面的字段、时区、域名三个大方向查一遍,一个花店小程序基本就稳了。
6. 把项目改成答辩能讲的样子:三个验证技巧与一个交付习惯
项目能跑起来之后,最值得花的不是加功能,而是把演示流程做顺。第一个技巧是善用微信开发者工具的 Network 面板。答辩演示时,老师看到的不应该只是一个能点的页面,而应该是一整套可以讲述的请求链条。打开首页,Network 面板会把每次 wx.request 请求按时间顺序列出来,login 先返回 token,flower/list 接着返回商品数据。按着这个请求顺序讲,就能把"前端如何登录、后端如何鉴权、数据如何流动"全部串起来,比背稿更有说服力。
第二个技巧是准备一组 Postman 接口测试。把登录、商品列表、购物车、创建订单这几个接口的请求和响应保存下来,万一现场微信开发者工具突然抽风,直接打开 Postman 重放接口也能完整展示后端逻辑。Postman 里重点关注返回结构 code、msg、data 的一致性,这也是老师经常检查的地方。
第三个技巧是把订单状态流转整理成一张小表,放在说明文档的首页,答辩时可以按表格讲业务闭环:
| 状态值 | 状态名 | 触发时机 | 后续动作 |
|---|---|---|---|
| 0 | 待付款 | 下单成功 | 用户支付(模拟) |
| 1 | 待发货 | 支付成功 | 管理员发货 |
| 2 | 已发货 | 发货操作 | 用户确认收货 |
| 3 | 已完成 | 确认收货 | 订单结束 |
一个交付习惯:交源码前,重新导出一次干净的数据库脚本,并且把自己测试产生的脏数据删干净。我以前就吃过亏,压缩包里的 SQL 带着一堆"测试花束123"的数据,老师导入后页面看起来乱七八糟,印象分直接降。正确的导出方式是先清理再导出:
mysqldump -u root -p flower_shop > flower_clean.sql导出后打开文件检查有没有本机绝对路径、有没有测试账号的敏感数据,再写一个 README 说明默认登录方式、后端端口、数据库账号密码。这一套做完,哪怕答辩前一周才跑通,也会显得项目非常完整。希望帮到你。
本文还有配套的精品资源,点击获取