Files
kefu_cloud/server/internal/model/models.go
T
yml2213 c5f28dca1c 新增独立快捷回复模块(团队/个人)
从知识库拆出快捷回复:支持团队暂存与发布同步、个人话术、输入码与工作台 / 调用,以及 CSV 导入导出;管理页顶栏与侧栏对齐。
2026-07-17 21:59:10 +08:00

202 lines
9.4 KiB
Go
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.
package model
import (
"time"
"gorm.io/gorm"
)
type Tenant struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:100;not null;uniqueIndex" json:"name"`
PlanID *uint `json:"plan_id"`
SeatCount int `gorm:"default:2" json:"seat_count"`
ExpireAt time.Time `json:"expire_at"`
Status string `gorm:"size:20;default:normal" json:"status"`
ContactName string `gorm:"size:30" json:"contact_name"`
ContactPhone string `gorm:"size:20" json:"contact_phone"`
ContactEmail string `gorm:"size:100" json:"contact_email"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type User struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
Role string `gorm:"size:20;default:agent" json:"role"`
Username string `gorm:"size:50;not null;uniqueIndex" json:"username"`
PasswordHash string `gorm:"size:255;not null" json:"-"`
Nickname string `gorm:"size:50" json:"nickname"`
Status string `gorm:"size:20;default:online" json:"status"`
LastOnlineAt *time.Time `json:"last_online_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Channel struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
Type string `gorm:"size:30;not null" json:"type"`
Name string `gorm:"size:50" json:"name"`
Status string `gorm:"size:20;default:enabled" json:"status"`
Config string `gorm:"type:text" json:"config"`
ScriptCode string `gorm:"size:500" json:"script_code"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Customer struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
Name string `gorm:"size:50;not null" json:"name"`
Phone string `gorm:"size:20" json:"phone"`
Email string `gorm:"size:100" json:"email"`
Tags string `gorm:"type:text" json:"tags"`
Source string `gorm:"size:30" json:"source"`
Status string `gorm:"size:20;default:online" json:"status"`
ConversationCount int `gorm:"default:0" json:"conversation_count"`
SatisfactionSum float64 `gorm:"default:0" json:"-"`
SatisfactionCount int `gorm:"default:0" json:"-"`
LastContactAt *time.Time `json:"last_contact_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Session struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
ChannelID uint `json:"channel_id"`
CustomerID uint `gorm:"index" json:"customer_id"`
AgentID *uint `gorm:"index" json:"agent_id"`
VisitorTokenHash string `gorm:"size:64;index" json:"-"`
VisitorIP string `gorm:"size:64" json:"visitor_ip"`
VisitorRegion string `gorm:"size:100" json:"visitor_region"`
UserAgent string `gorm:"size:500" json:"user_agent"`
LastReadSeq int `gorm:"default:0" json:"last_read_seq"`
Status string `gorm:"size:20;default:waiting" json:"status"`
Priority string `gorm:"size:20;default:normal" json:"priority"`
SatisfactionScore *int `json:"satisfaction_score"`
SatisfactionText string `gorm:"size:500" json:"satisfaction_text"`
EndReason string `gorm:"size:50" json:"end_reason"`
CreatedAt time.Time `json:"created_at"`
EndedAt *time.Time `json:"ended_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Message struct {
ID uint `gorm:"primaryKey" json:"id"`
SessionID uint `gorm:"not null;uniqueIndex:idx_message_session_seq" json:"session_id"`
SenderType string `gorm:"size:20;not null" json:"sender_type"`
SenderID *uint `json:"sender_id"`
Content string `gorm:"type:text;not null" json:"content"`
Type string `gorm:"size:20;default:text" json:"type"`
Seq int `gorm:"not null;uniqueIndex:idx_message_session_seq" json:"seq"`
SentAt time.Time `json:"sent_at"`
}
type SessionEvent struct {
ID uint `gorm:"primaryKey" json:"id"`
SessionID uint `gorm:"index;not null" json:"session_id"`
OperatorID uint `json:"operator_id"`
Action string `gorm:"size:50;not null" json:"action"`
Detail string `gorm:"size:500" json:"detail"`
CreatedAt time.Time `json:"created_at"`
}
type Category struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
ParentID *uint `json:"parent_id"`
Name string `gorm:"size:30;not null" json:"name"`
}
type KnowledgeEntry struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
CategoryID uint `json:"category_id"`
Title string `gorm:"size:100;not null" json:"title"`
Content string `gorm:"type:text;not null" json:"content"`
Status string `gorm:"size:20;default:draft" json:"status"`
UsageCount int `gorm:"default:0" json:"usage_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// QuickReply 团队/个人快捷回复(与知识库独立)。
// Scope=team 时 OwnerUserID 为空,全租户共享;Scope=personal 时归属 OwnerUserID。
type QuickReply struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"index;not null" json:"tenant_id"`
Scope string `gorm:"size:20;index;not null" json:"scope"` // team | personal
OwnerUserID *uint `gorm:"index" json:"owner_user_id,omitempty"`
Title string `gorm:"size:100;not null" json:"title"`
Content string `gorm:"type:text;not null" json:"content"`
Shortcut string `gorm:"size:32;index" json:"shortcut"` // 输入码,如 nh → /nh
GroupName string `gorm:"size:50" json:"group_name"`
Status string `gorm:"size:20;default:draft;index" json:"status"` // draft | published
SortOrder int `gorm:"default:0" json:"sort_order"`
UsageCount int `gorm:"default:0" json:"usage_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type Plan struct {
ID uint `gorm:"primaryKey" json:"id"`
Name string `gorm:"size:30;not null" json:"name"`
PriceMonthly int `json:"price_monthly"`
Seats int `json:"seats"`
StorageDays int `json:"storage_days"`
KBLimit int `json:"kb_limit"`
Features string `gorm:"type:text" json:"features"`
Status string `gorm:"size:20;default:active" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type OperationLog struct {
ID uint `gorm:"primaryKey" json:"id"`
OperatorID uint `json:"operator_id"`
Action string `gorm:"size:50;not null" json:"action"`
Detail string `gorm:"size:500" json:"detail"`
TargetType string `gorm:"size:30" json:"target_type"`
TargetID *uint `json:"target_id"`
IP string `gorm:"size:50" json:"ip"`
CreatedAt time.Time `json:"created_at"`
}
type Announcement struct {
ID uint `gorm:"primaryKey" json:"id"`
Title string `gorm:"size:100;not null" json:"title"`
Content string `gorm:"type:text" json:"content"`
Status string `gorm:"size:20;default:draft" json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// TenantSetting 租户级系统设置(欢迎语、工作时间、通知开关、分配策略等)。
type TenantSetting struct {
ID uint `gorm:"primaryKey" json:"id"`
TenantID uint `gorm:"uniqueIndex;not null" json:"tenant_id"`
DisplayName string `gorm:"size:100" json:"display_name"`
AgentNickname string `gorm:"size:50" json:"agent_nickname"`
Timezone string `gorm:"size:50;default:Asia/Shanghai" json:"timezone"`
WelcomeMessage string `gorm:"size:500" json:"welcome_message"`
// WelcomeMessagesJSON 多段欢迎语 JSON[{type:text|image, content:...}, ...]
WelcomeMessagesJSON string `gorm:"type:text" json:"welcome_messages_json"`
OfflinePrompt string `gorm:"size:500" json:"offline_prompt"`
WorkHoursJSON string `gorm:"type:text" json:"work_hours_json"`
WorktimePrompt string `gorm:"size:500" json:"worktime_prompt"`
NotifyNewSession bool `gorm:"default:true" json:"notify_new_session"`
NotifyOfflineLeave bool `gorm:"default:true" json:"notify_offline_leave"`
NotifyDailyReport bool `gorm:"default:false" json:"notify_daily_report"`
// AssignStrategy 自动分配策略:least_load(默认)| round_robin
AssignStrategy string `gorm:"size:30;default:least_load" json:"assign_strategy"`
// MaxActivePerAgent 每位坐席最大进行中会话数;0 表示不限制
MaxActivePerAgent int `gorm:"default:0" json:"max_active_per_agent"`
// RRLastAgentID 轮询策略的上次分配坐席游标
RRLastAgentID *uint `json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}