☰
Java商城小程序源码实战:linjiashop跑通与避坑指南
2026/9/28 5:01:30 网站建设 项目流程

简介:这是一份基于 Java 开发的轻量级单商户商城系统源码,适合初中级 Java 开发者学习电商项目完整流程,也可作为小型商家搭建线上销售平台的基础。项目以 Spring Boot 为核心,结合 MyBatis 数据映射、Thymeleaf 模板渲染、Redis 缓存与 Maven 工程管理,覆盖商品、订单、用户、支付等电商核心模块,同时体现微服务拆分、微信小程序接口对接、OAuth2 登录鉴权、Docker 容器化部署、Prometheus 监控与日志采集等常见工程化实践。资源为 ZIP 压缩包,整体约 13.2MB,目前已有 166 人学习下载。通过源码目录与核心代码,可逐步看懂 MyBatis 的 SQL 映射写法、Redis 缓存策略、Thymeleaf 页面渲染方式、小程序端 API 调用流程,以及支付、订单等核心模块的数据表设计与状态流转;对于希望入门 Java 电商开发、理解前后端交互或进行二次改造的开发者,均有不错的参考价值。

1. 这项目值得跑吗:一个 Java 商城小程序源码能给你什么

linjiashop 是一个典型的 Java 后端商城项目,microapp 是它的微信小程序前端目录。你拿到手的是一个带完整下单链路、后台管理、数据库初始化脚本的源码包,不是那种只有几个页面骨架的演示项目。这套东西适合两类人:一类是拿它做毕设或课设,需要快速出一个能演示的商城系统;另一类是工作一两年、想补电商基础的后端开发,想搞明白“用户在小程序里下单,后端到底经历了什么”。我的判断是它比想象中重,跑通过程会逼你补齐 MySQL、Redis、Maven、微信开发者工具和支付回调的全套常识。这篇我会按自己复现时的顺序写,从源码结构讲到数据表关系,再到本地启动和踩坑,尽量让代码和配置都能直接抄。

2. 拆开 linjiashop 源码:microapp 小程序与 Java 后端的模块地图

拿到源码包先别急着启动,先花十分钟把目录结构读明白。这个项目名里的 master 是 Git 主干分支名,打包时被带进了目录名,microapp 则是小程序端代码的存放位置。这类开源商城大多采用 maven 多模块单体架构,linjiashop 的实际目录可能因为版本不同略有出入,但模块边界通常一致:一个给小程序提供接口的后端模块、一个后台管理模块、一个放通用工具和数据库脚本的核心模块。

2.1 先看懂目录结构:master、microapp 和几个 maven 模块的关系

我见过的大多数同类项目会按下面这样的方式组织:

linjiashop-master/ ├── linjiashop-admin # 后台管理接口与页面资源 ├── linjiashop-api # 小程序端接口模块 ├── linjiashop-core # 通用工具、常量、异常处理 ├── linjiashop-db # 数据库脚本与实体映射 ├── microapp # 微信小程序前端 ├── pom.xml └── sql/

先说 maven 模块的依赖方向。linjiashop-api 是你真正要关注的模块,小程序每个页面请求的接口都定义在这里;linjiashop-admin 是管理员用的后台,和 api 模块共享 core 与 db 的基础能力。db 模块通常放数据库初始化脚本和 MyBatis 的 mapper 接口,core 模块放 JWT 工具、统一返回体、分页封装这些与业务无关的东西。

microapp 目录里是原生微信小程序代码,注意它不是 uniapp 写的,所以你不需要装 HBuilderX,直接用微信开发者工具打开这个目录就可以编译。如果你之前用惯了 uniapp 那套“一套代码多端发布”的流程,回到原生小程序会有个适应期,页面逻辑在 Page 里,公共请求封装在 utils 目录,请求地址通常集中在一个 config.js 里。这个文件等会改后端地址时一定要找到。

2.2 商城主链路的数据表:会员、商品、订单、支付记录先建好关系

商城系统不管前端怎么变,后端核心永远是“谁、在什么时间、买了哪个商品、付了多少钱、订单现在什么状态”。linjiashop 这类项目的表结构大体围绕这四类数据展开,我按常见实现简化成下面的样式:

CREATE TABLE mall_member ( id BIGINT PRIMARY KEY AUTO_INCREMENT, openid VARCHAR(64) NOT NULL, nickname VARCHAR(64), phone VARCHAR(20), status TINYINT DEFAULT 1, created_at DATETIME ); CREATE TABLE mall_goods ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(128) NOT NULL, price DECIMAL(10,2) NOT NULL, stock INT NOT NULL DEFAULT 0, is_on_sale TINYINT DEFAULT 1, created_at DATETIME ); CREATE TABLE mall_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL, member_id BIGINT NOT NULL, total_amount DECIMAL(10,2) NOT NULL, status TINYINT NOT NULL DEFAULT 0, pay_time DATETIME, created_at DATETIME ); CREATE TABLE mall_pay_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL, transaction_id VARCHAR(64), amount DECIMAL(10,2), notify_time DATETIME );

member 表通过 openid 关联微信用户;goods 表是商品信息;order 表里的 status 是整个系统的核心状态机,0 待支付、1 已支付、2 已发货、3 已完成这类数值语义通常写死在常量类里;pay_record 表负责记录每一次支付回调结果,用来做对账。这四张表的关系其实很简单:member 下单产生 order,order 支触发 pay_record 写入,pay_record 反过来更新 order 状态。

这里有个容易忽略的点:订单金额 total_amount 不应该来自前端传参,而应该由后端根据商品单价和数量重新计算。很多二次开发的新手直接把前端传来的金额落到订单表,支付时又按这个金额请求微信支付,结果前端一改价格就出大问题。正确做法是后端查商品表价格重新算一遍,前端只能传商品 id 和数量。

2.3 改一处业务要从哪层动手:Controller、Service、Mapper 的职责边界

拿到源码后,你迟早会改业务,比如给商品加个标签、给订单加个状态。如果不知道从哪层下手,代码会越改越乱。这套项目的分层思路和主流 Spring Boot 项目一致:Controller 只负责收参数和回结果,Service 写业务规则,Mapper 操数据库。

@RestController @RequestMapping("/api/goods") public class GoodsController { @Resource private GoodsService goodsService; @GetMapping("/page") public PageResult<GoodsVO> page(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "10") int pageSize) { return goodsService.page(pageNum, pageSize); } }

Controller 层不要写业务判断,比如“库存不足就返回失败”这类逻辑必须放到 Service。原因是小程序端、后台管理端可能共用同一个 Service,如果业务规则写在 Controller,另一端调用时就得再写一遍,极容易写出两套不一致的判断。

Service 层通常长这样:

public interface GoodsService { PageResult<GoodsVO> page(int pageNum, int pageSize); GoodsVO detail(Long goodsId); Boolean reduceStock(Long goodsId, Integer count); }

reduceStock 这个方法名值得注意,库存扣减是商城并发问题的高发区,后面避坑章节会专门讲。刚开始改代码时,建议沿这条线找文件:小程序页面 -> 找到请求的 url -> 在 api 模块 Controller 里搜这个路径 -> 进 Service -> 进 Mapper。按这个顺序读三个文件,就能搞清楚一次请求的完整路径,比在 IDE 里全局搜关键字高效得多。

3. 本地跑起商城:数据库初始化、后端配置与小程序编译的完整路子

这章是整篇最容易被卡住的地方。很多新手拿到源码后的做法是先用微信开发者工具打开 microapp,看到缺接口报错再回头搞后端,这个顺序是反的。正确顺序是:先建数据库、启动后端、用 curl 验证接口通,最后再编译小程序端。后端多模块项目还涉及依赖安装顺序,第一次跑建议从根目录的 pom.xml 开始构建。

3.1 先把数据库准备好:初始化 SQL 脚本与字符集设置

源码包里一般会在 sql 或 doc 目录放初始化脚本,文件名通常是 install.sql、linjiashop.sql 这种带 sql 后缀的。打开脚本先看前三行,确认它有没有自动建库语句。如果没有,你要手动建库再导入,否则会直接报 Unknown database。

mysql -uroot -p -e "CREATE DATABASE linjiashop DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" mysql -uroot -p --default-character-set=utf8mb4 linjiashop < sql/linjiashop.sql

第一句创建数据库时指定了 utf8mb4 字符集,第二句导入数据时也带了 --default-character-set=utf8mb4。这两处必须一致,否则 Windows 下终端默认的 gbk 会把中文数据写乱,后面前端页面显示商品名全是问号,你很难第一时间想到是导入环节出了问题。

导入完成后验证一下表数量,比如用 SHOW TABLES 看看结果,再 select 一条商品记录检查中文是否正常。我一般还会顺手查一下管理员账号的密码字段,确认它是明文还是加密,这关系到后台管理系统能不能登录。常见项目初始账号是 admin,密码可能在 README 或 sql 注释里。

3.2 后端必调的三个配置:数据源、Redis、JWT 密钥

改配置是启动后端的核心环节。linjiashop 的 api 模块和 admin 模块各自有 application.yml,但你只需要先改 api 模块。打开这个文件后,重点看三个配置项:数据库连接、Redis 连接、JWT 密钥。

spring: datasource: url: jdbc:mysql://localhost:3306/linjiashop?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 redis: host: localhost port: 6379 password: linjiashop: jwt: secret: change-me-to-a-random-string expire-in: 604800

数据源 url 里有两个参数很容易被忽略。serverTimezone 必须设置,否则高版本 MySQL 驱动连接时会报时区错误;characterEncoding=utf8 要和建库时的 utf8mb4 语义一致,虽然这里写法是 utf8,但 MySQL 驱动一般能正确识别。Redis 如果本地没装,赶紧先装一个,现在主流版本基本支持 Windows 和 macOS,启动后确认 6379 端口能访问。整个项目登录态和部分缓存都依赖 Redis,跳过去会报一堆连接异常。

JWT 密钥建议直接改成一串随机字符串,长度至少 32 位。这个密钥负责生成登录 token,一旦泄漏,任何人可以伪造管理员身份调用后台接口。expire-in 单位是秒,604800 是七天,按需调整就行。

改完配置用 maven 命令从根目录构建并启动。如果你本机 maven 没配镜像,下载依赖可能很慢,等看到 BUILD SUCCESS 再继续。启动 api 模块后观察控制台日志,出现 Tomcat started on port 字样说明后端起来了。curl 一下健康检查接口或任意一个公开接口,能通再往下走。

curl "http://127.0.0.1:8080/api/goods/page?pageNum=1&pageSize=10"

返回 JSON 里有商品列表就是正常的。如果 404,先去看端口和 context-path,有的项目接口前缀是 /api,有的还会加模块名,这两个地方对不上就会 404。

3.3 小程序端编译:微信开发者工具打开 microapp 后的第一步

后端就绪后,用微信开发者工具导入 microapp 目录。这一步有几个新手常犯的错误。第一个是导入时选错了目录,把整个 linjiashop-master 导进去了,结果开发者工具提示找不到 app.json。microapp 目录下才有 app.json、app.js、pages 目录,认准这个结构。

导入后先别急着点编译,打开 project.config.json 确认 appid 配置。个人开发没有企业小程序账号很正常,微信开发者工具支持测试号,把 appid 改成 touristappid 即可,不需要注册任何东西。

{ "appid": "touristappid", "projectname": "linjiashop-miniapp", "setting": { "urlCheck": false } }

urlCheck 是本地开发的关键开关。小程序默认要求请求地址必须是配置在后台的 HTTPS 域名,本地开发连的是 http://127.0.0.1:8080,属于不合规地址,不开这个开关编译直接报“不在以下 request 合法域名列表中”。把它设成 false 后,工具里的模拟器和真机调试都能访问本地接口。

编译后通常控制台还会出现一个“开发版小程序已过期”提示,这不是代码问题,是你上次打开的时间离现在太久了。处理方式是让微信开发者工具重新扫码登录,再编译就正常了。初次打开什么都不显示,先看控制台,把报错贴出来逐个解决,而不是反复点编译。

3.4 验证最小请求链:从登录接口拿到首页商品列表

小程序页面默认会走登录逻辑,拿到的登录凭证 code 传给后端,后端再用 code 向微信接口换 openid,最后返回一个业务 token。这个链路如果没走通,首页根本拉不到商品列表。为了确认问题在哪一环,我习惯先用 curl 手动模拟登录接口,把这个环节单独摘出来验证。

curl -X POST http://127.0.0.1:8080/api/member/login \ -H "Content-Type: application/json" \ -d '{"code":"test-code"}'

这里你本地没有真实 code,所以接口大概率返回 code 无效之类的错误,这没关系,重点看错误类型。如果返回 401 或“无效 code”,说明后端服务、数据库、Redis 都正常,只是微信登录凭证校验卡住了,等小程序端真实调用时 code 是有效的。如果返回 404 或连接拒绝,说明问题在配置或服务没起好。

真实跑通的方式是在小程序里调用 wx.login 拿 code,再发送登录请求。你可以在 app.js 的 onLaunch 里打一个 console.log 把 code 打出来,确认它有值。拿不到 code 的原因通常是基础库版本太旧,在开发者工具详情里把调试基础库调到最新再看。首页商品列表加载完成后,整个最小链路才算真正打通,这条链是后续所有订单功能的地基。

4. 读懂商城购买链路:购物车、订单状态与支付回调的代码咬合

前面能跑通只是第一步,你还需要读懂购买链路,否则改需求时完全不敢动代码。商城最核心的部分不是商品展示,而是下单时的库存扣减、支付回调的状态更新、登录态的凭证处理。这三段代码直接决定业务正确性,也是面试时最容易追问的点。

4.1 从加购到下单:事务边界与库存扣减的写法

加购本质是往购物车表插一条记录,真正有技术含量的是从购物车生成订单的过程。新手最容易犯的错误是把下单逻辑写成“先查库存,再扣库存,最后插入订单”,这三步之间没有任何保护,两个用户同时下单同一个商品时,库存直接变成负数。

常见做法是把库存扣减放到一条 SQL 里做条件更新,同时用事务保证订单和库存变更的一致性。

@Transactional(rollbackFor = Exception.class) public String createOrder(Long memberId, Long goodsId, Integer count) { int affected = goodsMapper.reduceStock(goodsId, count); if (affected == 0) { throw new BizException("库存不足"); } String orderNo = generateOrderNo(); orderMapper.insert(memberId, goodsId, count, orderNo); return orderNo; }

reduceStock 的实现是关键:

UPDATE mall_goods SET stock = stock - #{count} WHERE id = #{goodsId} AND stock >= #{count}

这条 SQL 利用了数据库行锁的特性:只有当前库存大于等于扣减数量时才更新,并且让受影响行数为 0。affected 等于 0 就说明库存被别的请求抢先扣完了,无需再查一次库存。放在 @Transactional 里能保证扣库存和插订单要么都成功、要么都失败,不会出现订单生成了但库存没扣的脏数据。

这里的参数 count 必须做上限校验,比如单次最多 99 件、最小 1 件,防止有人恶意下单。生成订单号建议用“时间戳 + 随机数 + 用户标识”组合,不要用数据库自增主键直接当订单号暴露给前端,很容易被遍历出平台每日订单量。

4.2 支付回调要做两件事:验签与幂等处理

微信支付完成后,微信服务器会异步 POST 一个支付结果到你的回调地址。这个回调地址就是后端 Controller 里的一个方法,它和普通接口最大的区别是:它可能被调用多次,而且任何人只要能构造报文都可能往这个地址 POST 数据。所以回调处理必须同时解决验签和幂等。

public String onNotify(PayNotify notify) { if (!payService.verifySign(notify)) { return "fail"; } Order order = orderMapper.findByOrderNo(notify.getOrderNo()); if (order == null) { return "fail"; } if (order.getStatus() == PAYED) { return "success"; } if (order.getStatus() != UNPAY) { return "fail"; } orderMapper.updateStatusByOrderNo(notify.getOrderNo(), PAYED); return "success"; }

验签逻辑在 payService 里,本质是用支付平台下发的密钥对回调报文里的几个关键字段重新签名,和微信传来的 sign 字段比对。比对通过才继续,不通过直接返回 fail。

幂等处理在代码里表现为先查订单状态:如果已经是已支付,说明之前已经处理过这次回调,直接返回 success 而不是再更新一次状态。如果不做这个判断,同一笔订单的重复回调可能把支付时间覆盖成两次不同的值,或触发发货逻辑重复执行。最后返回的字符串必须是 success 或 fail,微信服务器看到 success 才认为回调处理完成,返回其他内容它会重试多次。

4.3 小程序登录态:code 换 openid 的常见实现

小程序端的登录和传统用户名密码登录不一样,它依赖微信的 jscode2session 接口。用户在小程序里调用 wx.login 拿到一个临时 code,这个 code 有效期只有五分钟且只能用一次,小程序端把它传给后端,后端再用 appid、secret 和 code 去微信服务器换 openid 和 session_key。

public String code2Session(String code) { String url = "https://api.weixin.qq.com/sns/jscode2session" + "?appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code"; String result = restTemplate.getForObject(url, String.class); JSONObject json = JSON.parseObject(result); if (json.getInteger("errcode") != null) { throw new BizException("code 已失效"); } return json.getString("openid"); }

这个接口返回的 openid 是用户在小程序里的唯一标识,适合作为 mall_member 表的业务主键。拿到 openid 后,先查表有没有这个用户,没有就注册一条新记录。

这里的 session_key 要特别注意,它用于解密手机号和用户敏感信息,拿到后不应该写进日志,更不应该放到 Redis 以外的持久化里。有些老代码会把 session_key 和 openid 一起返回给前端,这是安全隐患。正确做法是后端自己持有 openid,返回给前端的是你们自己生成的业务 token,后续请求都带这个 token。

5. 避坑手册:linjiashop 跑通与二次开发的 5 个常见问题

前面讲的都是正向流程,实际跑的时候大概率会翻车。这一章我按自己多次复现这类项目的经验,把最容易卡住新手的五个问题列出来,每个都按现象、原因、解决的顺序写。建议先收藏,遇到问题再翻到这里。

5.1 接口 404:上下文路径与小程序请求地址不一致

现象:后端启动成功,浏览器直接访问后端地址能出数据,但小程序里请求接口全部 404。

原因:大部分项目配置了 context-path,也就是接口统一前缀。你浏览器里访问的是 http://127.0.0.1:8080/api/goods/page,小程序 config.js 里配的却是 http://127.0.0.1:8080/goods/page,少了一段路径,请求直接打到不存在的路由上。这类问题在小程序端表现为一个白页加一串 404 报错,想确认请求到底去了哪,在开发者工具的控制台看 network 面板就行,比对着代码猜快得多。

解决:打开小程序 public 配置或 utils/request.js,找 baseUrl,改成带完整前缀的地址。后端如果设置的是 /api,那就两者保持一致。

// config.js module.exports = { baseUrl: 'http://127.0.0.1:8080/api' }

注意改完要重新编译小程序,只改文件不重新编译有时不会生效。先 curl 一下完整地址确认后端能通,再在小程序里请求,两个环节分开验证,翻车概率会低很多。

5.2 订单状态乱跳:并发下单时的库存扣减没有加条件

现象:压测或多人同时下单时,库存变成负数,订单却能正常生成。

原因:代码逻辑是“先 select 查库存,库存大于 0 再 update 扣减”。这种写法在并发下有两个线程同时读到库存为 1,都认为可以下单,执行 update 时库存已经变成 -1。问题本质是“检查”和“扣减”不是原子操作。这个坑不只在商城项目里有,凡是涉及库存、余额、优惠券数量这类读改写场景都会遇到。

解决:改成前面 4.1 节那种带条件更新的 SQL,让检查与扣减在同一条语句中完成。顺手在商品的 stock 字段上建普通索引,避免 update 时全表扫描锁住过多行。

UPDATE mall_goods SET stock = stock - #{count} WHERE id = #{goodsId} AND stock >= #{count}

改完后再压测一次,affected 为 0 时你的事务会抛出异常并回滚,订单不会插入,库存也不会被扣成负数。

5.3 真机预览白屏:域名校验、调试基础库与抓包定位

现象:开发者工具里一切正常,点“真机预览”扫码后,手机打开小程序白屏,什么都显示不出来。

原因:真机上没有“不校验合法域名”这个开关,微信会强制检查请求地址域名是否在后台配置过。你的本地地址是 http://127.0.0.1:8080,既不是合法域名也不带 https,请求直接在真机侧被拦截,页面拿不到数据自然白屏。另一个常见原因是调试基础库版本太低,老旧基础库不支持某些新语法,页面脚本直接报错。

解决:分两步排查。先在开发者工具的“详情 -> 本地设置”里勾选“不校验合法域名”,这个只对模拟器有效,真机还得做域名配置。开发阶段如果没有现成域名,可以用局域网 IP 加开发者工具的真机调试模式绕过,或者用内网穿透工具把本地接口映射成一个 https 地址,再把小程序后台配置到 request 合法域名里。

这里给一个血泪经验:真机白屏时先别急着反编译小程序看源码,也不要在代码里乱加 console.log。把手机通过数据线连电脑,在开发者工具里打开“真机调试”,直接看手机端的 console 报错,定位速度最快。小程序是黑匣子,你不看它的报错就只能瞎猜。

5.4 数据库导入乱码:Windows 下默认字符集导致的典型现象

现象:数据库导入 SQL 脚本后,后台管理页面和商品列表的商品名全是问号或乱码。

原因:Windows 命令行终端的默认编码是 GBK,执行 mysql 命令导入文件时,终端把 utf8 编码的 SQL 脚本内容按 GBK 解析后写入库表,中文数据就坏了。问题不在代码,而在导入环节。

解决:重新导入,导入命令里强制指定字符集:

mysql -uroot -p --default-character-set=utf8mb4 linjiashop < sql/linjiashop.sql

如果你用的是 Navicat 这类图形化工具,执行 SQL 文件前先在连接属性里把编码设成 utf8mb4。导入完成后再次查询验证:select title from mall_goods limit 5。改完这个再重启后端,乱码问题基本一次解决。这个坑之所以常见,是因为它不像接口报错那么直接,数据看着是“有值”的,前端渲染时才对不上。

5.5 支付回调进不来:内网穿透与回调地址白名单

现象:本地调起微信支付成功,但订单状态始终不变成已支付,后台日志也没有打印支付回调相关的信息。

原因:微信支付回调地址必须是公网可访问的 https 地址。你本地开发时后端跑在 127.0.0.1,微信服务器根本访问不到,回调自然进不来。第二个原因是回调地址没有配置到支付商户平台的白名单里,微信会拒绝向其未校验的域名发送回调。

解决:先在本地自测把问题和网络隔离。用 curl 模拟微信服务器向你的回调接口发一条 POST 请求,接口能正常返回 success,说明业务代码没问题。

curl -X POST http://127.0.0.1:8080/api/pay/notify \ -H "Content-Type: application/json" \ -d '{"orderNo":"测试单","sign":"本地调试用"}'

接着把接口通过内网穿透工具暴露成公网 https 地址,在支付平台的回调地址配置里填这个公网地址。配置完成后重新发起一笔小额支付,观察后端日志有没有收到 POST。我见过有人在这里卡了两天,最后发现是穿透工具免费版的域名被微信风控拦截了,换了一个域名配置就好。支付回调的排查顺序永远是:本地自测 -> 公网可达性 -> 白名单配置。

6. 进阶改造:把 linjiashop 当脚手架用的三个心法

项目跑通只是开始,你要是拿它做毕设或二次开发,后面肯定要加需求。我自己的习惯是把它当成一个可拆解的脚手架,而不是一个完整交付物。下面这三个心法是我在改类似商城项目时最常用的思路。

第一个心法:动手改代码前,先把订单状态机画出来。linjiashop 的订单状态在数据库里只有一个 status 字段,但状态和状态之间不是随便跳的。待支付可以关闭、可以支付;已支付可以发货;已发货可以确认收货;已收货可以评价。你画完这张图再改代码,就不会出现“已支付订单直接改成已关闭”这种逻辑错误。代码里用枚举约束状态变更,比裸判断整数常量好维护得多。

第二个心法:支付结果不能只依赖回调,要加一个定时对账补偿。回调可能延迟、丢失,甚至微信侧处理完成但你本地网络断了。我的做法是建一张支付记录表,每五分钟跑一个任务,把超时未支付订单标记为关闭,把本地显示未支付但微信侧已扣款的订单捞出来,主动调用微信查单接口确认最终状态。这个机制是支付系统的后悔药,没有它,偶尔丢一笔回调就够你赔半天收益。

第三个心法:后台管理不要和小程序会员共用同一张权限表。我有一次图省事,在 member 表加了一个 is_admin 字段,后来想加角色权限完全没法扩展。正确做法是管理员单独建表,用角色关联菜单权限。这块代码写完以后,毕设答辩时也能讲出亮点,面试官问“你怎么设计权限模型”时你就有实战案例了。

public enum OrderStatus { WAIT_PAY(0, "待支付"), PAYED(1, "已支付"), DELIVERED(2, "已发货"), FINISHED(3, "已完成"), CLOSED(4, "已关闭"); private final int value; private final String desc; }

线上经验说到底是“先把边界搞清楚再动手”。我以前拿到一个项目源码就急着跑起来,结果支付回调没配好,硬是排查了两天。后来养成了一个习惯:先画状态图、列外部依赖、写最小验证用例。这三步做完,百分之八十的坑都提前避开了。希望能帮到你少走点弯路。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询