温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!1. 项目背景与意义
随着移动互联网的普及和微信生态的快速发展,微信小程序已成为连接商家与消费者的重要渠道。零食作为高频、低客单价的快消品类,天然适合通过小程序进行线上销售。传统零食零售门店面临租金高、客流有限、营销手段单一等痛点,而基于微信小程序的零食商城能够借助微信庞大的用户流量和社交传播能力,实现线上引流、线上下单、线下配送或自提的闭环。
本项目采用 Spring Boot 作为后端开发框架,结合微信小程序前端,构建一套完整的零食商城销售系统。其意义主要体现在以下几个方面:
- 降低获客成本:依托微信生态,用户无需下载独立 App,扫码即可进入商城,降低使用门槛。
- 提升购物体验:支持商品浏览、搜索、分类筛选、购物车、在线支付、订单跟踪等完整购物流程。
- 数据驱动运营:通过订单、用户、商品等数据的采集与分析,为商家提供经营决策支持。
- 技术实践价值:涵盖前后端分离、RESTful API 设计、数据库设计、微信登录鉴权、支付对接等主流技术点,适合作为毕业设计或项目实战。
2. 系统技术栈
2.1 后端技术栈
| 技术 | 说明 |
|---|---|
| Spring Boot | 核心后端框架,简化配置,快速构建独立运行的微服务应用 |
| Spring MVC | 处理 HTTP 请求,实现 RESTful API 接口 |
| MyBatis-Plus | ORM 框架,简化数据库操作,支持分页、条件构造器等 |
| MySQL | 关系型数据库,存储用户、商品、订单等业务数据 |
| Redis | 缓存热点数据,如商品信息、用户会话、购物车等 |
| JWT | 无状态身份认证,用于小程序端登录态管理 |
| 微信支付 SDK | 对接微信支付接口,实现在线支付功能 |
| Maven | 项目构建与依赖管理工具 |
2.2 前端技术栈
| 技术 | 说明 |
|---|---|
| 微信小程序原生框架 | WXML、WXSS、JavaScript,构建小程序页面与交互 |
| 微信开发者工具 | 小程序开发、调试与预览工具 |
| Vant Weapp | 轻量、可靠的移动端组件库,提升 UI 开发效率 |
| 微信支付 | 小程序端发起支付请求,完成交易闭环 |
3. 系统功能模块设计
系统整体分为用户端小程序和管理端后台两部分,核心功能模块如下:
- 用户模块:微信授权登录、用户信息维护、收货地址管理。
- 商品模块:商品分类、商品列表、商品详情、搜索与筛选。
- 购物车模块:加入购物车、修改数量、删除商品、批量结算。
- 订单模块:提交订单、在线支付、订单状态查询、取消订单、确认收货。
- 管理端模块:商品管理、分类管理、订单管理、用户管理、数据统计。
4. 数据库设计
系统核心数据表包括用户表、商品表、商品分类表、购物车表、订单表、订单明细表和收货地址表。以下为关键表结构设计:
4.1 用户表(user)
CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `openid` varchar(64) NOT NULL COMMENT '微信openid', `nickname` varchar(64) DEFAULT NULL COMMENT '昵称', `avatar_url` varchar(255) DEFAULT NULL COMMENT '头像地址', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_openid` (`openid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';4.2 商品表(product)
CREATE TABLE `product` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `category_id` bigint(20) NOT NULL COMMENT '分类ID', `name` varchar(128) NOT NULL COMMENT '商品名称', `description` text COMMENT '商品描述', `price` decimal(10,2) NOT NULL COMMENT '售价', `stock` int(11) NOT NULL DEFAULT 0 COMMENT '库存', `image_url` varchar(255) DEFAULT NULL COMMENT '商品图片', `status` tinyint(4) NOT NULL DEFAULT 1 COMMENT '状态:1上架 0下架', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), KEY `idx_category` (`category_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';4.3 订单表(orders)
CREATE TABLE `orders` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `order_no` varchar(32) NOT NULL COMMENT '订单编号', `user_id` bigint(20) NOT NULL COMMENT '用户ID', `total_amount` decimal(10,2) NOT NULL COMMENT '订单总金额', `status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '状态:0待支付 1已支付 2已发货 3已完成 4已取消', `address_id` bigint(20) DEFAULT NULL COMMENT '收货地址ID', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `pay_time` datetime DEFAULT NULL COMMENT '支付时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), KEY `idx_user` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';5. 核心代码实现
5.1 微信登录接口
小程序端通过wx.login获取临时 code,后端调用微信接口换取 openid,并生成 JWT 令牌返回给前端。
@RestController @RequestMapping("/api/user") public class UserController { @Autowired private UserService userService; @PostMapping("/login") public Result login(@RequestBody LoginRequest request) { String openid = userService.getOpenId(request.getCode()); User user = userService.findOrCreateUser(openid); String token = JwtUtil.generateToken(user.getId()); return Result.success(new LoginResponse(token, user)); } }5.2 商品列表分页查询
@Service public class ProductServiceImpl implements ProductService { @Autowired private ProductMapper productMapper; @Override public PageResult<ProductVO> getProductPage(ProductQuery query) { Page<Product> page = new Page<>(query.getPageNum(), query.getPageSize()); LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(query.getCategoryId() != null, Product::getCategoryId, query.getCategoryId()) .like(StringUtils.isNotBlank(query.getKeyword()), Product::getName, query.getKeyword()) .eq(Product::getStatus, 1) .orderByDesc(Product::getCreateTime); Page<Product> result = productMapper.selectPage(page, wrapper); return PageResult.of(result.getRecords(), result.getTotal()); } }5.3 提交订单与库存扣减
@Transactional(rollbackFor = Exception.class) public OrderVO createOrder(OrderCreateRequest request, Long userId) { // 1. 生成订单编号 String orderNo = OrderNoGenerator.generate(); // 2. 计算订单总金额并校验库存 BigDecimal totalAmount = BigDecimal.ZERO; List<OrderItem> items = new ArrayList<>(); for (OrderItemRequest item : request.getItems()) { Product product = productMapper.selectById(item.getProductId()); if (product == null || product.getStock() < item.getQuantity()) { throw new BusinessException("商品库存不足"); } totalAmount = totalAmount.add(product.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()))); // 3. 扣减库存 product.setStock(product.getStock() - item.getQuantity()); productMapper.updateById(product); // 4. 组装订单明细 OrderItem orderItem = new OrderItem(); orderItem.setOrderNo(orderNo); orderItem.setProductId(product.getId()); orderItem.setProductName(product.getName()); orderItem.setPrice(product.getPrice()); orderItem.setQuantity(item.getQuantity()); items.add(orderItem); } // 5. 保存订单主表 Order order = new Order(); order.setOrderNo(orderNo); order.setUserId(userId); order.setTotalAmount(totalAmount); order.setStatus(0); order.setAddressId(request.getAddressId()); orderMapper.insert(order); // 6. 保存订单明细 orderItemMapper.insertBatch(items); return OrderVO.from(order); }5.4 小程序端商品列表页
Page({ data: { productList: [], pageNum: 1, pageSize: 10, hasMore: true, keyword: '' }, onLoad() { this.loadProducts(); }, loadProducts() { const that = this; wx.request({ url: 'https://api.example.com/api/product/page', method: 'GET', data: { pageNum: that.data.pageNum, pageSize: that.data.pageSize, keyword: that.data.keyword }, success(res) { const list = res.data.data.records; that.setData({ productList: that.data.productList.concat(list), hasMore: that.data.productList.length < res.data.data.total }); } }); }, onReachBottom() { if (this.data.hasMore) { this.setData({ pageNum: this.data.pageNum + 1 }); this.loadProducts(); } }, goDetail(e) { const id = e.currentTarget.dataset.id; wx.navigateTo({ url: '/pages/detail/detail?id=' + id }); } });6. 总结
本项目基于 Spring Boot 和微信小程序构建零食商城销售系统,后端采用分层架构设计,前端使用小程序原生框架,实现了从用户登录、商品浏览到下单支付、订单管理的完整业务闭环。系统在技术层面覆盖了微信登录鉴权、RESTful API 设计、MyBatis-Plus 数据持久化、Redis 缓存、微信支付对接等主流技术,具备良好的扩展性和可维护性,既满足实际业务需求,也具有较高的工程实践参考价值。