营业厅类场景(通信营业厅、政务分厅、银行网点)的小程序核心是"让到场时间精确化":用户远程取号、预估等待、快到号再出发,到场后叫号系统联动。本文给出排队取号的服务端设计要点,示例基于 Node.js + MySQL 8 + Redis。
排队系统的基础模型是"网点 × 业务类型 × 队列"。不同业务办理时长差异极大(补卡十分钟、销户可能半小时),混在一个队列里会拖慢整体,因此按业务类型分队列,窗口配置可办理的业务集合:
CREATE TABLE queue_ticket (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
branch_id BIGINT NOT NULL,
biz_type VARCHAR(20) NOT NULL COMMENT '业务类型编码',
ticket_no VARCHAR(10) NOT NULL COMMENT '票号,如 A036',
user_id BIGINT NULL COMMENT '远程取号的用户,现场取号为 NULL',
status TINYINT NOT NULL DEFAULT 1
COMMENT '1等待 2办理中 3已完成 4过号 5已撤销',
issued_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
called_at DATETIME NULL,
done_at DATETIME NULL,
counter_no VARCHAR(10) NULL COMMENT '办理窗口',
UNIQUE KEY uk_branch_ticket (branch_id, ticket_no),
KEY idx_waiting (branch_id, biz_type, status, issued_at)
);票号生成规则:按业务类型前缀 + 当日自增序号,uk_branch_ticket 保证不重号。远程取号与现场取号写同一张表,叫号端(窗口 PAD 或叫号屏)只认这一张表,两类来源天然公平。
过号是排队系统里规则最微妙的地方。用户远程取号后被堵在路上,到号了没到,系统叫号无人应答——这一单怎么处理?
直接作废体验太差,无限顺延又会堵塞队列。常见做法是"过号顺延 + 有限次重叫":叫号两次无人应答置为过号,过号的票插入队列尾部优先位(比新取号的人靠前),并设置重新应答时限(如 10 分钟内到扫码签到可保留优先)。这个规则要做成配置,因为不同网点客流特征不同,高峰期网点会把过号优先位取消以保证队列吞吐。
关键实现是状态迁移的条件更新,杜绝并发下的双重办理:
UPDATE queue_ticket
SET status = 2, called_at = NOW(), counter_no = '3号窗口'
WHERE id = ? AND status = 1;受影响行数为 0 说明已被叫走或已过号,窗口端提示重取下一张。叫号、过号、完成三个动作全部走条件更新,这是并发正确性的底线。
用户最关心"还要等多久"。估算逻辑建议用滚动统计而不是理论公式:取该网点该业务类型最近 20 单的实际办理时长均值,乘以当前前方等待人数。高峰时段均值会拉长,滚动窗口天然适应。
预估显示要克制两点:一是预估时间不要精确到分钟("约还需等待 25 分钟"),精确数字错了会被截图投诉;二是排队人数和预估时长要分钟级刷新,数据陈旧比没有更伤信任。
营业厅体验差评的头号来源不是排队久,是"排到了发现材料不全"。业务预审模块的价值就在这里:用户选业务后,小程序列出材料清单与办理条件,用户逐项自查确认后才允许远程取号。
更进一步的做法是线上预填:销户、过户这类业务涉及的表单字段,用户在家填好,到场后窗口调出预填单确认即可。预填数据存草稿态,有效期设 7 天,超期自动作废(业务规则可能变化,旧数据不可直接使用)。
预审清单要做成配置而不是写死在页面里:不同地区、不同时期的材料要求不同,运营可改的清单才是活的清单。
多网点的一致性也值得注意。连锁品牌下多个营业厅,用户在 A 厅办到一半的业务,第二天到 B 厅能不能续办?这要求业务预填、办件进度等数据按"客户 + 业务"维度集中存储,网点只是办理入口。设计时把"网点"当作队列和库存的归属维度,而把"办件"建为客户维度的单据,两层分离后,跨网点续办、异地进度查询这类需求都是顺带的能力,反过来先按网点建库,后面迁移就是大工程。
微信订阅消息一次授权发一条,而排队场景天然需要多次通知(取号成功、前方还有 3 位、过号提醒)。配额省着用的策略:
- 授权请求放在取号成功页(意愿最强的时刻),此时拿到的一条配额留给"前方还有 3 位"的关键节点;- "过号提醒"这类低概率事件不值得预占配额,改为小程序内横幅 + 到店叫号屏双重兜底;- 剩余等待人数用小程序内的轮询或页面刷新展示,不消耗消息配额。
过号策略的几种常见配置,取舍各有不同:
策略 | 用户体验 | 队列吞吐 | 适用网点 |
|---|---|---|---|
过号作废,重新取号 | 差,等于惩罚迟到 | 最高 | 高峰期人流极大的网点 |
过号插队尾优先位,限时保留 | 较好,给迟到者机会 | 较高 | 常规网点(多数场景默认) |
过号自动顺延三次重叫 | 最好,但队列空转多 | 低 | 人流稀疏、以老年客户为主的网点 |
配置切换要即时生效且只影响新票,已发出的票按取号时的规则走,避免同一张票前后规则不一致引发争议。
排队数据的运营价值在报表侧兑现:各业务类型的时段分布(用于排班)、平均办理时长(用于窗口配置)、过号率(用于规则调整)。一个常用的统计口径示例:
SELECT biz_type,
DATE_FORMAT(issued_at, '%H') AS hour_slot,
COUNT(*) AS total,
SUM(status = 4) AS skipped,
AVG(TIMESTAMPDIFF(SECOND, called_at, done_at)) AS avg_handle_sec
FROM queue_ticket
WHERE branch_id = ? AND issued_at >= CURDATE() - INTERVAL 30 DAY
GROUP BY biz_type, hour_slot;注意 avg_handle_sec 用 called_at 到 done_at 而不是取号到完成——前者是纯办理时长,后者混入了等待时间,调度决策要的是前者。
营业厅排队系统的四个要点:队列按业务类型拆分、状态迁移全走条件更新、过号规则做成配置、预审把材料问题挡到场外。技术上没有高深的东西,难点全在规则细节与并发正确性上。青海青帝信息科技有限公司在本地政务与通信类项目里的经验是:排队系统上线后第一个月,过号规则一定还会调两三轮——把它做成配置项,运营自己就能改,比每次改代码发版体面得多。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。