1. 项目背景与核心价值
无人超市支付系统是近年来零售行业数字化转型的重要实践方向。作为计算机专业毕业设计的选题,这个项目融合了Java企业级开发、移动支付集成、物联网设备交互等多项前沿技术。我在实际开发中发现,这类系统不仅考验编程能力,更需要对零售业务场景的深入理解。
传统超市的人力成本约占运营成本的30%-40%,其中收银环节占据很大比重。无人支付系统通过自助扫码、人脸识别、自动结算等技术,能够将单次交易时间压缩到10秒以内,同时减少80%以上的人工干预。这种模式在校园便利店、社区超市、机场零售等场景具有显著优势。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 整体架构方案
系统采用经典的三层架构设计:
- 前端:微信小程序+H5混合开发
- 后端:SpringBoot 2.7 + MyBatis-Plus
- 数据库:MySQL 8.0(阿里云RDS版)
- 中间件:Redis缓存 + RabbitMQ消息队列
这种架构选择基于以下考量:
- SpringBoot的自动配置特性适合快速搭建支付系统核心
- MyBatis-Plus的代码生成器可快速构建商品CRUD模块
- MySQL的ACID特性保障交易数据一致性
- Redis应对高并发秒杀场景
- RabbitMQ解耦支付结果通知与订单处理
2.2 关键技术选型解析
支付模块:
- 微信支付V3 API(Native支付)
- 支付宝当面付SDK
- 本地模拟支付(开发环境用)
选择双支付渠道主要考虑:
- 微信支付覆盖中青年用户
- 支付宝在校园场景渗透率高
- 开发时需隔离真实支付接口
商品识别方案:
- 主方案:二维码+重量传感器校验
- 备选:RFID标签识别(成本较高)
- 实验性:YOLOv5图像识别(需GPU支持)
3. 核心功能实现
3.1 支付流程设计
典型支付时序:
- 用户扫码开门(小程序授权)
- 摄像头捕捉商品二维码
- 系统生成预支付订单
- 调用支付接口获取付款码
- 用户完成支付
- 门禁系统收到成功通知后放行
关键代码片段:
java复制// 支付订单生成逻辑
public PaymentOrder generateOrder(List<CartItem> items) {
PaymentOrder order = new PaymentOrder();
order.setOrderNo(IdWorker.getIdStr());
order.setTotalAmount(calculateTotal(items));
order.setPayChannel(PAY_CHANNEL_WECHAT);
order.setStatus(ORDER_STATUS_CREATED);
// 防重校验
if(orderMapper.selectById(order.getOrderNo()) != null){
throw new BusinessException("订单号重复");
}
return order;
}
3.2 并发控制方案
针对可能出现的并发问题:
- 使用Redis分布式锁控制库存扣减
- MySQL乐观锁保证数据一致性
- 支付结果采用异步通知机制
库存扣减示例:
sql复制UPDATE product_stock
SET stock = stock - 1
WHERE product_id = #{productId} AND stock >= 1
4. 数据库设计要点
4.1 核心表结构
商品表(product)
sql复制CREATE TABLE `product` (
`id` bigint NOT NULL AUTO_INCREMENT,
`barcode` varchar(32) NOT NULL COMMENT '商品条码',
`name` varchar(64) NOT NULL,
`price` decimal(10,2) NOT NULL,
`weight` int DEFAULT NULL COMMENT '单位克',
`category_id` int DEFAULT NULL,
`status` tinyint DEFAULT '1' COMMENT '1上架 0下架',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_barcode` (`barcode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
订单表(payment_order)
sql复制CREATE TABLE `payment_order` (
`order_no` varchar(32) NOT NULL,
`user_id` varchar(32) NOT NULL,
`total_amount` decimal(10,2) NOT NULL,
`pay_time` datetime DEFAULT NULL,
`status` tinyint NOT NULL COMMENT '0未支付 1已支付 2已退款',
`device_id` varchar(32) DEFAULT NULL COMMENT '设备编号',
PRIMARY KEY (`order_no`),
KEY `idx_user` (`user_id`),
KEY `idx_device` (`device_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 开发实战经验
5.1 支付安全实践
- 签名验证:所有支付回调必须验证签名
java复制boolean isValid = WxPayKit.verifyNotify(
params,
wxPayConfig.getApiKey(),
wxPayConfig.getSignType()
);
if(!isValid){
throw new SecurityException("签名验证失败");
}
- 敏感数据加密:
- 使用AES加密存储用户openid
- 数据库字段加密采用MyBatis TypeHandler实现
- XSS防护:
- 前端使用DOMPurify过滤输入
- 后端采用Spring HtmlUtils
5.2 性能优化技巧
- 商品查询缓存:
java复制@Cacheable(value = "product", key = "#barcode")
public Product getByBarcode(String barcode){
return productMapper.selectOne(
new QueryWrapper<Product>().eq("barcode", barcode)
);
}
- 支付结果查询优化:
- 本地缓存+Redis二级缓存
- 失败请求采用指数退避重试
- 数据库连接池配置:
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
6. 典型问题解决方案
6.1 支付超时处理
常见场景:
- 用户扫码后未完成支付
- 网络延迟导致回调丢失
解决方案:
- 设置15分钟支付有效期
- 定时任务扫描待支付订单
- 订单状态机设计:
java复制public enum OrderStatus {
CREATED(0),
PAID(1),
EXPIRED(2),
REFUNDED(3);
// 状态转换校验逻辑
public boolean canTransferTo(OrderStatus target) {
switch(this) {
case CREATED:
return target == PAID || target == EXPIRED;
case PAID:
return target == REFUNDED;
default:
return false;
}
}
}
6.2 设备离线应对
应急方案设计:
- 本地存储未上传交易记录
- 使用SQLite作为临时存储
- 网络恢复后批量同步
- 心跳检测机制监控设备状态
7. 项目扩展方向
- 智能货架:通过重量传感器实时监测商品变动
- 行为分析:利用摄像头数据优化货架摆放
- 电子价签:远程同步价格信息
- 供应链对接:自动生成补货订单
实际开发中发现,使用SpringBoot的Actuator端点可以方便地监控系统健康状态:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
在部署阶段,建议采用Docker容器化方案。通过Docker Compose可以快速搭建包含MySQL、Redis的完整环境:
dockerfile复制version: '3'
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- redis
- mysql
redis:
image: redis:alpine
ports:
- "6379:6379"
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
