Files
kefu_cloud/README.md
T

286 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 客服云(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 |
| 存储 | MinIOS3 兼容),图片转 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/` 平台端页面
---
## 许可证
内部项目 / 按团队约定使用。未单独声明开源协议时,默认保留所有权利。