1. 项目背景与核心价值
台球这项运动在国内年轻人群体中一直保持着稳定的热度。传统台球室通常需要前台人工服务,不仅增加了人力成本,在夜间运营时段也面临管理难题。去年我在北京某大学城附近考察时发现,很多学生群体对"随时能打台球"有强烈需求,但传统球房晚上10点后就停止营业了。
这个Java开发的无人台球室系统正是为了解决这些痛点而生。通过自助开台机+移动端小程序组合,实现了24小时无人化运营。更妙的是加入了社交匹配功能——当单人用户想打球时,系统可以自动匹配同样落单的玩家,既解决了"一个人没法玩"的尴尬,又为球室增加了客流量。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型
后端采用SpringBoot+MyBatis经典组合,考虑到需要处理大量实时状态数据,引入了Redis作为缓存层。数据库选用MySQL 8.0,主要看中其JSON字段处理能力——用户动态、匹配记录这些非结构化数据直接存JSON格式,比传统关系型设计更灵活。
前端小程序用uni-app开发,一次编码可同时发布到微信和支付宝平台。自助终端设备实际是一台Android平板,通过定制ROM锁定了只能运行我们的开台APP。
2.2 核心模块划分
系统包含六大核心模块:
- 设备控制模块 - 管理球桌电磁锁、计费显示屏等硬件
- 支付模块 - 聚合微信/支付宝/银联支付
- 用户系统 - 处理注册、登录、权益体系
- 匹配引擎 - 基于ELO算法的智能匹配
- 订单系统 - 记录消费流水
- 管理后台 - 供运营者查看数据报表
3. 关键实现细节
3.1 自助开台流程
当用户扫描球桌二维码时,系统会执行以下原子操作:
java复制// 伪代码展示核心逻辑
public Response scanQRCode(String qrcode, Long userId) {
// 1. 校验球桌状态
Table table = tableDao.selectByQrcode(qrcode);
if (table.getStatus() != TableStatus.FREE) {
throw new BusinessException("该球桌正在使用中");
}
// 2. 创建预订单
Order order = new Order();
order.setStartTime(LocalDateTime.now());
order.setTableId(table.getId());
order.setUserId(userId);
orderDao.insert(order);
// 3. 开启电磁锁
iotService.unlock(table.getDeviceId());
// 4. 更新球桌状态
table.setStatus(TableStatus.IN_USE);
tableDao.updateById(table);
// 5. 开始计费
billingService.startBilling(order.getId());
return Response.success(order);
}
3.2 智能匹配算法
交友系统的核心是匹配策略。我们改良了国际象棋常用的ELO算法,除了考虑玩家技术水平外,还加入了三个维度:
- 社交活跃度(经常参与匹配的用户优先)
- 消费能力(匹配相近消费档次的用户)
- 时段偏好(夜猫子不会匹配早睡族)
匹配池采用Redis的ZSET实现,用户进入匹配状态时:
java复制// 用户加入匹配池
String key = "matching_pool:" + courtId;
redisTemplate.opsForZSet().add(key, userId, calculateScore(user));
// 定时任务每30秒执行一次匹配
Set<Long> candidateIds = redisTemplate.opsForZSet()
.rangeByScore(key, minScore, maxScore, 0, 10);
// 使用匈牙利算法找出最优匹配
List<MatchPair> pairs = hungarianMatch(candidateIds);
4. 安全与风控设计
无人值守系统最怕的就是作弊和破坏。我们实现了三重防护机制:
- 设备心跳检测:每台球桌终端每分钟上报状态,超时3次自动触发警报
- 异常订单识别:用孤立森林算法检测异常消费模式
- 用户信用体系:破坏设备或恶意逃单会被降低信用分,影响匹配优先级
支付环节特别要注意幂等性处理。我们给每个订单设置了唯一token,防止重复支付:
java复制@Transactional
public boolean confirmPayment(String orderNo, String paymentId) {
// 使用select for update加行锁
Order order = orderDao.selectForUpdate(orderNo);
if (order.getStatus() != OrderStatus.UNPAID) {
return false; // 已处理过的订单直接返回
}
// 更新订单状态
order.setPaymentId(paymentId);
order.setStatus(OrderStatus.PAID);
return orderDao.updateById(order) > 0;
}
5. 运营数据分析
系统上线三个月后,我们从后台数据中发现几个有趣现象:
- 匹配成功率随时间变化:晚8-10点成功率高达78%,而下午时段仅32%
- 用户留存率:通过匹配认识的用户,次周留存率比普通用户高41%
- 设备使用率:加装自助系统后,球桌日均使用时长从5.2小时提升到9.8小时
基于这些数据,我们优化了匹配策略的权重系数,并在低峰时段推出"拼桌特惠"活动,使整体营收提升了27%。
6. 踩坑实录
-
电磁锁供电问题:初期选用WiFi模块控制电磁锁,实际使用中发现断电后无法自动恢复。后来改用4G物联网卡+蓄电池方案,保证72小时断电续航。
-
并发开台冲突:曾出现多人同时扫描同一球桌二维码导致重复开台。最终通过Redis分布式锁+数据库乐观锁双重保障解决:
java复制public boolean tryLock(String key, long expireSeconds) {
String requestId = UUID.randomUUID().toString();
Boolean result = redisTemplate.opsForValue()
.setIfAbsent(key, requestId, expireSeconds, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(result)) {
// 成功获取锁
return true;
}
return false;
}
- 小程序审核被拒:因"涉及陌生人社交"被微信拒绝上架。调整产品文案,强调"运动约伴"属性后通过审核。
这套系统目前已在12家球房落地,平均节省人力成本4.2万元/年/店。最让我意外的是社交功能带来的附加价值——有7%的用户会为心仪对手购买饮料,这部分衍生消费占总营收的9%。
