refactor: 将客服后端重构为宿主可嵌入模块

- 注入数据库、运行时配置、统一响应、文件存储和平台 AI 能力,补充业务读写工具与客户快捷操作契约。

- 移除模块内重复的组织、客户、工单、标签、技能、旧工作流、MCP 和迁移实现,将身份权限与业务主体交由宿主管理。

- 使用 libSQL 重构向量存储,并完善图片消息、访客身份、排队调度、企业微信和支持聊天页面。

- 统一 HTTP、DTO 与 WebSocket 的 snake_case 协议,补齐模块初始化、业务动作和公共载荷等回归测试。
This commit is contained in:
t
2026-08-28 22:23:13 +08:00
parent 6845c728f8
commit 18c9354095
377 changed files with 13199 additions and 22881 deletions
+15 -14
View File
@@ -240,20 +240,21 @@ func GetAIAgentFallbackModeLabel(mode AIAgentFallbackMode) string {
}
const (
IMRealtimeEventConnected = "connected"
IMRealtimeEventPong = "pong"
IMRealtimeEventSubscribed = "subscribed"
IMRealtimeEventUnsubscribed = "unsubscribed"
IMRealtimeEventResyncRequired = "resyncRequired"
IMRealtimeEventMessageCreated = "message.created"
IMRealtimeEventMessageRecalled = "message.recalled"
IMRealtimeEventConversationCreated = "conversation.created"
IMRealtimeEventConversationUpdated = "conversation.updated"
IMRealtimeEventConversationAssigned = "conversation.assigned"
IMRealtimeEventConversationTransferred = "conversation.transferred"
IMRealtimeEventConversationClosed = "conversation.closed"
IMRealtimeEventConversationRead = "conversation.read"
IMRealtimeEventNotificationCreated = "notification.created"
IMRealtimeEventConnected = "connected"
IMRealtimeEventPong = "pong"
IMRealtimeEventSubscribed = "subscribed"
IMRealtimeEventUnsubscribed = "unsubscribed"
IMRealtimeEventResyncRequired = "resyncRequired"
IMRealtimeEventMessageCreated = "message.created"
IMRealtimeEventMessageRecalled = "message.recalled"
IMRealtimeEventConversationCreated = "conversation.created"
IMRealtimeEventConversationUpdated = "conversation.updated"
IMRealtimeEventConversationAssigned = "conversation.assigned"
IMRealtimeEventConversationTransferred = "conversation.transferred"
IMRealtimeEventConversationClosed = "conversation.closed"
IMRealtimeEventConversationRead = "conversation.read"
IMRealtimeEventConversationQueueUpdated = "conversation.queue_updated"
IMRealtimeEventNotificationCreated = "notification.created"
)
const (
-16
View File
@@ -1,21 +1,5 @@
package enums
type VectorDBType string
const (
VectorDBTypeQdrant VectorDBType = "qdrant"
VectorDBTypeLanceDB VectorDBType = "lancedb"
)
var vectorDBTypeLabelMap = map[VectorDBType]string{
VectorDBTypeQdrant: "Qdrant",
VectorDBTypeLanceDB: "LanceDB",
}
func GetVectorDBTypeLabel(dbType VectorDBType) string {
return vectorDBTypeLabelMap[dbType]
}
type KnowledgeDocumentContentType string
const (
-12
View File
@@ -1,12 +0,0 @@
package enums
import "testing"
func TestVectorDBTypeLabelIncludesLanceDB(t *testing.T) {
if VectorDBTypeLanceDB != "lancedb" {
t.Fatalf("VectorDBTypeLanceDB = %q, want %q", VectorDBTypeLanceDB, "lancedb")
}
if got := GetVectorDBTypeLabel(VectorDBTypeLanceDB); got != "LanceDB" {
t.Fatalf("GetVectorDBTypeLabel(VectorDBTypeLanceDB) = %q, want %q", got, "LanceDB")
}
}
-55
View File
@@ -1,55 +0,0 @@
package enums
type TicketStatus string
const (
TicketStatusPending TicketStatus = "pending"
TicketStatusInProgress TicketStatus = "in_progress"
TicketStatusDone TicketStatus = "done"
)
var TicketStatusValues = []TicketStatus{
TicketStatusPending,
TicketStatusInProgress,
TicketStatusDone,
}
var ticketStatusLabelMap = map[TicketStatus]string{
TicketStatusPending: "待处理",
TicketStatusInProgress: "处理中",
TicketStatusDone: "已处理",
}
func GetTicketStatusLabel(status TicketStatus) string {
return ticketStatusLabelMap[status]
}
func IsValidTicketStatus(status string) bool {
for _, item := range TicketStatusValues {
if string(item) == status {
return true
}
}
return false
}
type TicketSource string
const (
TicketSourceManual TicketSource = "manual"
TicketSourceConversation TicketSource = "conversation"
)
var TicketSourceValues = []TicketSource{
TicketSourceManual,
TicketSourceConversation,
}
func IsValidTicketSource(source string) bool {
for _, item := range TicketSourceValues {
if string(item) == source {
return true
}
}
return false
}