坐席工作台
登录后保持「在线」即可接收系统派发的会话。
- 实时会话列表,带状态标签与最后一条消息预览
- 在线 / 忙碌 / 暂离状态切换,决定是否被分配新会话
- 双向聊天:WebSocket 推送,连不上自动退回 HTTP
- 会话转接给其他坐席、快捷回复一键插入
- 「正在输入」提示、连接状态指示灯、结束会话
系统由三个相互独立的前端组成,共享同一套后端接口与账号体系。点击按钮直接进入。
登录后保持「在线」即可接收系统派发的会话。
需要管理员角色(role=2),普通坐席账号会被拦下。
进去后点右下角悬浮气泡,就是一个真实的访客会话。
以下都是已经实现并在跑的机制,不是规划中的功能。
消息先写 MySQL 拿到自增主键作为 seq 再推送;client_msg_id 唯一索引做幂等;
客户端记录 lastSeq,重连后带 after_seq 补拉差额。
粘性优先(24 小时内服务过该访客的坐席)→ 最少负载 → 轮询兜底。抢会话靠
UPDATE ... WHERE status='waiting' 影响行数判定,并发下不会一客多接。
在线状态就是内存里的连接表;等待队列是进程内队列;消息序号直接用数据库自增主键。 单进程下 Redis 的收益约等于零,所以不引入。
内置迁移器,SQL 以 embed 方式编译进二进制,按版本记录在
schema_migrations。首次启动自动建库建表,无需外部迁移 CLI。
排队超过 5 分钟无人接待会提示留言并结束;进行中 30 分钟无动静自动结束以释放坐席名额。 每 30 秒一跳。
三端渲染消息一律只用 textContent,不碰 innerHTML。
消息表已预留 content_type 与 extra,将来加图片不需要改表也不会引入 XSS。
配置分两份:config.yaml 用于部署环境;本地开发把
config.local.yaml.example 复制成 config.local.yaml,填自己的库地址。
环境变量优先级更高。
# 1. 本地开发:先准备自己的配置(只需做一次) cp config.local.yaml.example config.local.yaml # 2. 起服务(首次启动会自动建库 + 跑迁移 + 播种管理员) make run # 自动优先用 config.local.yaml # 3. 健康检查(会真的 ping 一次数据库) make health # 4. 换端口 / 换库,不用改文件 $env:APP_PORT = "8081" $env:DB_PASSWORD = "..." # 5. 改了前端之后:构建 → 同步进 embed 目录 → 重新编译 make web ; make web-sync ; make build