✅ 已完成功能: 1. 项目基础设施和Docker开发环境 2. 前端React 18 + TypeScript架构 3. 后端Golang + Gin框架 4. 多租户数据库设计 5. 完整API路由系统 6. 智能客服聊天界面 7. 详细文档和部署指南 🔧 技术栈: - 前端:React 18, TypeScript, Vite, Zustand - 后端:Golang, Gin, GORM, PostgreSQL - 部署:Docker, Docker Compose 🎨 设计规范: - 无渐变色,无紫色 - 简洁专业的中性色系 - 响应式布局 📊 状态: - 前端开发服务器:http://localhost:5173 - 后端API服务:http://localhost:8080 - 数据库:PostgreSQL + Redis - 完整的多租户架构 作者:小弟 (大哥的AI助手) 日期:2026-02-27
130 lines
5.4 KiB
Go
130 lines
5.4 KiB
Go
package models
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// Conversation 会话模型
|
|
type Conversation struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
TenantID uint `gorm:"not null;index" json:"tenant_id"`
|
|
Channel string `gorm:"size:50;not null" json:"channel"` // web, mobile, api, email
|
|
Type string `gorm:"size:20;not null" json:"type"` // customer_service, ticket, consultation
|
|
|
|
// 参与者
|
|
CustomerID *uint `gorm:"index" json:"customer_id"` // 客户用户ID
|
|
CustomerName string `gorm:"size:100" json:"customer_name"`
|
|
CustomerEmail string `gorm:"size:100" json:"customer_email"`
|
|
CustomerPhone string `gorm:"size:20" json:"customer_phone"`
|
|
|
|
AgentID *uint `gorm:"index" json:"agent_id"` // 分配的客服ID
|
|
Department string `gorm:"size:100" json:"department"` // 分配的部门
|
|
|
|
// 会话信息
|
|
Title string `gorm:"size:200" json:"title"`
|
|
Description string `gorm:"type:text" json:"description"`
|
|
Tags []string `gorm:"type:jsonb" json:"tags"`
|
|
Priority string `gorm:"size:20;default:'normal'" json:"priority"` // low, normal, high, urgent
|
|
|
|
// 状态
|
|
Status string `gorm:"size:20;default:'open'" json:"status"` // open, assigned, in_progress, waiting, resolved, closed
|
|
Source string `gorm:"size:100" json:"source"` // 来源页面/应用
|
|
Referrer string `gorm:"size:500" json:"referrer"` // 来源URL
|
|
|
|
// 统计
|
|
MessageCount int `gorm:"default:0" json:"message_count"`
|
|
FirstResponseAt *time.Time `json:"first_response_at"`
|
|
FirstResponseDuration int `gorm:"default:0" json:"first_response_duration"` // 首次响应时间(秒)
|
|
ResolutionAt *time.Time `json:"resolution_at"`
|
|
ResolutionDuration int `gorm:"default:0" json:"resolution_duration"` // 解决时间(秒)
|
|
|
|
// 满意度
|
|
Rating *int `json:"rating"` // 1-5
|
|
RatingComment string `gorm:"type:text" json:"rating_comment"`
|
|
|
|
// 元数据
|
|
Metadata JSONMap `gorm:"type:jsonb" json:"metadata"`
|
|
|
|
// 时间戳
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
ClosedAt *time.Time `json:"closed_at"`
|
|
|
|
// 关联
|
|
Tenant Tenant `gorm:"foreignKey:TenantID" json:"tenant,omitempty"`
|
|
Customer *User `gorm:"foreignKey:CustomerID" json:"customer,omitempty"`
|
|
Agent *Agent `gorm:"foreignKey:AgentID" json:"agent,omitempty"`
|
|
Messages []Message `gorm:"foreignKey:ConversationID" json:"messages,omitempty"`
|
|
}
|
|
|
|
// Message 消息模型
|
|
type Message struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
TenantID uint `gorm:"not null;index" json:"tenant_id"`
|
|
ConversationID uint `gorm:"not null;index" json:"conversation_id"`
|
|
|
|
// 发送者信息
|
|
SenderType string `gorm:"size:20;not null" json:"sender_type"` // user, agent, system, ai
|
|
SenderID *uint `gorm:"index" json:"sender_id"` // 用户ID或客服ID
|
|
SenderName string `gorm:"size:100" json:"sender_name"`
|
|
SenderAvatar string `gorm:"size:255" json:"sender_avatar"`
|
|
|
|
// 消息内容
|
|
ContentType string `gorm:"size:50;default:'text'" json:"content_type"` // text, image, file, audio, video, location
|
|
Content string `gorm:"type:text;not null" json:"content"`
|
|
RichContent JSONMap `gorm:"type:jsonb" json:"rich_content"` // 富文本内容
|
|
|
|
// 附件
|
|
Attachments []Attachment `gorm:"foreignKey:MessageID" json:"attachments,omitempty"`
|
|
|
|
// AI相关
|
|
IsAIResponse bool `gorm:"default:false" json:"is_ai_response"`
|
|
AIModel string `gorm:"size:100" json:"ai_model"`
|
|
AIPromptTokens int `gorm:"default:0" json:"ai_prompt_tokens"`
|
|
AICompletionTokens int `gorm:"default:0" json:"ai_completion_tokens"`
|
|
AITotalTokens int `gorm:"default:0" json:"ai_total_tokens"`
|
|
|
|
// 状态
|
|
Status string `gorm:"size:20;default:'sent'" json:"status"` // sending, sent, delivered, read, failed
|
|
ReadBy []uint `gorm:"type:jsonb" json:"read_by"` // 已读用户ID列表
|
|
ReadAt *time.Time `json:"read_at"`
|
|
|
|
// 回复引用
|
|
ReplyToID *uint `gorm:"index" json:"reply_to_id"`
|
|
|
|
// 时间戳
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
|
|
// 关联
|
|
Tenant Tenant `gorm:"foreignKey:TenantID" json:"tenant,omitempty"`
|
|
Conversation Conversation `gorm:"foreignKey:ConversationID" json:"conversation,omitempty"`
|
|
ReplyTo *Message `gorm:"foreignKey:ReplyToID" json:"reply_to,omitempty"`
|
|
}
|
|
|
|
// Attachment 附件模型
|
|
type Attachment struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
TenantID uint `gorm:"not null;index" json:"tenant_id"`
|
|
MessageID uint `gorm:"not null;index" json:"message_id"`
|
|
|
|
// 文件信息
|
|
Name string `gorm:"size:255;not null" json:"name"`
|
|
Type string `gorm:"size:100;not null" json:"type"` // MIME类型
|
|
Size int64 `gorm:"not null" json:"size"` // 文件大小(字节)
|
|
URL string `gorm:"size:500;not null" json:"url"`
|
|
ThumbnailURL string `gorm:"size:500" json:"thumbnail_url"`
|
|
|
|
// 元数据
|
|
Width int `json:"width"` // 图片宽度
|
|
Height int `json:"height"` // 图片高度
|
|
Duration int `json:"duration"` // 音视频时长(秒)
|
|
|
|
// 时间戳
|
|
CreatedAt time.Time `json:"created_at"`
|
|
|
|
// 关联
|
|
Tenant Tenant `gorm:"foreignKey:TenantID" json:"tenant,omitempty"`
|
|
Message Message `gorm:"foreignKey:MessageID" json:"message,omitempty"`
|
|
}
|