第 3 / 8 篇
整理于 · 8 分钟
报名方式为什么逐步变复杂
常规选课、插班动态计价与一对一定制开班的业务演进
报名主线中保留九月并发编号与付款事务的后续修正。
贯穿项目的约定 本篇涉及 3 条
在培训机构的商业模型中,让学员完成报名的路径远不止“点击购买”那么简单。
随着业务的展开,系统必须同时应对至少三种截然不同的招生场景:
- 常规开班报名:新学期开课前,班级尚未开课,学员按整门课程全款购买;
- 插班报名(Mid-Term Enrollment):学期已过半但班级尚有空位,新学员希望中途加入,只按剩余课时付费;
- 定制一对一(1-on-1):学员提出专属学习诉求,管理员定制报价、安排专属教师,并在学员付款成功后动态生成班级与排课通道。
这些场景让报名不再是一次选课写入。系统需要分别处理订单期限、购买课时和付款后建课。
1. 常规报名:30 分钟订单状态机
常规报名处理尚未开课班级的选课。待付款订单只记录购买意向,付款成功后才形成选课权益:
- 30 分钟付款有效窗口:生成订单不预占班级名额。付款时仍要检查容量,满员时不能继续付款;后台定时任务关闭超时未付订单,也不需要释放预留名额。
- 倒计时保持原期限:前端弹窗关闭后再次打开该订单,倒计时依据后端剩余秒数,不因重新打开弹窗而重置为 30 分钟。
2. 插班报名:按剩余课时动态计价与名额穿透
当一个班级已经开课数周,但班型名额仍有富余时,机构通常允许新学员“插班”学习。插班学员显然不应当为已经结束的课时支付全款。
系统确立了插班比例计价与场地级容量校验规则:
2.1 课时剔除与次日生效
-
计价公式:系统自动统计该班级未来尚未开始的剩余课时数,按比例折算报名费用:
插班应付金额=课程标准全价×未来剩余课时数课程标准总课时 -
次日生效原则:若插班报名发生在当天,当天的课次被视为已经完成,学员从次日开始的课次正式参与考勤与上课。
2.2 课次级教室容量校验
插班不仅增加了班级总人数,还会直接增加未来每一次课的实际到场人数。
系统在插班提交时,不仅校验班型招生上限,还会逐一扫描该班级未来所有已排课次的教室座位容量。一旦发现某次课的原教室无法多容纳一人,系统会明确提示教务需为该课次调整大教室,防止出现学生到场后“无座可坐”的尴尬事故。
3. 一对一流程:为什么必须独立建轨?
班课先开班再招生,一对一则先有学员诉求,再确定教师与价格,付款后正式建班。因此,一对一申请时还没有现成班级可供报名,需要单独处理报价、付款与建课的先后关系。
系统为一对一量身定制了定制申请与付款建课链路:
3.1 付款后建课与即刻排课
只有当学员完成付款后,系统才在同一数据库事务中原子创建专属开班实例(CourseInstance),并将学员写入选课表(StudentCourse)。
同时,系统将该一对一课程的开课日期默认设为付款当天,允许管理员在付款完成后进入排课工作台安排课程,不再因默认开课日期而额外等待;具体安排仍需满足时间、教师与教室条件。
3.2 一对一自动班号递增的并发修复
自动建课还需要处理两个编号风险:
- 并发重复编号:两个请求若同时读取相同的最大班号并递增,可能分配出相同编号;
- 字符串排序陷阱:数字后缀跨越 99 后,字符串排序与数字大小不同,可能重复生成 100。
9 月重构引入了模板级锁与数字后缀递增规则。同一模板的自动编号分配先获取模板行锁,再读取已提交的班号,按数字后缀最大值递增。已有一对一付款等外层事务也使用 READ_COMMITTED,避免等待锁之后仍读取旧快照。超范围数字明确返回冲突,不回退到 1;隔离测试覆盖了模板锁竞争和 99、100 之后的递增。后续新增建课入口仍需遵守这些前提。
3.3 支付身份的显式限制
在当前的业务安全边界中,普通班课与插班支持由授权绑定的家长使用自己的钱包完成代付;但对于定制一对一课程,系统在现阶段严格限制仅允许学员本人账户进行付款核销,服务端对传入的非学员付款身份进行显式拦截。
常规报名解决订单期限与付款时的名额检查,插班增加剩余课时计价,一对一则把建课放到付款之后。三条流程各自保留业务限制,后续的支付与退款验证也需要分别覆盖它们。