首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >健身管理系统开发实战:消息通知、预约排队、售后工单模块

健身管理系统开发实战:消息通知、预约排队、售后工单模块

原创
作者头像
面芽科技
发布于 2026-11-04 16:54:05
发布于 2026-11-04 16:54:05
1190
举报

健身管理系统开发实战:消息通知、预约排队、售后工单模块

一、业务痛点分析

健身房系统在落地时,经常遇到三类典型问题。消息推送杂乱无章,重复推送、消息丢失、课前提醒失效,会员错过课程;预约模块在课程满员后缺少排队替补机制,有人取消预约时空位无法自动流转,资源利用率低;设备报修、会员投诉没有标准化工单流程,问题口头传递、处理进度无法追溯,售后闭环难以形成。 这三个模块存在强联动关系:预约变更、排队替补、工单状态变更都需要触发消息通知,单独开发很容易出现状态不一致、并发超卖、消息幂等性失效等问题,需要统一事件驱动模型来串联。

二、消息通知模块设计与实现

消息通知采用事件驱动架构,不与业务主流程强耦合,使用消息队列异步消费,支持站内消息、小程序模板消息、短信多渠道分发,同时做幂等、重试、消息模板管理。 核心设计要点:事件源统一发布通知事件,通知服务做渠道分发、消息持久化、已读状态管理;增加消息防重表,基于业务唯一key防止重复推送;失败消息进入死信队列,支持后台重发。

代码语言:javascript
复制
@Service
public class FitnessNotifyService {
    @Autowired
    private NotifyRecordMapper notifyRecordMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendNotify(NotifyEvent event) {
        // 幂等校验,防止重复发送
        LambdaQueryWrapper<NotifyRecord> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(NotifyRecord::getBizKey, event.getBizKey());
        if (notifyRecordMapper.selectCount(wrapper) > 0) {
            return;
        }
        // 持久化通知记录
        NotifyRecord record = new NotifyRecord();
        record.setUserId(event.getUserId());
        record.setBizType(event.getBizType());
        record.setBizKey(event.getBizKey());
        record.setContent(event.getContent());
        record.setStatus(0);
        notifyRecordMapper.insert(record);
        // 投递消息队列异步推送
        rabbitTemplate.convertAndSend("fitness.notify.exchange", "notify.send", event);
    }
}

通知场景覆盖:预约成功通知、课前定时提醒、排队替补成功通知、售后工单接单/完结通知。定时提醒可以结合延时队列实现,避免定时轮询数据库带来的性能损耗。

三、预约排队模块设计与实现

预约排队分为预约主流程和候补排队流程。预约时先校验课程容量,余量充足直接生成预约单;课程已满,则加入FIFO候补队列,存入Redis有序集合,保证排队顺序。 当已有会员取消预约,系统释放名额,自动取出队首候补用户,自动转正预约并触发通知事件。这里必须使用分布式锁,防止并发取消、并发转正造成超卖。

代码语言:javascript
复制
@Service
public class CourseBookingService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private FitnessNotifyService notifyService;

    public void booking(Long courseId, Long userId) {
        String lockKey = "course:booking:lock:" + courseId;
        RLock lock = redissonClient.getLock(lockKey);
        try {
            lock.lock(5, TimeUnit.SECONDS);
            CourseInfo course = getCourseById(courseId);
            Long bookedCount = getBookedCount(courseId);
            if (bookedCount < course.getMaxNum()) {
                // 直接预约成功
                createBookingOrder(courseId, userId);
                notifyService.sendNotify(buildSuccessEvent(courseId, userId));
            } else {
                // 进入候补排队
                String queueKey = "course:wait:" + courseId;
                redisTemplate.opsForZSet().add(queueKey, userId.toString(), System.currentTimeMillis());
                notifyService.sendNotify(buildWaitEvent(courseId, userId));
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

候补队列需要设置有效期,超过开课时间自动清理队列,避免无效数据堆积。同时支持会员主动退出排队,删除Redis队列内对应记录。

四、售后工单模块设计与实现

售后工单用于处理健身器械故障报修、会员服务投诉、场地问题反馈,完整生命周期:工单创建、分派、接单、处理、复核、完结、关闭。 状态流转控制:新建→待分派→已接单→处理中→待复核→已完结,支持驳回重新处理,所有状态变更记录日志,每次状态变更都推送消息通知对应会员和处理人员。 工单支持自动分派和手动派单两种模式,自动分派可以根据处理人员负载、擅长类型进行路由。

代码语言:javascript
复制
@Service
public class WorkOrderService {
    @Autowired
    private WorkOrderMapper orderMapper;
    @Autowired
    private FitnessNotifyService notifyService;

    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(Long orderId, Integer status, Long operatorId) {
        WorkOrder order = orderMapper.selectById(orderId);
        // 状态机校验,非法状态流转直接拦截
        if (!checkStatusFlow(order.getStatus(), status)) {
            throw new RuntimeException("工单状态流转不合法");
        }
        order.setStatus(status);
        order.setOperatorId(operatorId);
        orderMapper.updateById(order);
        // 状态变更触发通知
        notifyService.sendNotify(buildOrderEvent(order));
    }
}

工单表除基础描述、故障类型、图片附件字段外,保留状态变更日志表,用于后续统计工单响应时长、故障类型分布,辅助场馆运维优化。

五、模块联动与落地注意事项

三个模块共用一套事件发布能力,预约转正、工单状态变更作为事件源,统一交给通知模块消费。开发时需要重点关注并发安全:预约扣减、名额释放、候补转正全部加分布式锁;消息通知做好幂等,避免重复推送;延时任务做好补偿,防止MQ消息丢失导致课前提醒漏发。 数据库层面,预约单、工单、通知记录做好分库索引,课程ID、用户ID作为高频查询字段建立索引;Redis只做排队队列、热点容量缓存,核心业务数据持久落库。 测试重点覆盖高并发场景:多人同时取消预约、候补队列连续转正、短时间大量报修工单提交,验证是否存在超约、消息风暴、工单状态错乱问题。

六、总结

健身管理系统里消息通知、预约排队、售后工单是支撑场馆运营的核心业务模块,三者不是独立功能,而是依靠事件驱动机制串联起来。消息通知模块作为基础设施,统一承载各类业务变更的触达能力;预约排队解决课程资源高效复用,降低空课率;售后工单完成会员问题闭环,沉淀运维数据。 在技术实现上,通过MQ异步解耦、Redis实现排队队列、分布式锁保障并发安全、状态机管控工单流转,能够在保证性能的前提下,规避超卖、消息重复、状态异常等常见问题。这套方案可以直接复用在私教预约、团课管理、场地预约等场景,在后续迭代中,可以在此基础上叠加智能排班、工单SLA超时预警等能力,持续完善整套健身管理系统。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 健身管理系统开发实战:消息通知、预约排队、售后工单模块
    • 一、业务痛点分析
    • 二、消息通知模块设计与实现
    • 三、预约排队模块设计与实现
    • 四、售后工单模块设计与实现
    • 五、模块联动与落地注意事项
    • 六、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档