西安GogoAI健身系统Java后端开发,会员权益模块实现
痛点分析
西安本地很多自助健身场馆、私教工作室的会员权益管理大多采用简单的卡记录方案,无法兼容多种卡类型。月卡、季卡不限次时效权益、次卡、私教课时包、团购体验券混在一起校验,很容易出现扣次错乱、过期判定不准的问题;订单支付回调、团购核销、门禁入场、约课多个入口都要消耗权益,并发场景下存在超扣、重复扣次风险;连锁门店场景,会员跨店权限、门店数据隔离不好控制;退款、订单撤销之后权益回滚逻辑缺失,财务对账困难;权益变更之后无法实时同步到门禁网关,会员购卡成功却开不了门;同时缺少统一的权益流水,客诉时很难追溯每一次消耗记录。
GogoAI健身系统基于SpringBoot + MyBatisPlus + Redis开发会员权益模块,面向西安本地24小时自助健身房、私教工作室、连锁场馆,统一抽象权益模型,区分时效型、计次型两类权益,支持购卡发放、入场核销扣次、退款回滚、跨店权限配置,配合乐观锁+幂等机制保证并发安全,和订单、团购核销、自助入场、续费提醒模块打通。
整体架构与核心表设计
模块分为权益模板层、权益实例层、权益消耗引擎、权益变更流水、权限控制层。权益模板在后台配置,定义卡类型、有效期规则、可使用门店范围;会员下单或者团购核销成功后,基于模板生成会员权益实例;消耗引擎统一处理入场、约课、私教消课的校验和扣减;每一次发放、扣次、回滚都生成不可修改的流水记录。
核心数据表: card_template 卡模板表:模板名称、卡类型(TIME_LIMIT时效卡 / COUNT_LIMIT计次卡)、默认次数、有效天数、可用门店范围; member_card_right 会员权益实例表:会员ID、门店ID、模板ID、剩余次数、生效时间、到期时间、状态、版本号; card_consume_log 权益消耗流水表:流水号、关联业务单号、权益ID、消耗次数、消耗类型、变更前余量、变更后余量; card_shop_scope 门店使用范围表:权益ID、允许使用门店ID,用于跨店核销控制。
权益状态枚举:VALID有效、EXPIRED已过期、USED_UP次数用完、REFUND已退款、FROZEN冻结。
权益校验与扣次核心Java代码实现
@Service @Slf4j public class MemberCardRightService { @Autowired private MemberCardRightMapper cardRightMapper; private CardConsumeLogMapper consumeLogMapper; private RedisTemplate<String, Object> redisTemplate; @Transactional(rollbackFor = Exception.class) public ResultDTO consumeRight(ConsumeDTO dto) { // 幂等控制,业务单号作为唯一标识,防止回调重试重复扣次 String idempotentKey = "card:consume:" + dto.getBizNo(); if (Boolean.TRUE.equals(redisTemplate.hasKey(idempotentKey))) { return ResultDTO.success("权益已消耗,无需重复处理"); } // 查询有效权益,优先取符合门店范围、未过期、未耗尽的权益 MemberCardRight cardRight = cardRightMapper.selectValidRight( dto.getMemberId(), dto.getStoreId(), dto.getConsumeType()); if (cardRight == null) { return ResultDTO.fail("没有可用的健身权益,请购卡后再使用"); } // 时效卡只校验状态,不扣次数;计次卡校验余量 if ("COUNT_LIMIT".equals(cardRight.getCardType())) { if (cardRight.getRemainCount().compareTo(dto.getConsumeCount()) < 0) { return ResultDTO.fail("剩余次数不足"); } // 乐观锁更新,带版本号防止并发超扣 int rows = cardRightMapper.reduceCount( cardRight.getId(), dto.getConsumeCount(), cardRight.getVersion() ); if (rows <= 0) { throw new BizException("权益更新失败,请重试"); } } // 写入消耗流水,所有变更留痕 CardConsumeLog log = new CardConsumeLog(); log.setBizNo(dto.getBizNo()); log.setCardRightId(cardRight.getId()); log.setMemberId(dto.getMemberId()); log.setStoreId(dto.getStoreId()); log.setConsumeCount(dto.getConsumeCount()); log.setBeforeCount(cardRight.getRemainCount()); log.setAfterCount("COUNT_LIMIT".equals(cardRight.getCardType()) ? cardRight.getRemainCount().subtract(dto.getConsumeCount()) : cardRight.getRemainCount()); log.setConsumeType(dto.getConsumeType()); log.setConsumeTime(LocalDateTime.now()); consumeLogMapper.insert(log); redisTemplate.opsForValue().setIfAbsent(idempotentKey, "1", Duration.ofMinutes(30)); return ResultDTO.success("权益校验通过"); } }这里采用乐观锁方案,更新SQL中携带version版本号,多线程同时扣次时只有一条更新成功,避免并发超扣问题;时效卡(月卡/季卡)只做状态和时间校验,不修改次数字段。
模块核心业务能力
统一权益模型抽象:将所有卡项收敛为时效卡、计次卡两类。时效卡管控起止时间,有效期内不限入场次数;计次卡管控剩余次数,包含普通次卡、私教课时包;团购核销发放的体验券、线下开卡、续费购卡共用同一套发放逻辑,新增卡类型只需要扩展模板配置,不用改动核心扣减代码。
门店使用范围管控:可以配置权益仅限发卡门店,或者支持跨店通用,适配连锁场馆;会员在A店购买的卡,B店开启跨店权限后才可以入场使用;后台可以单独修改单张权益的可用门店列表。
退款与权益回滚:订单退款、团购撤销核销时,支持权益回滚。计次卡把次数原路返还,时效卡如果还未过期则恢复正常可用;回滚同样生成独立流水,和正常消耗区分标记,财务对账时可以区分消耗和回滚记录。
权益状态自动流转:定时任务每日扫描,自动把到达到期时间的权益标记为EXPIRED;次卡余量扣减至0自动标记USED_UP;后台支持手动冻结,用于会员纠纷、暂停服务场景。
实时同步门禁权限:权益发放、冻结、过期、回滚事件发布事件消息,自助入场模块、边缘网关订阅事件,实时更新会员白名单;避免会员购卡成功之后,门禁还是提示无权限入场。
数据权限隔离:使用@StoreDataScope注解,门店管理员只能查看本店会员权益,不能查看其他门店数据;总部账号可以查看全部门店权益汇总,适配多门店管理。
和其他业务模块联动逻辑
和订单支付模块联动:支付成功回调触发权益发放,生成会员卡权益;订单退款触发权益回滚; 和抖音美团团购核销模块联动:团购核销完成后,根据商品映射的卡模板自动发放体验权益;撤销核销同步回收权益; 和自助入场模块联动:会员扫码开门时调用权益校验接口,校验通过才下发开门指令; 和私教排课模块联动:私教预约、课程完成消课走同一套权益消耗接口,单独标记消耗类型; 和续费提醒模块联动:权益到期、次数不足时读取权益数据,触发到期预警、次数预警; 和财务分账模块联动:权益发放、消耗、回滚流水作为财务统计依据,区分实收订单和消耗营收。
落地优化、踩坑总结
第一,区分【发放】和【消耗】两个动作,支付成功只是发放权益,入场、消课才是消耗权益,财务统计一定要分开实收和消耗口径; 第二,并发扣次优先乐观锁,业务简单稳定,不需要引入分布式锁,降低运维复杂度;高并发场馆可以叠加Redis预扣缓存,最终落库; 第三,幂等键一定要绑定业务唯一单号,支付回调、平台重试、前端重复扫码是高频场景,防止多次扣次; 第四,权益流水只新增,不修改原有记录,所有回滚是新增一条反向流水,方便财务审计和客诉排查; 第五,跨店权限单独维护,不要直接写死在卡模板里,支持单卡单独调整,适配西安本地很多一卡多馆的连锁方案; 第六,定时过期任务分批分片执行,不要一次性全表扫描,避免数据库压力波动; 第七,权益变更事件异步推送给门禁网关,增加失败重试队列,防止网关消息丢失导致权限不同步。
落地效果总结
这套会员权益模块是GogoAI健身系统的核心底层模块,统一收敛了购卡、团购、入场、私教消课的权益校验逻辑,解决了多卡类型混杂、并发超扣、退款权益难回滚、门禁权限不同步的问题。模块适配西安本地自助健身房、私教工作室的运营模式,兼顾单店轻量化部署和连锁多门店隔离管控,为入场核销、续费转化、财务对账提供统一的数据底座。