ff3a058f290017f22bf560ef5bc621ebe2ee5e88
客服云(kefu_cloud)
多租户在线客服 SaaS:租户坐席工作台 + 访客 Widget + 平台超管后台。
消息模型为 HTTP 落库 + WebSocket 实时推送;图片经对象存储(MinIO / S3 兼容)上传后以 URL 入消息。
功能总览
租户侧(坐席 / 主管 / 租户管理员)
| 模块 | 能力 |
|---|---|
| 工作台 | 会话列表、领取/转接/结束、文字与图片、输入中提示、内部备注、知识库快捷引用 |
| 实时通信 | 客服/访客 WebSocket(ws/wss);推送可直接上屏;断线重连后按 seq 增量同步 |
| 访客 Widget | 嵌入脚本、欢迎语、离线留言、结束评价(星级+快捷评语)、重新咨询 |
| 客户管理 | 客户档案、标签、历史会话、CSV 导出 |
| 对话记录 | 筛选、归档、详情回放、CSV 导出 |
| 知识库 | 分类树 CRUD、条目管理 |
| 数据统计 | KPI、趋势、响应分布、渠道分布、坐席绩效、CSV 报告导出 |
| 系统设置 | 基本信息、渠道与嵌入代码、坐席账号/配额、自动分配策略、欢迎语/工作时间/通知 |
平台侧(platform_admin)
| 模块 | 能力 |
|---|---|
| 运营概览 | 租户量、套餐分布、增长等 |
| 租户管理 | 开通/暂停/恢复、联系人与套餐 |
| 套餐定价 | 套餐 CRUD |
| 系统运维 | 真实 metrics(CPU/内存/磁盘、24h 请求量与错误率、DB/WS/对象存储探测)、操作日志、平台公告 |
分配与会话
- 自动分配(可配置):
least_load(负载最低)/round_robin(轮询) - 最大并发:每位坐席
active会话上限(0 = 不限) - 人工:领取、转接(事件记录操作人与目标)、结束与评价
技术架构
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ React + Vite │────▶│ Gin API :8080 │────▶│ PostgreSQL │
│ Antd/Tailwind │ WS │ JWT 多租户 │ │ (开发 :5433) │
│ :5173 │◀────│ Hub 内存广播 │ └─────────────────┘
└─────────────────┘ │ metrics 中间件 │
└────────┬─────────┘
│
▼
┌─────────────────┐
│ MinIO / S3 │
│ (开发 :9100) │
└─────────────────┘
| 层 | 选型 |
|---|---|
| 前端 | React 19、Vite 8、Ant Design 6、Tailwind 4、React Router |
| 后端 | Go、Gin、GORM、JWT、Gorilla WebSocket |
| 数据库 | PostgreSQL(生产/开发主库);测试可用 SQLite |
| 存储 | MinIO(S3 兼容),图片转 WebP |
| 实时 | 进程内 WebSocket Hub(单实例;多副本需后续 Redis 广播) |
消息链路(简要)
发送方 ──POST 消息/上传──▶ API 落库(seq 单调)
│
├── WebSocket type=message 推送(可带消息体)
└── 对端追加或 after_seq 增量拉取
- 客服:
/api/ws(子协议鉴权) - 访客:
/api/widget/ws?session_id=…(访客 token) - 图片:先
/uploads或/widget/upload,再type=image+ URL
目录结构
kefu_cloud/ # 仓库目录名(本地可能仍为旧名,以模块名为准)
├── docker-compose.dev.yml # Postgres + MinIO
├── Makefile
├── docs/ # 产品原型 / 需求 HTML
├── server/ # Go module: kefu-cloud/server
│ ├── cmd/main.go # 服务入口
│ ├── cmd/seed/ # 演示数据
│ └── internal/
│ ├── config/ # 环境变量配置
│ ├── handler/ # HTTP / Widget / 导出 / 分配
│ ├── metrics/ # 请求统计与运维指标
│ ├── middleware/ # JWT / 平台权限
│ ├── model/ # GORM 模型与消息序号
│ ├── storage/ # 对象存储抽象
│ └── ws/ # WebSocket Hub
└── web/
├── public/widget.js # 嵌入脚本入口
└── src/
├── pages/agent/ # 租户工作台等
├── pages/admin/ # 平台后台
├── widgets/ # 访客聊天组件
└── services/ # API 与 CSV 下载
生产部署(腾讯云 Docker)
单机一键部署(应用内 Nginx + API + PostgreSQL + MinIO)。默认宿主机端口 18080,便于与已有 Caddy(80/443) 共存:
# 服务器安装 Docker 后
chmod +x deploy/scripts/*.sh
./deploy/scripts/deploy.sh # 首次会生成 deploy/.env.prod,请改域名与密钥
./deploy/scripts/deploy.sh --seed # 可选:导入演示账号
说明见 deploy/README.md(Caddy 共存、安全组、HTTPS、COS、备份升级)。Caddy 站点示例:deploy/caddy/Caddyfile.example。
本地开发
环境要求
- Go 1.22+(仓库
go.mod声明见server/go.mod) - Node.js 20+
- Docker(数据库与 MinIO)
1. 基础设施
make db-up
# 或:docker compose -f docker-compose.dev.yml up -d
| 服务 | 地址 |
|---|---|
| PostgreSQL | localhost:5433(用户/库/密码见下表) |
| MinIO API | http://localhost:9100 |
| MinIO 控制台 | http://localhost:9101(minioadmin / minioadmin) |
2. 后端
cd server
go mod download
go run ./cmd/main.go
# 默认 :8080
首次启动会 AutoMigrate。可选种子数据:
cd server && go run ./cmd/seed
3. 前端
cd web
npm install
npm run dev
# 默认 http://localhost:5173 ,/api 与 WS 代理到 :8080
4. 一键(Makefile)
make install # 前后端依赖
make db-up
# 再分别启动后端与前端,或使用 make dev(按需调整)
默认账号(seed 后)
| 角色 | 用户名 | 密码 |
|---|---|---|
| 平台管理员 | platform_admin |
kefu_admin123 |
| 租户管理员 | kefu_admin |
kefu_admin123 |
| 主管 | supervisor |
kefu_admin123 |
| 坐席 | agent1 / agent2 / agent3 |
kefu_admin123 |
常用入口
| 地址 | 说明 |
|---|---|
| http://localhost:5173/login | 登录 |
| http://localhost:5173/agent/dashboard | 客服工作台 |
| http://localhost:5173/admin | 平台后台 |
| http://localhost:5173/widget/preview | 访客 Widget 预览 |
| 渠道嵌入 | 设置 → 渠道管理 → 复制 script(data-id 为 channel_key) |
主要环境变量
后端通过环境变量加载(可 server/.env 配合 shell set -a):
| 变量 | 默认 | 说明 |
|---|---|---|
SERVER_PORT |
8080 |
HTTP 端口 |
GIN_MODE |
debug |
Gin 模式 |
DB_HOST / DB_PORT |
localhost / 5433 |
数据库 |
DB_USER / DB_PASSWORD / DB_NAME |
postgres / postgres / kefu_cloud |
|
JWT_SECRET |
内置开发密钥 | 生产务必修改 |
STORAGE_ENDPOINT |
localhost:9100 |
MinIO/S3 |
STORAGE_ACCESS_KEY / STORAGE_SECRET_KEY |
minioadmin |
|
STORAGE_BUCKET |
kefu |
|
STORAGE_PUBLIC_BASE_URL |
http://localhost:9100/kefu |
浏览器访问前缀 |
角色与权限(概要)
| 角色 | 范围 |
|---|---|
platform_admin |
平台租户/套餐/运维(TenantID=0) |
admin |
租户管理员:设置、坐席、全量会话等 |
supervisor |
主管:统计、客户、会话监管 |
agent |
一线:本人会话 + 排队领取;客户可见范围为相关会话客户 |
Widget 访客使用 visitor_token,与会话绑定,不走 JWT 坐席体系。
API 分组(摘录)
| 前缀 | 说明 |
|---|---|
POST /api/login |
登录 |
/api/widget/* |
访客 init/消息/留言/评价/上传/WS |
/api/ws |
坐席 WebSocket |
/api/sessions/* |
会话、消息、after_seq 增量、导出 |
/api/customers/* |
客户 CRUD、导出 |
/api/statistics/* |
统计与导出 |
/api/settings |
租户设置(含分配策略) |
/api/staff |
坐席账号 |
/api/admin/* |
平台管理 + ops/metrics |
GET /health |
健康检查 |
完整路由见 server/internal/handler/router.go。
测试
cd server && go test ./...
cd web && npx tsc --noEmit
集成测试覆盖鉴权隔离、自动分配、转接、Widget 等(handler 包内)。
产品现状与后续方向
已具备(适合演示 / 中小单实例)
- 完整接待闭环:进线 → 分配 → 聊天 → 转接/结束 → 评价 → 重新咨询
- 租户隔离、坐席配额、知识库、统计与 CSV 导出
- 运维页进程级真实负载与请求错误率
- 分配策略可配置(负载最低 / 轮询 + 并发上限)
已知边界(有意未做或单实例限制)
| 项 | 说明 |
|---|---|
| 多 API 实例 | Hub 为进程内存;扩副本需 Redis Pub/Sub 等跨节点广播 |
| 独立消息队列 | 当前不需要;实时靠 WS Hub |
| 技能组 / 渠道专属坐席 | 未做;可在候选过滤层扩展 |
| 厂商推送(APNs/FCM) | 未做 |
| 微信/APP/电话渠道 | 模型预留,完整对接未做 |
建议演进顺序
- 生产配置加固(JWT、HTTPS、存储与 DB 备份)
- 需要水平扩展时:Redis 会话广播 + sticky 或共享连接层
- 技能组 / 渠道路由
- 监控可对接 Prometheus(现有 metrics 可作过渡)
设计稿与需求
docs/ 下保留各页面 HTML 原型与需求说明:
docs/spec/开发需求docs/agent/租户端页面docs/admin/平台端页面
许可证
内部项目 / 按团队约定使用。未单独声明开源协议时,默认保留所有权利。
Languages
TypeScript
55.8%
Go
39.3%
Shell
2.4%
HTML
1.6%
JavaScript
0.6%
Other
0.2%