286 lines
9.4 KiB
Markdown
286 lines
9.4 KiB
Markdown
# 客服云(kefu_sys)
|
||
|
||
多租户在线客服 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_sys/
|
||
├── docker-compose.dev.yml # Postgres + MinIO
|
||
├── Makefile
|
||
├── docs/ # 产品原型 / 需求 HTML
|
||
├── 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 下载
|
||
```
|
||
|
||
---
|
||
|
||
## 本地开发
|
||
|
||
### 环境要求
|
||
|
||
- Go 1.22+(仓库 `go.mod` 声明见 `server/go.mod`)
|
||
- Node.js 20+
|
||
- Docker(数据库与 MinIO)
|
||
|
||
### 1. 基础设施
|
||
|
||
```bash
|
||
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. 后端
|
||
|
||
```bash
|
||
cd server
|
||
go mod download
|
||
go run ./cmd/main.go
|
||
# 默认 :8080
|
||
```
|
||
|
||
首次启动会 AutoMigrate。可选种子数据:
|
||
|
||
```bash
|
||
cd server && go run ./cmd/seed
|
||
```
|
||
|
||
### 3. 前端
|
||
|
||
```bash
|
||
cd web
|
||
npm install
|
||
npm run dev
|
||
# 默认 http://localhost:5173 ,/api 与 WS 代理到 :8080
|
||
```
|
||
|
||
### 4. 一键(Makefile)
|
||
|
||
```bash
|
||
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_sys` | |
|
||
| `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`。
|
||
|
||
---
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
cd server && go test ./...
|
||
cd web && npx tsc --noEmit
|
||
```
|
||
|
||
集成测试覆盖鉴权隔离、自动分配、转接、Widget 等(`handler` 包内)。
|
||
|
||
---
|
||
|
||
## 产品现状与后续方向
|
||
|
||
### 已具备(适合演示 / 中小单实例)
|
||
|
||
- 完整接待闭环:进线 → 分配 → 聊天 → 转接/结束 → 评价 → 重新咨询
|
||
- 租户隔离、坐席配额、知识库、统计与 CSV 导出
|
||
- 运维页进程级真实负载与请求错误率
|
||
- 分配策略可配置(负载最低 / 轮询 + 并发上限)
|
||
|
||
### 已知边界(有意未做或单实例限制)
|
||
|
||
| 项 | 说明 |
|
||
|----|------|
|
||
| 多 API 实例 | Hub 为进程内存;扩副本需 Redis Pub/Sub 等跨节点广播 |
|
||
| 独立消息队列 | 当前不需要;实时靠 WS Hub |
|
||
| 技能组 / 渠道专属坐席 | 未做;可在候选过滤层扩展 |
|
||
| 厂商推送(APNs/FCM) | 未做 |
|
||
| 微信/APP/电话渠道 | 模型预留,完整对接未做 |
|
||
|
||
### 建议演进顺序
|
||
|
||
1. 生产配置加固(JWT、HTTPS、存储与 DB 备份)
|
||
2. 需要水平扩展时:Redis 会话广播 + sticky 或共享连接层
|
||
3. 技能组 / 渠道路由
|
||
4. 监控可对接 Prometheus(现有 metrics 可作过渡)
|
||
|
||
---
|
||
|
||
## 设计稿与需求
|
||
|
||
`docs/` 下保留各页面 HTML 原型与需求说明:
|
||
|
||
- `docs/spec/` 开发需求
|
||
- `docs/agent/` 租户端页面
|
||
- `docs/admin/` 平台端页面
|
||
|
||
---
|
||
|
||
## 许可证
|
||
|
||
内部项目 / 按团队约定使用。未单独声明开源协议时,默认保留所有权利。
|