Files
gochat/docs/product/09-enterprise-features.md
T
rogee 0dabb8cfa5 docs: 整理文档目录结构 — 清理过时文档、归集功能子目录、统一命名规范
清理:
- 删除 34 份过时文档(gap reports/QA临时报告/验收报告/阶段性文档)
- 删除 docs/.hermes/skills 第三方 skills 副本(16 文件)
- 删除 skills-lock.json

目录归集:
- 根目录仅保留 README.md 索引
- product/ — 产品与架构设计(PRD + ARCHITECTURE + P2设计文档 + AI/企业路线图)
- tracking/ — Chatwoot parity 开发跟踪
- requirements/ — M01-M12 模块需求
- plans/ — 历史实现计划
- parity/ — 路由 parity 与前端契约
- qa/ — QA 报告与测试计划
- ops/ — 运维部署

命名规范:
- 全小写 kebab-case,禁止全大写文件名
- product/tracking/ops 用 NN- 序号前缀
- requirements 用 MNN- 两位零填充模块号
- plans/qa 用 YYYY-MM-DD- 日期前缀
- requirements M1-M9 零填充为 M01-M09(修复字典序)

同步更新:
- backend/cmd/route_parity/main.go 路径默认值
- backend/scripts/parity_frontend_smoke.sh 报告路径
- 所有 docs 内部交叉引用
- .gitignore 排除编译产物 (backend/gochat, backend/route_parity)
- 新增迁移 000052/000053
- 前端 WS 相关修改
2026-07-09 14:53:27 +08:00

991 lines
41 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.
# GoChat 企业功能分析文档
> 版本:v1.1
> 更新日期:2026-07-09
> 目标:Chatwoot 企业版功能深度分析 + GoChat 商业收费功能构思 + CaptainAI/SSO/语音通话等功能设计方案
> 注:本文档最初生成于 2026-05-25,当时多数企业功能标记为 "Stub/未实现"。
> 截至更新日期,SLA/AuditLog/CustomRole/Company/AgentCapacity/AssignmentPolicy/Captain/Copilot 等已实现并通过 Chatwoot parity 对齐,详见 tracking/01-chatwoot-parity-tracker.md。
---
## 目录
1. [Chatwoot 企业版功能全景分析](#一chatwoot-企业版功能全景分析)
2. [GoChat 商业收费模式构思](#二gochat-商业收费模式构思)
3. [CaptainAI 功能设计](#三captainai-功能设计)
4. [SSO 单点登录设计](#四sso-单点登录设计)
5. [语音通话功能设计](#五语音通话功能设计)
6. [企业版功能实施路线图](#六企业版功能实施路线图)
---
## 一、Chatwoot 企业版功能全景分析
### 1.1 Chatwoot 版本分层
Chatwoot 采取 **社区版(开源) + 企业版(付费)** 双轨模式:
| 版本 | 定价 | 定位 | 核心差异 |
|------|------|------|----------|
| **Community (开源)** | 免费 / 自部署 | 小团队、初创企业 | 基础客服功能,无 SLA/SSO/AI/语音 |
| **Cloud Pro** | $29/坐席/月 | 中型企业 | 云托管,含基础自动化 |
| **Cloud Enterprise** | $69/坐席/月 | 大型企业 | 全功能 + SSO + SLA + CaptainAI + 语音 |
| **Self-hosted Enterprise** | 按需报价 | 大型企业自部署 | 同 Cloud Enterprise,但自行部署 |
### 1.2 企业版独占功能清单
以下功能 **仅在 Enterprise 版本开放**,社区版无法使用:
| # | 功能 | 模块 | Chatwoot 实现 | GoChat 状态 |
|---|------|------|---------------|-------------|
| 1 | **SLA 策略** | SlaPolicy + AppliedSla + SlaEvent | 完整实现 | Stub/未实现 |
| 2 | **审计日志** | AuditLog | 完整实现 | Stub/未实现 |
| 3 | **自定义角色权限** | CustomRole | 完整实现 | Stub/未实现 |
| 4 | **公司/组织管理** | Company | 完整实现 | Stub/未实现 |
| 5 | **坐席容量策略** | AgentCapacityPolicy + InboxCapacityLimit | 完整实现 | Stub/未实现 |
| 6 | **语音通话** | Call + Voice 系列 Service | Twilio 集成 | Stub/未实现 |
| 7 | **SAML SSO** | AccountSamlSettings | 完整实现 | 部分(仅 Enable |
| 8 | **Captain AI** | Captain::Assistant + Document + Scenario | 完整实现 | 已实现 |
| 9 | **Copilot** | SuggestReplies/Summarize/Translate | 完整实现 | 已实现 |
| 10 | **定时任务调度** | SidekiqCron | 完整实现 | 未实现 |
| 11 | **自动分配策略** | AssignmentPolicy | 完整实现 | Stub/未实现 |
| 12 | **Platform App / Partner API** | PlatformApp + Permissible | 完整实现 | Stub/未实现 |
| 13 | **AgentBot 智能机器人** | AgentBot + AgentBotInbox | 完整实现 | Stub/未实现 |
| 14 | **数据导入** | DataImport + DataImportJob | 完整实现 | 未实现 |
| 15 | **多品牌 Help Center** | Portal + Category + Article | 完整实现 | Stub/未实现 |
### 1.3 Chatwoot 功能授权机制
Chatwoot 通过以下三层机制控制企业版功能:
1. **Feature Flag**`features.yml`):全局功能开关
- `enterprise` flag → 企业版总开关
- `saml` flag → SAML SSO 子开关
- `voice` flag → 语音通话子开关
2. **Billing Subscription**(云版):`InstallationConfig` + `Subscription` 模型
- 超级管理员配置订阅状态
- API 中间件检查订阅 → 未订阅则 403
3. **Policy 授权**Pundit Policy 类
- `CustomRole` → 精细化角色权限
- `AccountPolicy` → 账户级操作权限
### 1.4 GoChat 当前差距总结
基于 `Gochat-vs-Chatwoot-Full-Comparison.md` 分析:
| 维度 | Chatwoot | GoChat | 差距 |
|------|----------|--------|------|
| API 路由数 | 327+ | 106 | **缺 221+(仅 32% 覆盖)** |
| Handler 方法数 | 150+ | 99 | **缺 51+** |
| 真实实现率 | 100% | 57% | **差 43%** |
| Stub/Placeholder | 0 | 37 | **全部需补实现** |
| 501 Not Implemented | 0 | 6 | **全部需补实现** |
| 消息队列调度 | Sidekiq 完整 | WorkerPool 全 stub | **不可用** |
| 渠道扩展机制 | 11 渠道 | 仅 2 渠道 | **缺 9 渠道** |
| 事件分发 | 9 Listener | 无真实 Listener | **事件驱动完全不可用** |
---
## 二、GoChat 商业收费模式构思
### 2.1 定价策略定位
GoChat 作为 Chatwoot 的 Go 语言高性能重写,应借鉴但超越 Chatwoot 的定价模式:
**核心差异化卖点:**
- Go 语言带来的 **10x 性能优势**(并发处理、内存占用、延迟)
- 更轻量的部署架构(单二进制 vs Ruby+Sidekiq+Redis 多进程)
- 开源友好 + 自部署优先
- AI 能力原生集成(而非插件式)
### 2.2 版本分层设计
| 版本 | 定价 | 目标用户 | 功能范围 |
|------|------|----------|----------|
| **Community(开源)** | 免费 | 小团队/个人/初创 | 核心客服功能:对话、联系人、收件箱、基础渠道、基础报表 |
| **Professional** | ¥99/坐席/月($15) | 中型企业 | +自动化规则 +高级报表 +批量操作 +Email渠道 +品牌定制 |
| **Enterprise** | ¥299/坐席/月($45 | 大型企业 | +SLA +SSO +语音通话 +CaptainAI +审计日志 +自定义角色 +坐席容量 |
| **Ultimate** | ¥599/坐席/月($90) | 超大型/政府 | +全功能 +私有部署支持 +定制开发 +专属SLA保障 |
### 2.3 功能-版本矩阵
| 功能 | Community | Professional | Enterprise | Ultimate |
|------|-----------|-------------|------------|----------|
| **对话管理** | ✅ | ✅ | ✅ | ✅ |
| **联系人 CRM** | ✅ | ✅ | ✅ | ✅ |
| **收件箱(5个)** | ✅ | ✅ 20个 | ✅ 无限 | ✅ 无限 |
| **坐席数** | 5 | 20 | 无限 | 无限 |
| **Telegram 渠道** | ✅ | ✅ | ✅ | ✅ |
| **WebWidget 渠道** | ✅ | ✅ | ✅ | ✅ |
| **API 渠道** | ✅ | ✅ | ✅ | ✅ |
| **Email 渠道** | - | ✅ | ✅ | ✅ |
| **WhatsApp 渠道** | - | ✅ | ✅ | ✅ |
| **Facebook 渠道** | - | ✅ | ✅ | ✅ |
| **Instagram 渠道** | - | ✅ | ✅ | ✅ |
| **Slack 渠道** | - | - | ✅ | ✅ |
| **Line 渠道** | - | - | ✅ | ✅ |
| **语音通话** | - | - | ✅ | ✅ |
| **SLA 策略** | - | - | ✅ | ✅ |
| **SAML SSO** | - | - | ✅ | ✅ |
| **Captain AI** | - | - | ✅ | ✅ |
| **Copilot 副驾驶** | - | - | ✅ | ✅ |
| **自定义角色权限** | - | - | ✅ | ✅ |
| **审计日志** | - | - | ✅ | ✅ |
| **坐席容量管理** | - | - | ✅ | ✅ |
| **公司/组织管理** | - | ✅ 基础 | ✅ 高级 | ✅ 高级 |
| **Help Center** | - | - | ✅ | ✅ |
| **自动分配策略** | - | ✅ 基础 | ✅ 高级 | ✅ 高级 |
| **自动化规则** | - | ✅ | ✅ | ✅ |
| **批量操作** | - | ✅ | ✅ | ✅ |
| **高级报表/洞察** | - | ✅ | ✅ | ✅ |
| **实时报表** | - | ✅ | ✅ | ✅ |
| **Platform API/Partner** | - | - | - | ✅ |
| **私有部署支持** | - | - | ✅ 基础 | ✅ 专属 |
| **定制开发** | - | - | - | ✅ |
### 2.4 计费模型设计
#### 计费维度
1. **坐席数(Agent**:主计费单位,按月/年订阅
- 月付:标准价格
- 年付:8折优惠
2. **用量加价(Overage**
- 对话量超限:每 1K 对话 ¥10
- AI 调用量超限:每 1K 次 ¥5
- 存储超限:每 GB ¥2/月
3. **附加功能包(Add-on**
- CaptainAI 增强包:¥50/坐席/月(更高 AI 调用额度)
- 语音通话包:¥30/坐席/月 + Twilio 话费
- SSO 增强包:¥20/坐席/月(支持 OIDC + LDAP + SAML
#### 数据模型设计
```go
// Subscription 订阅模型
type Subscription struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
Plan string `gorm:"not null;type:varchar(20)"` // community/professional/enterprise/ultimate
BillingCycle string `gorm:"not null;type:varchar(10)"` // monthly/yearly
AgentCount int `gorm:"not null;default:5"`
StartedAt time.Time `gorm:"not null"`
ExpiresAt time.Time `gorm:"not null"`
Status string `gorm:"not null;type:varchar(20)"` // active/expired/cancelled/suspended
AutoRenew bool `gorm:"default:true"`
Addons json.RawMessage `gorm:"type:jsonb"` // [{name, quantity, unit_price}]
OverageAlert bool `gorm:"default:true"` // 用量超限是否告警
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// BillingUsage 计费用量
type BillingUsage struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
Period string `gorm:"not null;type:varchar(7)"` // 2026-05
Conversations int `gorm:"default:0"`
AICalls int `gorm:"default:0"`
StorageGB float64 `gorm:"default:0"`
VoiceMinutes float64 `gorm:"default:0"`
CreatedAt time.Time
UpdatedAt time.Time
}
// FeatureEntitlement 功能授权
type FeatureEntitlement struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;uniqueIndex"`
Plan string `gorm:"not null"`
Features json.RawMessage `gorm:"type:jsonb"` // {"sla": true, "sso": true, "voice": true, ...}
MaxInboxes int `gorm:"default:5"`
MaxAgents int `gorm:"default:5"`
AICallLimit int `gorm:"default:0"` // 月度 AI 调用上限
StorageLimitGB float64 `gorm:"default:5"`
CreatedAt time.Time
UpdatedAt time.Time
}
```
### 2.5 功能开关中间件
```go
// FeatureGate 中间件:根据订阅计划控制功能访问
func FeatureGate(requiredFeature string) gin.HandlerFunc {
return func(c *gin.Context) {
accountID := getAccountID(c)
entitlement := getFeatureEntitlement(accountID)
features := parseFeatures(entitlement.Features)
if !features[requiredFeature] {
c.JSON(403, gin.H{
"error": "Feature not available in your plan",
"feature": requiredFeature,
"plan": entitlement.Plan,
"upgrade_url": "/billing/upgrade",
})
c.Abort()
return
}
c.Next()
}
}
// 路由注册示例
router.POST("/api/v1/accounts/:id/sla_policies",
FeatureGate("sla"), // Enterprise 专属
authMiddleware(),
slaHandler.Create(),
)
router.POST("/api/v1/accounts/:id/captain/assistants",
FeatureGate("captain_ai"), // Enterprise 专属
authMiddleware(),
captainHandler.Create(),
)
```
### 2.6 GoChat vs Chatwoot 商业模式差异
| 维度 | Chatwoot | GoChat 设计 |
|------|----------|-------------|
| **定价模型** | 按坐席/月(美元) | 按坐席/月(人民币优先,支持多币种) |
| **自部署** | 免费社区版 + 企业版需购买 license | Community 免费 + Enterprise 自部署可购买 license 密钥 |
| **功能授权** | features.yml + InstallationConfig | config.yaml + FeatureEntitlement DB + FeatureGate 中间件 |
| **AI 计费** | 无独立计费(含在 Enterprise | CaptainAI 独立 Add-on 包 + 用量计费 |
| **语音计费** | 含在 Enterprise | 独立 Add-on + Twilio 话费透明 |
| **开放策略** | 企业版源码闭源 | 全源码开放 + license 密钥解锁企业功能 |
---
## 三、CaptainAI 功能设计
### 3.1 Captain AI 架构概览
Captain AI 是 GoChat 企业版的 AI 助手系统,提供两大核心能力:
1. **Captain(船长)**:AI 自动回复引擎,可绑定 Inbox 后自动处理客户咨询
2. **Copilot(副驾驶)**:AI 辅助工具,帮助坐席更快回复(建议回复、摘要、翻译)
### 3.2 功能模块拆解
| # | 子模块 | Chatwoot 对应 | 功能描述 | GoChat 实现状态 |
|---|--------|--------------|----------|-----------------|
| 1 | CaptainAssistant | Captain::Assistant | AI 助手 CRUD + Playground | ✅ 已实现 |
| 2 | CaptainDocument | Captain::Document | 知识库文档管理 | ✅ 已实现 |
| 3 | CaptainScenario | Captain::Scenario | 场景化对话流程 | ✅ 已实现 |
| 4 | CaptainCustomTool | Captain::CustomTool | 自定义 AI 工具 | ✅ 已实现 |
| 5 | CopilotSuggest | Copilot::SuggestReplies | 建议回复 | ✅ 已实现 |
| 6 | CopilotSummarize | Copilot::Summarize | 对话摘要 | ✅ 已实现 |
| 7 | CopilotTranslate | Copilot::Translate | 多语言翻译 | ✅ 已实现 |
| 8 | CaptainInbox | CaptainInbox | 助手-Inbox 绑定 | ✅ 已实现 |
| 9 | Playground | AssistantChatService/AgentRunnerService | 在线调试 | ✅ 已实现 |
| 10 | DocumentSearch | pgvector 向量检索 | 知识库搜索 | ✅ 已实现 |
### 3.3 CaptainAI 增强设计(超越 Chatwoot
#### 3.3.1 多 LLM Provider 支持
Chatwoot 仅支持 OpenAI。GoChat 设计为多 Provider 架构:
```go
// LLMProvider 接口
type LLMProvider interface {
ChatCompletion(ctx context.Context, req ChatRequest) (ChatResponse, error)
Embedding(ctx context.Context, text string) ([]float32, error)
StreamChat(ctx context.Context, req ChatRequest) (<-chan ChatChunk, error)
}
// 支持的 Provider
var Providers = map[string]LLMProvider{
"openai": &OpenAIProvider{},
"azure": &AzureOpenAIProvider{},
"anthropic": &AnthropicProvider{}, // Claude
"deepseek": &DeepSeekProvider{}, // DeepSeek
"qwen": &QwenProvider{}, // 通义千问
"glm": &GLMProvider{}, // 智谱 GLM
"local": &LocalProvider{}, // llama.cpp 本地
"ollama": &OllamaProvider{}, // Ollama 本地
}
```
#### 3.3.2 RAG 知识库增强
| 特性 | Chatwoot | GoChat 增强 |
|------|----------|-------------|
| 向量存储 | pgvector 单一 | pgvector + Elasticsearch + Milvus 可选 |
| 文档类型 | 知识库文档 | + 网页抓取 + PDF + FAQ 自动提取 |
| 检索策略 | 简单向量相似度 | 混合检索(向量 + 关键词 + 重排序) |
| 上下文窗口 | 固定 | 动态窗口 + MMR 去重 |
| 多语言支持 | 英文为主 | 中英双语 + 自动检测 |
#### 3.3.3 Agent Tool 框架
GoChat Agent Tool 设计超越 Chatwoot 的简单工具列表:
```go
// AgentTool 接口
type AgentTool interface {
Name() string
Description() string
Parameters() ToolParameters // JSON Schema
Execute(ctx context.Context, args map[string]interface{}) (ToolResult, error)
}
// 内置工具
type FAQTool struct{} // FAQ 检索
type MemoryTool struct{} // 对话记忆
type ContactAttributesTool struct{} // 客户属性查询
type OrderStatusTool struct{} // 订单状态查询(需企业定制)
type KnowledgeBaseTool struct{} // 知识库检索
// 自定义工具注册表
type ToolRegistry struct {
builtin map[string]AgentTool
custom map[string]AgentTool // 用户通过 API 注册
}
// Agent Runnerv2 引擎)
type AgentRunnerService struct {
provider LLMProvider
registry *ToolRegistry
assistant *CaptainAssistant
documents []CaptainDocument
}
func (s *AgentRunnerService) Run(ctx context.Context, message string) (*AgentResponse, error) {
// 1. 构建系统 promptassistant config + response_guidelines + guardrails
// 2. 检索相关文档(RAG
// 3. 调用 LLM(带 tool_choice
// 4. LLM 返回 tool_call → 执行工具 → 回注结果
// 5. 循环直到 LLM 返回最终回复
// 6. 返回回复 + 引用来源 + 工具调用日志
}
```
#### 3.3.4 Copilot 增强功能
| 增强功能 | 描述 | 优先级 |
|----------|------|--------|
| **情绪分析** | 分析客户情绪(正面/负面/中性),帮助坐席判断应对策略 | P1 |
| **意图识别** | 自动识别客户意图(投诉/咨询/退换/续费等) | P1 |
| **智能摘要** | 不仅摘要对话,还提取关键决策点和承诺 | P0 |
| **知识推荐** | 根据对话上下文推荐相关知识库文档 | P1 |
| **多轮建议** | 不仅建议单条回复,还提供后续跟进建议 | P2 |
| **质检辅助** | 对话结束后自动标注质检项(合规/违规) | P2 |
### 3.4 CaptainAI API 设计
```
# Captain Assistant CRUD
GET /api/v1/accounts/{id}/captain/assistants # 列表
POST /api/v1/accounts/{id}/captain/assistants # 创建
GET /api/v1/accounts/{id}/captain/assistants/{aid} # 详情
PATCH /api/v1/accounts/{id}/captain/assistants/{aid} # 更新
DELETE /api/v1/accounts/{id}/captain/assistants/{aid} # 删除
# Playground
POST /api/v1/accounts/{id}/captain/assistants/{aid}/playground # 调试
# Tools
GET /api/v1/accounts/{id}/captain/assistants/tools # 可用工具列表
# Inbox Binding
POST /api/v1/accounts/{id}/captain/assistants/{aid}/inboxes # 绑定
DELETE /api/v1/accounts/{id}/captain/assistants/{aid}/inboxes/{inbox_id} # 解绑
# Captain Document CRUD
GET /api/v1/accounts/{id}/captain/assistants/{aid}/documents
POST /api/v1/accounts/{id}/captain/assistants/{aid}/documents
DELETE /api/v1/accounts/{id}/captain/assistants/{aid}/documents/{did}
# Captain Scenario CRUD
GET /api/v1/accounts/{id}/captain/assistants/{aid}/scenarios
POST /api/v1/accounts/{id}/captain/assistants/{aid}/scenarios
PATCH /api/v1/accounts/{id}/captain/assistants/{aid}/scenarios/{sid}
DELETE /api/v1/accounts/{id}/captain/assistants/{aid}/scenarios/{sid}
# Copilot
POST /api/v1/accounts/{id}/copilot/suggest_replies # 建议回复
POST /api/v1/accounts/{id}/copilot/summarize # 对话摘要
POST /api/v1/accounts/{id}/copilot/translate # 翻译
POST /api/v1/accounts/{id}/copilot/analyze_sentiment # 情绪分析(新增)
POST /api/v1/accounts/{id}/copilot/detect_intent # 意图识别(新增)
```
### 3.5 数据模型
```go
// CaptainAssistant — AI 助手
type CaptainAssistant struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
Name string `gorm:"not null;type:varchar(255)"`
Description string `gorm:"type:text"`
Status AssistantStatus `gorm:"type:varchar(20);default:'draft'"` // active/draft/archived
Config json.RawMessage `gorm:"type:jsonb"` // {temperature, feature_faq, feature_memory, ...}
Guardrails json.RawMessage `gorm:"type:jsonb"` // 限制性规则
ResponseGuidelines json.RawMessage `gorm:"type:jsonb"` // 回复指导方针
LLMProvider string `gorm:"type:varchar(50);default:'openai'"` // 新增:LLM Provider
LLMModel string `gorm:"type:varchar(100);default:'gpt-4'"` // 新增:具体模型
MaxTokens int `gorm:"default:2048"` // 新增:最大 token
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// CaptainDocument — 知识库文档
type CaptainDocument struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
AssistantID uint `gorm:"not null;index"`
ExternalURL string `gorm:"type:varchar(500)"` // 外部链接
Content string `gorm:"type:text"` // 文档内容
Embedding []float32 `gorm:"type:vector(1536)"` // pgvector
SourceType string `gorm:"type:varchar(20)"` // url/file/faq/api
Status string `gorm:"type:varchar(20);default:'active'"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// CaptainScenario — 对话场景
type CaptainScenario struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
AssistantID uint `gorm:"not null;index"`
Name string `gorm:"not null;type:varchar(255)"`
Description string `gorm:"type:text"`
TriggerRules json.RawMessage `gorm:"type:jsonb"` // 触发条件
FlowConfig json.RawMessage `gorm:"type:jsonb"` // 场景流程配置
Priority int `gorm:"default:0"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// CaptainCustomTool — 自定义工具
type CaptainCustomTool struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
AssistantID uint `gorm:"not null;index"`
Name string `gorm:"not null;type:varchar(100)"`
Description string `gorm:"type:text"`
Parameters json.RawMessage `gorm:"type:jsonb"` // JSON Schema
Endpoint string `gorm:"type:varchar(500)"` // API endpoint
Method string `gorm:"type:varchar(10);default:'POST'"`
Headers json.RawMessage `gorm:"type:jsonb"`
AuthType string `gorm:"type:varchar(20)"` // none/bearer/basic/oauth2
AuthConfig json.RawMessage `gorm:"type:jsonb"`
Status string `gorm:"type:varchar(20);default:'active'"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// CaptainInbox — 助手-Inbox 绑定
type CaptainInbox struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
AssistantID uint `gorm:"not null;index"`
InboxID uint `gorm:"not null;index"`
CreatedAt time.Time
}
```
---
## 四、SSO 单点登录设计
### 4.1 SSO 架构概览
GoChat 企业版 SSO 支持 **三种协议**,超越 Chatwoot 仅支持 SAML
| 协议 | Chatwoot | GoChat | 适用场景 |
|------|----------|--------|----------|
| **SAML 2.0** | ✅ 仅此一种 | ✅ | Okta、Azure AD、OneLogin |
| **OIDC (OAuth 2.0)** | ❌ | ✅ 新增 | Google Workspace、Auth0、Keycloak |
| **LDAP** | ❌ | ✅ 新增 | 传统企业 AD/LDAP |
### 4.2 SAML 2.0 设计
#### 数据模型
```go
// AccountSamlSettings — SAML 配置
type AccountSamlSettings struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;uniqueIndex"`
SsoURL string `gorm:"not null;type:varchar(500)"` // IdP SSO URL
Certificate string `gorm:"not null;type:text"` // X509 证书
IdpEntityID string `gorm:"not null;type:varchar(500)"` // IdP Entity ID
SpEntityID string `gorm:"type:varchar(500)"` // 自动生成 SP Entity ID
RoleMappings json.RawMessage `gorm:"type:jsonb"` // SAML 属性 → GoChat 角色
SamlVersion string `gorm:"type:varchar(10);default:'2.0'"`
NameIDFormat string `gorm:"type:varchar(50);default:'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress'"`
SignAssertions bool `gorm:"default:true"`
SignRequests bool `gorm:"default:false"`
EncryptAssertions bool `gorm:"default:false"`
ForceAuthn bool `gorm:"default:false"` // 强制重新认证
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
```
#### SAML 认证流程
```
1. 用户点击 "SSO Login" → GoChat 生成 SAML AuthnRequest
2. 重定向到 IdP SsoURLOkta/Azure AD 等)
3. 用户在 IdP 完成认证
4. IdP 返回 SAML Response → GoChat ACS URL (/api/v1/saml/callback)
5. GoChat 验证 SAML Response
a. 验证签名(使用 Certificate
b. 验证时间戳(NotOnOrAfter
c. 验证 AudienceSpEntityID
d. 提取 NameIDemail
6. SamlUserBuilder 处理:
a. 按 email 查找已有用户 → 如属于账户直接登录
b. 新用户 → 创建 + 设置 provider='saml' + 自动确认邮箱
c. 角色映射 → 根据 RoleMappings 配置分配 AccountUser 角色
7. 返回 JWT token → 完成登录
```
#### API 端点
```
# SAML 配置管理
GET /api/v1/accounts/{id}/saml_settings # 获取配置
POST /api/v1/accounts/{id}/saml_settings # 创建配置
PUT /api/v1/accounts/{id}/saml_settings # 更新配置
DELETE /api/v1/accounts/{id}/saml_settings # 删除配置
# SAML 认证流程
GET /api/v1/accounts/{id}/saml/authn_request # 生成 AuthnRequest + 重定向
POST /api/v1/saml/callback # ACS 回调处理
GET /api/v1/accounts/{id}/saml/metadata # SP Metadata(供 IdP 配置)
GET /api/v1/accounts/{id}/saml/certificate_fingerprint # 证书指纹
```
### 4.3 OIDC (OpenID Connect) 设计
```go
// AccountOIDCSettings — OIDC 配置(新增)
type AccountOIDCSettings struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;uniqueIndex"`
IssuerURL string `gorm:"not null;type:varchar(500)"` // OIDC Issuer URL
ClientID string `gorm:"not null;type:varchar(200)"`
ClientSecret string `gorm:"not null;type:varchar(200)"`
Scopes string `gorm:"type:varchar(200);default:'openid,email,profile'"`
AuthorizationURL string `gorm:"type:varchar(500)"` // 自动从 Issuer 发现
TokenURL string `gorm:"type:varchar(500)"` // 自动从 Issuer 发现
JWKSURL string `gorm:"type:varchar(500)"` // 自动从 Issuer 发现
UserInfoURL string `gorm:"type:varchar(500)"`
RoleClaim string `gorm:"type:varchar(100);default:'roles'"` // 角色声明字段
GroupClaim string `gorm:"type:varchar(100);default:'groups'"` // 组声明字段
AutoProvision bool `gorm:"default:true"` // 自动创建新用户
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
```
#### OIDC 认证流程
```
1. 用户点击 "OIDC Login" → 重定向到 AuthorizationURL
2. IdP 认证 → 返回 authorization_code
3. GoChat 交换 code → TokenURL 获取 access_token + id_token
4. 验证 id_tokenJWKS → 提取 claimsemail, name, roles
5. OIDCUserBuilder 处理(类似 SamlUserBuilder
6. 返回 JWT token → 完成登录
```
#### API 端点
```
GET /api/v1/accounts/{id}/oidc_settings # 获取配置
POST /api/v1/accounts/{id}/oidc_settings # 创建配置
PUT /api/v1/accounts/{id}/oidc_settings # 更新配置
DELETE /api/v1/accounts/{id}/oidc_settings # 删除配置
GET /api/v1/accounts/{id}/oidc/authorize # 发起 OIDC 认证
POST /api/v1/oidc/callback # OIDC 回调
```
### 4.4 LDAP 设计
```go
// AccountLDAPSettings — LDAP 配置(新增)
type AccountLDAPSettings struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;uniqueIndex"`
Host string `gorm:"not null;type:varchar(200)"` // LDAP 服务器
Port int `gorm:"not null;default:389"`
UseTLS bool `gorm:"default:false"`
BaseDN string `gorm:"not null;type:varchar(200)"` // 搜索基准 DN
BindDN string `gorm:"type:varchar(200)"` // 绑定 DN
BindPassword string `gorm:"type:varchar(200)"` // 绑定密码
UserFilter string `gorm:"type:varchar(200);default:'(objectClass=person)'"`
EmailAttribute string `gorm:"type:varchar(50);default:'mail'"`
NameAttribute string `gorm:"type:varchar(50);default:'cn'"`
GroupAttribute string `gorm:"type:varchar(50);default:'memberOf'"`
RoleMappings json.RawMessage `gorm:"type:jsonb"` // LDAP group → GoChat 角色
AutoProvision bool `gorm:"default:true"`
SyncInterval int `gorm:"default:3600"` // 同步间隔(秒)
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
```
#### LDAP 认证流程
```
1. 用户输入企业账号密码 → GoChat 发起 LDAP Bind
2. BindDN + BindPassword 连接 LDAP 服务器
3. 搜索 BaseDN + UserFilter → 获取用户 DN
4. 用户 DN + 密码验证(Bind 验证)
5. 提取 email/name/groups 属性
6. LDAPUserBuilder 处理(类似 SamlUserBuilder
7. 返回 JWT token → 完成登录
8. 后台定时同步 LDAP 组 → GoChat 角色
```
### 4.5 SSO 中间件设计
```go
// SSOMiddleware — SSO 通用中间件
func SSOMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
accountID := getAccountID(c)
// 检查账户是否配置了 SSO
samlSettings := getSamlSettings(accountID)
oidcSettings := getOIDCSettings(accountID)
ldapSettings := getLDAPSettings(accountID)
if samlSettings != nil || oidcSettings != nil || ldapSettings != nil {
// 强制 SSO 登录(禁用普通邮箱登录)
// 仅管理员可绕过 SSOsuper_admin bypass
if !isSuperAdmin(c) {
enforceSSO(c)
}
}
c.Next()
}
}
// SSOProviderRouter — 根据配置路由到不同 SSO Provider
func SSOProviderRouter(accountID uint) string {
if getSamlSettings(accountID) != nil { return "saml" }
if getOIDCSettings(accountID) != nil { return "oidc" }
if getLDAPSettings(accountID) != nil { return "ldap" }
return "email" // 默认邮箱登录
}
```
---
## 五、语音通话功能设计
### 5.1 语音通话架构概览
GoChat 语音通话采用 **Conference 模式**(坐席 + 客户通过会议桥连接),与 Chatwoot 保持一致,但增加更多 Provider 支持:
| Provider | Chatwoot | GoChat | 说明 |
|----------|----------|--------|------|
| **Twilio** | ✅ | ✅ | 主要语音 Provider |
| **WhatsApp 通话** | ✅ | ✅ | WhatsApp Voice Call |
| **Agora(声网)** | ❌ | ✅ 新增 | 国内音视频首选 |
| **Tencent RTC** | ❌ | ✅ 新增 | 腾讯实时音视频 |
### 5.2 数据模型
```go
// Call — 通话记录
type Call struct {
ID uint `gorm:"primaryKey"`
AccountID uint `gorm:"not null;index"`
InboxID uint `gorm:"not null;index"`
ConversationID uint `gorm:"not null;index"`
ContactID uint `gorm:"not null"`
AgentID uint `gorm:"index"` // 接听坐席
CallSource string `gorm:"not null;type:varchar(20)"` // inbox/initiated
CallDirection string `gorm:"not null;type:varchar(20)"` // inbound/outbound
Status string `gorm:"not null;type:varchar(20)"` // ringing/in_progress/completed/no_answer/failed/busy
Provider string `gorm:"type:varchar(20);default:'twilio'"` // twilio/agora/tencent/whatsapp
CallSID string `gorm:"type:varchar(100)"` // Provider 侧通话 ID
ConferenceSID string `gorm:"type:varchar(100)"` // Conference SIDTwilio
DurationSeconds int `gorm:"default:0"` // 通话时长
RecordingURL string `gorm:"type:varchar(500)"` // 录音 URL
RecordingSID string `gorm:"type:varchar(100)"` // 录音 SID
Transcript string `gorm:"type:text"` // 通话转录
VoipToken string `gorm:"type:varchar(500)"` // Twilio Access Token
ClientIdentity string `gorm:"type:varchar(100)"` // Client 标识
AdditionalAttrs json.RawMessage `gorm:"type:jsonb"` // 附加属性
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
// CallStatus 状态机
// ringing → in_progress → completed
// ringing → no_answer
// ringing → failed
// ringing → busy
// in_progress → completed(正常结束)
```
### 5.3 通话流程设计
#### 5.3.1 呼出通话(Outbound
```
1. 坐席在对话页面点击 "Call" 按钮
2. GoChat 创建 Call 记录(status=ringing, direction=outbound
3. 生成 VoipTokenTwilio Access Token + VoiceGrant
4. 前端使用 Twilio Client SDK 发起通话
5. 同时通过 Twilio API 呼叫客户号码
6. Twilio Conference 模式:坐席 + 客户加入会议桥
7. 客户接听 → status=in_progress + 自动分配坐席到对话
8. 通话结束 → status=completed + 更新 duration_seconds
9. 对话中插入 voice_call 消息气泡(含通话详情)
```
#### 5.3.2 呼入通话(Inbound
```
1. 客户拨打企业号码 → Twilio 转发到 GoChat Webhook
2. GoChat Voice::IncomingCallService 处理:
a. 查找关联 Inbox + Contact
b. 创建/查找 Conversation
c. 创建 Callstatus=ringing, direction=inbound
d. 通知坐席(WebSocket 推送 + 呼叫响铃)
3. 坐席接听 → claim_call + auto_assign
4. 通话进行 → status=in_progress
5. 通话结束 → status=completed + 录音处理
```
#### 5.3.3 WhatsApp 通话
```
1. WhatsApp 客户发起通话请求 → GoChat Webhook 接收 SDP offer
2. CallPermissionReplyService 处理权限判断
3. 呼入通话创建 → 通知坐席
4. 坐席 accept/reject → WhatsApp SDP answer/reject
5. 通话进行 → 状态更新
```
### 5.4 通话 Provider 抽象层
```go
// VoiceProvider 接口
type VoiceProvider interface {
// 基础通话
MakeCall(ctx context.Context, params MakeCallParams) (*CallResult, error)
HangupCall(ctx context.Context, callSID string) error
// Conference
CreateConference(ctx context.Context, params ConferenceParams) (*ConferenceResult, error)
EndConference(ctx context.Context, conferenceSID string) error
// Token
GenerateToken(ctx context.Context, identity string) (string, error)
// 录音
StartRecording(ctx context.Context, callSID string) error
StopRecording(ctx context.Context, callSID string) error
GetRecordingURL(ctx context.Context, recordingSID string) (string, error)
// Webhook 处理
HandleIncomingCall(ctx context.Context, payload map[string]interface{}) (*IncomingCallResult, error)
HandleConferenceEvent(ctx context.Context, event ConferenceEvent) error
HandleRecordingStatus(ctx context.Context, payload map[string]interface{}) error
}
// Twilio Provider 实现
type TwilioProvider struct {
AccountSID string
AuthToken string
AppSID string
PhoneNumber string
APIBase string // https://api.twilio.com
}
// Agora Provider 实现(新增)
type AgoraProvider struct {
AppID string
AppCertificate string
APIBase string
}
// TencentRTC Provider 实现(新增)
type TencentRTCProvider struct {
SDKAppID int
SecretKey string
APIBase string
}
```
### 5.5 通话 API 设计
```
# 通话管理
POST /api/v1/accounts/{id}/calls # 创建通话(呼出)
GET /api/v1/accounts/{id}/calls/{call_id} # 通话详情
PUT /api/v1/accounts/{id}/calls/{call_id} # 更新通话状态
DELETE /api/v1/accounts/{id}/calls/{call_id} # 结束通话
# 通话动作
POST /api/v1/accounts/{id}/calls/{call_id}/answer # 接听
POST /api/v1/accounts/{id}/calls/{call_id}/hangup # 挂断
POST /api/v1/accounts/{id}/calls/{call_id}/reject # 拒接
POST /api/v1/accounts/{id}/calls/{call_id}/mute # 静音
POST /api/v1/accounts/{id}/calls/{call_id}/unmute # 取消静音
# Twilio Token
GET /api/v1/accounts/{id}/voice/token # 获取 VoIP Token
# 录音
POST /api/v1/accounts/{id}/calls/{call_id}/record # 开始录音
GET /api/v1/accounts/{id}/calls/{call_id}/recording # 获取录音
# WebhookTwilio 回调)
POST /voice/twilio/incoming # Twilio 呼入回调
POST /voice/twilio/conference # Twilio 会议事件
POST /voice/twilio/recording_status # Twilio 录音状态
# WhatsApp 通话
POST /api/v1/accounts/{id}/whatsapp/call/accept # 接听 WhatsApp 通话
POST /api/v1/accounts/{id}/whatsapp/call/reject # 拒绝 WhatsApp 通话
```
### 5.6 录音与转录设计
```go
// VoiceRecordingService — 录音处理
type VoiceRecordingService struct {
provider VoiceProvider
storage StorageProvider // 本地/S3/OSS
}
func (s *VoiceRecordingService) ProcessRecording(ctx context.Context, callID uint) error {
// 1. 从 Provider 获取录音文件 URL
// 2. 下载录音文件
// 3. 存储到对象存储(S3/OSS
// 4. 创建 Attachment 关联到对话消息
// 5. 可选:调用转录服务(Whisper/阿里语音识别)
// 6. 更新 Call.RecordingURL + Call.Transcript
}
// VoiceTranscriptionService — 通话转录
type VoiceTranscriptionService interface {
Transcribe(ctx context.Context, audioURL string) (TranscriptionResult, error)
}
// 支持的转录 Provider
var TranscriptionProviders = map[string]VoiceTranscriptionService{
"whisper": &WhisperProvider{}, // OpenAI Whisper
"aliyun": &AliyunASRProvider{}, // 阿里云语音识别
"tencent": &TencentASRProvider{}, // 腾讯云语音识别
"azure": &AzureSpeechProvider{}, // Azure Speech
}
```
---
## 六、企业版功能实施路线图
### 6.1 Phase 分期
| Phase | 功能 | 优先级 | 预估工时 | 前置条件 |
|-------|------|--------|----------|----------|
| **E1** | Feature Gate + Subscription 模型 | P0 | 3天 | 无 |
| **E2** | SAML SSO 完整实现 | P0 | 5天 | E1 |
| **E3** | OIDC SSO 实现 | P1 | 4天 | E2 |
| **E4** | LDAP SSO 实现 | P2 | 4天 | E2 |
| **E5** | SLA 策略完整实现 | P0 | 4天 | E1 |
| **E6** | 审计日志实现 | P0 | 3天 | E1 |
| **E7** | 自定义角色权限 | P0 | 5天 | E1 |
| **E8** | 语音通话(Twilio | P1 | 7天 | E1 |
| **E9** | 语音通话(Agora/Tencent | P2 | 4天 | E8 |
| **E10** | CaptainAI 增强(多 LLM | P1 | 5天 | E1 |
| **E11** | Copilot 增强 | P2 | 3天 | E10 |
| **E12** | 坐席容量策略 | P1 | 3天 | E7 |
| **E13** | 公司/组织管理完善 | P1 | 3天 | E7 |
| **E14** | 定时任务调度 | P2 | 2天 | Worker Pool 可用 |
| **E15** | AgentBot 完善 | P1 | 4天 | E1 |
### 6.2 E1 Feature Gate 实现细节
```
E1 是所有企业功能的基石,需要优先实现:
1. 数据模型:Subscription + BillingUsage + FeatureEntitlement
2. 中间件:FeatureGate(requiredFeature) → 403 if not entitled
3. 路由注册:所有企业版路由加 FeatureGate 中间件
4. 配置管理:config.yaml 增加 billing section
5. License 密钥验证(自部署场景)
6. API
- GET /api/v1/accounts/{id}/subscription # 查看订阅
- POST /api/v1/accounts/{id}/subscription # 创建/更新订阅
- GET /api/v1/accounts/{id}/entitlement # 查看功能授权
- GET /api/v1/accounts/{id}/billing_usage # 查看用量
```
### 6.3 关键技术决策
| 决策点 | 选项 | 推荐 | 原因 |
|--------|------|------|------|
| **向量存储** | pgvector vs Milvus vs ES | pgvector(默认) + Milvus(可选) | pgvector 与 PG 一体化,运维简单 |
| **LLM 调用** | 直接 HTTP vs SDK | 直接 HTTPresty/v2 | 减少依赖,多 Provider 更灵活 |
| **SSO 协议** | 仅 SAML vs 三协议 | 三协议(SAML+OIDC+LDAP | 国内企业 OIDC/LDAP 更常见 |
| **语音 Provider** | 仅 Twilio vs 多 Provider | Twilio(海外) + Agora(国内) | 国内 Agaora 生态更成熟 |
| **计费存储** | Stripe vs 本地 | Stripe(海外) + 支付宝/微信(国内) | 双币种双渠道 |
| **功能授权** | config.yaml vs DB | DBFeatureEntitlement | 云版动态调整,自部署用 config.yaml + license |
| **录音转录** | Whisper vs 云 ASR | Whisper(本地) + 阿里 ASR(云) | 灵活选择 |
| **Conference 模式** | 保留 vs 简化 | 保留 Conference 模式 | 与 Chatwoot 一致,坐席可转接 |
---
## 附录AChatwoot 企业版 Feature Flag 对照表
| Flag | 功能 | GoChat 对应开关 |
|------|------|-----------------|
| `enterprise` | 企业版总开关 | `FeatureEntitlement.plan >= enterprise` |
| `saml` | SAML SSO | `FeatureEntitlement.features.sso_saml` |
| `voice` | 语音通话 | `FeatureEntitlement.features.voice` |
| `captain_ai` | Captain AI | `FeatureEntitlement.features.captain_ai` |
| `audit_log` | 审计日志 | `FeatureEntitlement.features.audit_log` |
| `custom_roles` | 自定义角色 | `FeatureEntitlement.features.custom_roles` |
| `sla` | SLA 策略 | `FeatureEntitlement.features.sla` |
| `agent_capacity` | 坐席容量 | `FeatureEntitlement.features.agent_capacity` |
## 附录BGoChat 新增企业版功能 Flag(超越 Chatwoot
| Flag | 功能 | 描述 |
|------|------|------|
| `oidc_sso` | OIDC SSO | OpenID Connect 单点登录(新增) |
| `ldap_sso` | LDAP SSO | LDAP 认证(新增) |
| `multi_llm` | 多 LLM Provider | 支持 Claude/DeepSeek/Qwen/GLM 等(新增) |
| `voice_agora` | Agora 语音 | 声网语音通话(新增) |
| `voice_tencent` | Tencent RTC | 腾讯实时音视频(新增) |
| `sentiment_analysis` | 情绪分析 | Copilot 情绪分析(新增) |
| `intent_detection` | 意图识别 | Copilot 意图识别(新增) |
| `voice_transcription` | 通话转录 | 通话自动转录(新增) |
| `hybrid_rag` | 混合 RAG | 向量+关键词混合检索(新增) |
---
> **文档维护说明**:本文档随 GoChat 企业版功能迭代持续更新。每次 Phase 完成后更新实施状态和差距分析。