企业内部自用 · 单租户 · 一期

实时网页聊天、坐席分配、管理后台与数据看板,
整个系统只有一个二进制和一个 MySQL

访客在网页上点开聊天窗,系统按「粘性优先 → 最少负载 → 轮询兜底」把会话派给空闲坐席; 坐席在工作台实时对话、转接、用快捷回复;管理员在后台看数据、管坐席、查会话。 不引入 Redis、不引入消息队列、不需要 nginx —— 前端产物用 embed.FS 打进二进制,由 Go 自己 serve。

首次使用?点击下方三端入口即可直接体验。

1 个Go 二进制,含全部前端产物
1 个MySQL 8,六张业务表 + 迁移表
0 个Redis / 消息队列 / nginx
9 KB可嵌入第三方站点的访客 SDK

三端入口

系统由三个相互独立的前端组成,共享同一套后端接口与账号体系。点击按钮直接进入。

坐席工作台

/agent/ · 坐席处理会话的地方

登录后保持「在线」即可接收系统派发的会话。

  • 实时会话列表,带状态标签与最后一条消息预览
  • 在线 / 忙碌 / 暂离状态切换,决定是否被分配新会话
  • 双向聊天:WebSocket 推送,连不上自动退回 HTTP
  • 会话转接给其他坐席、快捷回复一键插入
  • 「正在输入」提示、连接状态指示灯、结束会话
打开坐席工作台

管理后台

/admin/ · 数据与配置

需要管理员角色(role=2),普通坐席账号会被拦下。

  • 数据看板:排队中 / 进行中 / 今日新建 / 今日结束 / 在线坐席 / 平均满意度
  • 7 天会话量趋势、平均首响、平均会话时长、坐席工作量报表
  • 坐席管理:新增、编辑、删除,设置角色与最大并发数
  • 会话记录检索与快捷回复库维护
打开管理后台

访客端 SDK

/sdk/ · 示例页与可嵌入脚本

进去后点右下角悬浮气泡,就是一个真实的访客会话。

  • 匿名身份:不注册不登录,用 localStorage 里的匿名 ID 换 token
  • 断线重连 + 消息补拉(after_seq),消息先落库再确认
  • 满意度评价、移动端 H5 适配(键盘弹起 / iOS 安全区)
  • 样式隔离在 Shadow DOM 里,一行 script 即可嵌入第三方站点
打开访客端示例

系统能力

以下都是已经实现并在跑的机制,不是规划中的功能。

01消息可靠性三件套

消息先写 MySQL 拿到自增主键作为 seq 再推送;client_msg_id 唯一索引做幂等; 客户端记录 lastSeq,重连后带 after_seq 补拉差额。

02会话分配引擎

粘性优先(24 小时内服务过该访客的坐席)→ 最少负载 → 轮询兜底。抢会话靠 UPDATE ... WHERE status='waiting' 影响行数判定,并发下不会一客多接。

03无中间件架构

在线状态就是内存里的连接表;等待队列是进程内队列;消息序号直接用数据库自增主键。 单进程下 Redis 的收益约等于零,所以不引入。

04自动迁移与建库

内置迁移器,SQL 以 embed 方式编译进二进制,按版本记录在 schema_migrations。首次启动自动建库建表,无需外部迁移 CLI。

05后台自动清理

排队超过 5 分钟无人接待会提示留言并结束;进行中 30 分钟无动静自动结束以释放坐席名额。 每 30 秒一跳。

06渲染层安全

三端渲染消息一律只用 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
/本首页
/agent/坐席工作台
/admin/管理后台(需管理员)
/sdk/访客端示例页
/sdk/chat.js可嵌入第三方站点的 SDK 单文件
/healthz健康检查(含数据库连通性、在线连接数)
/ws?token=...WebSocket,坐席与访客共用同一端点