829 lines
29 KiB
Go
829 lines
29 KiB
Go
/**
|
||
* package model
|
||
* 作用:定义全系统通用的数据结构(PO 与 DTO)。
|
||
* 规范:所有字段均采用 snake_case (下划线命名) 以保持 DB 和 JSON 的高度一致性。
|
||
*/
|
||
package model
|
||
|
||
import "time"
|
||
|
||
// ==========================================
|
||
// 数据库实体 (PO - Persistent Object)
|
||
// ==========================================
|
||
|
||
/**
|
||
* ChatMessage
|
||
* 对应数据库表:chat_messages
|
||
* 作用:持久化存储聊天记录,包括文本、多媒体和信令状态。
|
||
*/
|
||
type ChatMessage struct {
|
||
// 消息唯一标识 ID
|
||
ID uint `gorm:"primaryKey;comment:消息唯一标识ID" json:"id"`
|
||
// 房间ID,用于标识聊天室或会话
|
||
RoomID string `gorm:"type:varchar(100);index;comment:房间ID" json:"room_id"`
|
||
// 发送者用户ID
|
||
SenderUserID string `gorm:"type:varchar(100);index;comment:发送者用户ID" json:"sender_user_id"`
|
||
// 接收者用户ID
|
||
ReceiverUserID string `gorm:"type:varchar(100);index;comment:接收者用户ID" json:"receiver_user_id"`
|
||
// 消息类型 ( // 0:文本 1:图片 2:语音 3:视频 8:文件 6:信令)
|
||
MessageType int `gorm:"type:int;comment:消息类型" json:"message_type"`
|
||
// 消息内容或信令数据
|
||
Content string `gorm:"type:text;comment:消息内容" json:"content"`
|
||
// 存储富文本元数据(如URL预览信息的JSON字符串: {"title":"...","image":"..."})
|
||
Extra string `gorm:"type:text;comment:扩展字段,存储JSON格式的元数据" json:"extra"`
|
||
// 通话时长(秒),仅在通话类型的消息中有效
|
||
Duration int `gorm:"type:int;comment:通话时长(秒)" json:"duration"`
|
||
// 关联的通话ID (用于串联信令)
|
||
CallID string `gorm:"type:varchar(100);index;comment:关联的通话ID" json:"call_id"`
|
||
// 通话状态 (invite, accepted, ended, rejected, offer, answer, candidate, hangup, etc.)
|
||
CallStatus string `gorm:"type:varchar(50);comment:通话状态" json:"call_status"`
|
||
// 创建时间,自动生成
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (ChatMessage) TableName() string {
|
||
return "chat_messages"
|
||
}
|
||
|
||
// ==========================================
|
||
// 交互数据传输对象 (DTO - Data Transfer Object)
|
||
// ==========================================
|
||
|
||
/**
|
||
* WsPayload
|
||
* 作用:WebSocket 传输的最外层通用载荷。
|
||
* 逻辑:根据 RequestType 字段决定如何解析 Data。
|
||
*/
|
||
type WsPayload struct {
|
||
// 请求类型: "bind", "heartbeat", "send_message", "receive_message"
|
||
RequestType string `json:"request_type"`
|
||
// 具体数据载荷,结构取决于 RequestType
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
/**
|
||
* SendMessageReq
|
||
* 作用:客户端发送消息或信令的请求参数结构。
|
||
*/
|
||
type SendMessageReq struct {
|
||
// [新增] 发送端的 WebSocket ClientID,用于在多端同步时排除自己
|
||
SenderClientID string `json:"sender_client_id,omitempty"`
|
||
|
||
// 指定目标客户端ID (选填,用于点对点精确控制)
|
||
TargetClientID string `json:"target_client_id,omitempty"`
|
||
// 指定目标用户ID (选填,用于发送给用户的所有设备)
|
||
ReceiverUserID string `json:"receiver_user_id,omitempty"`
|
||
// 房间ID
|
||
RoomID string `json:"room_id"`
|
||
// 消息类型
|
||
MessageType int `json:"message_type"`
|
||
// 内容
|
||
Content string `json:"content"`
|
||
// 时长
|
||
Duration int `json:"duration"`
|
||
// 辅助字段: 辅助元数据
|
||
Extra string `json:"extra,omitempty"`
|
||
|
||
// WebRTC 信令专用字段: 通话唯一ID
|
||
CallID string `json:"call_id,omitempty"`
|
||
// WebRTC 信令专用字段: 信令状态 (invite, offer, answer, candidate, hangup)
|
||
CallStatus string `json:"call_status,omitempty"`
|
||
}
|
||
|
||
/**
|
||
* UrlMeta
|
||
* 作用:URL 预览元数据结构 (存储在 Extra 字段中)
|
||
*/
|
||
type UrlMeta struct {
|
||
// 标题
|
||
Title string `json:"title"`
|
||
// 描述
|
||
Description string `json:"description"`
|
||
// 图片链接
|
||
Image string `json:"image"`
|
||
// 原始URL
|
||
Url string `json:"url"`
|
||
}
|
||
|
||
/**
|
||
* BindReq
|
||
* 作用:用户绑定请求参数。
|
||
*/
|
||
type BindReq struct {
|
||
// 用户ID
|
||
UserID string `json:"user_id"`
|
||
// WebSocket握手后获得的临时ID
|
||
ClientID string `json:"client_id"`
|
||
}
|
||
|
||
/**
|
||
* ICEServerConfig
|
||
* 作用:返回给前端的 TURN/STUN 配置信息。
|
||
*/
|
||
type ICEServerConfig struct {
|
||
// TURN服务器地址列表
|
||
Urls []string `json:"urls"`
|
||
// 鉴权用户名
|
||
Username string `json:"username,omitempty"`
|
||
// 鉴权密码
|
||
Credential string `json:"credential,omitempty"`
|
||
}
|
||
|
||
/**
|
||
* User
|
||
* 对应数据库表:users
|
||
* 作用:用户基本信息表
|
||
*/
|
||
type User struct {
|
||
// 用户唯一ID
|
||
ID string `gorm:"primaryKey;type:varchar(100);comment:用户唯一ID" json:"id"`
|
||
// 邮箱
|
||
Email string `gorm:"type:varchar(255);uniqueIndex;comment:邮箱" json:"email"`
|
||
// 手机号
|
||
Phone string `gorm:"type:varchar(20);uniqueIndex;comment:手机号" json:"phone"`
|
||
// 密码(加密后)
|
||
Password string `gorm:"type:varchar(255);comment:密码(加密后)" json:"-"`
|
||
// 用户名称
|
||
Name string `gorm:"type:varchar(100);comment:用户名称" json:"name"`
|
||
// 用户头像URL或字符
|
||
Avatar string `gorm:"type:varchar(500);comment:用户头像" json:"avatar"`
|
||
// 用户描述或签名
|
||
Desc string `gorm:"type:varchar(500);comment:用户描述或签名" json:"desc"`
|
||
// 地区
|
||
Region string `gorm:"type:varchar(100);comment:地区" json:"region"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (User) TableName() string {
|
||
return "users"
|
||
}
|
||
|
||
/**
|
||
* UserContact
|
||
* 对应数据库表:user_contacts
|
||
* 作用:用户联系人表,存储好友关系、分组、备注等信息
|
||
*/
|
||
type UserContact struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 用户ID - 当前用户
|
||
UserID string `gorm:"type:varchar(100);index;comment:用户ID" json:"user_id"`
|
||
// 联系人ID - 好友的用户ID
|
||
ContactID string `gorm:"type:varchar(100);index;comment:联系人ID" json:"contact_id"`
|
||
// 房间ID - 关联的房间ID
|
||
RoomID string `gorm:"type:varchar(100);index;comment:房间ID" json:"room_id"`
|
||
// 备注名称 - 用户自定义的好友备注
|
||
RemarkName string `gorm:"type:varchar(100);comment:备注名称" json:"remark_name"`
|
||
// 分组ID - 好友所属分组
|
||
GroupID uint `gorm:"type:int;index;comment:分组ID" json:"group_id"`
|
||
// 是否置顶
|
||
IsTop bool `gorm:"type:tinyint(1);default:0;comment:是否置顶" json:"is_top"`
|
||
// 是否免打扰
|
||
IsMuted bool `gorm:"type:tinyint(1);default:0;comment:是否免打扰" json:"is_muted"`
|
||
// 是否特别关心(高优先级提醒,类似 QQ 特别关心)
|
||
IsSpecialCare bool `gorm:"type:tinyint(1);default:0;comment:是否特别关心" json:"is_special_care"`
|
||
// 是否拉黑(加入黑名单,不再接收消息/出现在默认列表中)
|
||
IsBlocked bool `gorm:"type:tinyint(1);default:0;comment:是否拉黑" json:"is_blocked"`
|
||
// 最后聊天时间
|
||
LastChatTime *time.Time `gorm:"type:datetime;comment:最后聊天时间" json:"last_chat_time"`
|
||
// 最后一条消息
|
||
LastMessage string `gorm:"type:text;comment:最后一条消息" json:"last_message"`
|
||
// 未读消息数
|
||
UnreadCount int `gorm:"type:int;default:0;comment:未读消息数" json:"unread_count"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (UserContact) TableName() string {
|
||
return "user_contacts"
|
||
}
|
||
|
||
/**
|
||
* ContactGroup
|
||
* 对应数据库表:contact_groups
|
||
* 作用:联系人分组表
|
||
*/
|
||
type ContactGroup struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 用户ID - 分组所属用户
|
||
UserID string `gorm:"type:varchar(100);index;comment:用户ID" json:"user_id"`
|
||
// 分组名称
|
||
GroupName string `gorm:"type:varchar(100);comment:分组名称" json:"group_name"`
|
||
// 排序顺序
|
||
SortOrder int `gorm:"type:int;default:0;comment:排序顺序" json:"sort_order"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (ContactGroup) TableName() string {
|
||
return "contact_groups"
|
||
}
|
||
|
||
/**
|
||
* ChatRoom
|
||
* 对应数据库表:chat_rooms
|
||
* 作用:聊天房间表,支持点对点和群聊
|
||
*/
|
||
type ChatRoom struct {
|
||
// 房间ID - 主键
|
||
RoomID string `gorm:"primaryKey;type:varchar(100);comment:房间ID" json:"room_id"`
|
||
// 房间类型 - "p2p" 点对点 / "group" 群聊
|
||
RoomType string `gorm:"type:varchar(20);index;comment:房间类型" json:"room_type"`
|
||
// 房间名称 - 群聊时显示
|
||
RoomName string `gorm:"type:varchar(200);comment:房间名称" json:"room_name"`
|
||
// 房间头像 - 群聊时显示
|
||
RoomAvatar string `gorm:"type:varchar(500);comment:房间头像" json:"room_avatar"`
|
||
// 群主ID - 群聊必填,单聊为0
|
||
OwnerID string `gorm:"type:varchar(100);index;default:0;comment:群主ID(群聊必填,单聊为0)" json:"owner_id"`
|
||
// 管理员ID列表 - 逗号分隔
|
||
AdminIDs string `gorm:"type:varchar(500);comment:管理员ID列表(逗号分隔)" json:"admin_ids"`
|
||
// 创建者ID
|
||
CreatorID string `gorm:"type:varchar(100);index;comment:创建者ID" json:"creator_id"`
|
||
// 最后消息时间
|
||
LastMessageTime *time.Time `gorm:"type:datetime;index;comment:最后消息时间" json:"last_message_time"`
|
||
// 最后消息内容
|
||
LastMessage string `gorm:"type:text;comment:最后消息内容" json:"last_message"`
|
||
// 群公告 - 仅群聊使用
|
||
Announcement string `gorm:"type:text;comment:群公告" json:"announcement"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (ChatRoom) TableName() string {
|
||
return "chat_rooms"
|
||
}
|
||
|
||
/**
|
||
* RoomMember
|
||
* 对应数据库表:room_members
|
||
* 作用:房间成员表,存储房间与用户的关联关系
|
||
*/
|
||
type RoomMember struct {
|
||
// 房间ID
|
||
RoomID string `gorm:"type:varchar(100);primaryKey;comment:房间ID" json:"room_id"`
|
||
// 用户ID
|
||
UserID string `gorm:"type:varchar(100);primaryKey;comment:用户ID" json:"user_id"`
|
||
// 成员角色:0-成员 1-管理员 2-群主
|
||
Role int8 `gorm:"type:tinyint(1);default:0;comment:成员角色(0=成员,1=管理员,2=群主)" json:"role"`
|
||
// 加入时间
|
||
JoinedAt time.Time `gorm:"type:datetime;autoCreateTime;comment:加入时间" json:"joined_at"`
|
||
// 禁言到期时间(null或过期时间之前表示未禁言)
|
||
MutedUntil *time.Time `gorm:"type:datetime;comment:禁言到期时间" json:"muted_until,omitempty"`
|
||
// 用户信息(关联查询,不存储在数据库中)
|
||
User *User `gorm:"foreignKey:UserID;references:ID" json:"user,omitempty"`
|
||
// 群名片(可选,用于群聊中显示的自定义昵称)
|
||
Nickname string `gorm:"-" json:"nickname,omitempty"`
|
||
}
|
||
|
||
// IsMuted 判断成员是否被禁言
|
||
func (m *RoomMember) IsMuted() bool {
|
||
if m.MutedUntil == nil {
|
||
return false
|
||
}
|
||
return m.MutedUntil.After(time.Now())
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (RoomMember) TableName() string {
|
||
return "room_members"
|
||
}
|
||
|
||
/**
|
||
* FriendRequest
|
||
* 对应数据库表:friend_requests
|
||
* 作用:好友申请表
|
||
*/
|
||
type FriendRequest struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 发送者用户ID
|
||
FromUserID string `gorm:"type:varchar(100);index;comment:发送者用户ID" json:"from_user_id"`
|
||
// 接收者用户ID
|
||
ToUserID string `gorm:"type:varchar(100);index;comment:接收者用户ID" json:"to_user_id"`
|
||
// 申请消息
|
||
Message string `gorm:"type:text;comment:申请消息" json:"message"`
|
||
// 状态 - "pending", "accepted", "rejected"
|
||
Status string `gorm:"type:varchar(20);default:'pending';index;comment:状态" json:"status"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (FriendRequest) TableName() string {
|
||
return "friend_requests"
|
||
}
|
||
|
||
/**
|
||
* VerificationCode
|
||
* 对应数据库表:verification_codes
|
||
* 作用:验证码表
|
||
*/
|
||
type VerificationCode struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 邮箱或手机号
|
||
Target string `gorm:"type:varchar(255);index;comment:邮箱或手机号" json:"target"`
|
||
// 验证码
|
||
Code string `gorm:"type:varchar(10);comment:验证码" json:"-"`
|
||
// 类型 - "email" 或 "sms"
|
||
Type string `gorm:"type:varchar(20);comment:类型" json:"type"`
|
||
// 过期时间
|
||
ExpiresAt time.Time `gorm:"type:datetime;index;comment:过期时间" json:"expires_at"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (VerificationCode) TableName() string {
|
||
return "verification_codes"
|
||
}
|
||
|
||
/**
|
||
* Attachment
|
||
* 对应数据库表:attachments
|
||
* 作用:附件表,记录上传的文件信息
|
||
*/
|
||
type Attachment struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 上传者ID
|
||
UploaderID string `gorm:"type:varchar(100);index;comment:上传者ID" json:"uploader_id"`
|
||
// 文件名
|
||
FileName string `gorm:"type:varchar(255);comment:文件名" json:"file_name"`
|
||
// 文件类型 - "image" 或 "video"
|
||
FileType string `gorm:"type:varchar(20);index;comment:文件类型" json:"file_type"`
|
||
// 文件大小(字节)
|
||
FileSize int64 `gorm:"type:bigint;comment:文件大小(字节)" json:"file_size"`
|
||
// 文件路径
|
||
FilePath string `gorm:"type:varchar(500);comment:文件路径" json:"file_path"`
|
||
// 文件URL
|
||
FileURL string `gorm:"type:varchar(500);comment:文件URL" json:"file_url"`
|
||
// MIME类型
|
||
MimeType string `gorm:"type:varchar(100);comment:MIME类型" json:"mime_type"`
|
||
// 宽度(图片/视频)
|
||
Width int `gorm:"type:int;comment:宽度" json:"width"`
|
||
// 高度(图片/视频)
|
||
Height int `gorm:"type:int;comment:高度" json:"height"`
|
||
// 时长(视频,秒)
|
||
Duration int `gorm:"type:int;comment:时长(秒)" json:"duration"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (Attachment) TableName() string {
|
||
return "attachments"
|
||
}
|
||
|
||
/**
|
||
* ApiRequestLog
|
||
* 对应数据库表:api_request_logs
|
||
* 作用:接口请求日志表,记录所有API请求信息
|
||
*/
|
||
type ApiRequestLog struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 请求路由
|
||
Route string `gorm:"type:varchar(255);index;comment:请求路由" json:"route"`
|
||
// 请求IP
|
||
IP string `gorm:"type:varchar(50);index;comment:请求IP" json:"ip"`
|
||
// IP归属地
|
||
IPLocation string `gorm:"type:varchar(255);comment:IP归属地" json:"ip_location"`
|
||
// 请求用户ID(未登录为0)
|
||
UserID string `gorm:"type:varchar(100);index;comment:请求用户ID" json:"user_id"`
|
||
// 请求方式
|
||
Method string `gorm:"type:varchar(10);comment:请求方式" json:"method"`
|
||
// 请求参数(JSON)
|
||
RequestParams string `gorm:"type:text;comment:请求参数" json:"request_params"`
|
||
// 返回参数(JSON)
|
||
ResponseParams string `gorm:"type:text;comment:返回参数" json:"response_params"`
|
||
// 返回code
|
||
ResponseCode int `gorm:"type:int;index;comment:返回code" json:"response_code"`
|
||
// 返回http状态
|
||
HTTPStatus int `gorm:"type:int;comment:返回http状态" json:"http_status"`
|
||
// 请求时间
|
||
RequestTime time.Time `gorm:"type:datetime;index;comment:请求时间" json:"request_time"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (ApiRequestLog) TableName() string {
|
||
return "api_request_logs"
|
||
}
|
||
|
||
/**
|
||
* ChatConversation
|
||
* 对应数据库表:chat_conversations
|
||
* 作用:用户级别的最近会话列表,支持置顶、免打扰和未读计数等功能
|
||
*/
|
||
type ChatConversation struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 所属用户ID(当前登录用户)
|
||
UserID string `gorm:"type:varchar(100);index;comment:用户ID" json:"user_id"`
|
||
// 目标ID:好友ID或群ID
|
||
TargetID string `gorm:"type:varchar(100);index;comment:目标ID(好友或群)" json:"target_id"`
|
||
// 房间ID:与 chat_messages / chat_rooms 中的 room_id 一致
|
||
RoomID string `gorm:"type:varchar(100);index;comment:房间ID" json:"room_id"`
|
||
// 会话类型:1-私聊 2-群聊
|
||
Type int `gorm:"type:int;comment:会话类型(1=私聊,2=群聊)" json:"type"`
|
||
// 是否置顶
|
||
IsTop bool `gorm:"type:tinyint(1);default:0;comment:是否置顶" json:"is_top"`
|
||
// 是否免打扰
|
||
IsMuted bool `gorm:"type:tinyint(1);default:0;comment:是否免打扰" json:"is_muted"`
|
||
// 是否特别关心(用于在前端高亮显示)
|
||
IsSpecialCare bool `gorm:"type:tinyint(1);default:0;comment:是否特别关心" json:"is_special_care"`
|
||
// 未读消息数
|
||
UnreadCount int `gorm:"type:int;default:0;comment:未读消息数" json:"unread_count"`
|
||
// 最后一条消息内容(用于列表摘要)
|
||
LastMessage string `gorm:"type:varchar(500);comment:最后一条消息内容" json:"last_message"`
|
||
// 最后消息时间
|
||
LastTime time.Time `gorm:"type:datetime;index;comment:最后消息时间" json:"last_time"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
// 目标用户信息(关联查询,不存储在数据库中)
|
||
// 注意:不使用外键约束,因为 target_id 可能是用户ID(私聊)或群ID(群聊)
|
||
// 使用 - 前缀禁用 GORM 的自动外键创建
|
||
TargetUser *User `gorm:"-" json:"target_user,omitempty"`
|
||
// 群聊信息(关联查询,仅群聊时使用,不存储在数据库中)
|
||
// 使用 - 前缀禁用 GORM 的自动外键创建,手动加载
|
||
Room *ChatRoom `gorm:"-" json:"room,omitempty"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (ChatConversation) TableName() string {
|
||
return "chat_conversations"
|
||
}
|
||
|
||
/**
|
||
* LoginLog
|
||
* 对应数据库表:login_logs
|
||
* 作用:登录日志表,记录所有登录尝试
|
||
*/
|
||
type LoginLog struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 登录账号
|
||
Account string `gorm:"type:varchar(255);index;comment:登录账号" json:"account"`
|
||
// 登录ID(失败记录0)
|
||
UserID string `gorm:"type:varchar(100);index;comment:登录ID" json:"user_id"`
|
||
// 归属地(IP归属地)
|
||
Location string `gorm:"type:varchar(255);comment:归属地" json:"location"`
|
||
// 地址(IP地址)
|
||
IP string `gorm:"type:varchar(50);index;comment:IP地址" json:"ip"`
|
||
// 成功/失败状态(true=成功,false=失败)
|
||
Success bool `gorm:"type:tinyint(1);index;comment:成功状态" json:"success"`
|
||
// 登录时间
|
||
LoginTime time.Time `gorm:"type:datetime;index;comment:登录时间" json:"login_time"`
|
||
}
|
||
|
||
// TableName 指定表名和注释
|
||
func (LoginLog) TableName() string {
|
||
return "login_logs"
|
||
}
|
||
|
||
/**
|
||
* ClusterMessage
|
||
* 作用:内部通信,Redis Pub/Sub 集群消息转发结构。
|
||
*/
|
||
type ClusterMessage struct {
|
||
// 发出该消息的源节点ID
|
||
SenderNodeID string `json:"sender_node_id"`
|
||
// 目标用户ID
|
||
TargetUserID string `json:"target_user_id"`
|
||
// 原始消息体 (WsPayload)
|
||
Payload interface{} `json:"payload"`
|
||
}
|
||
|
||
// ==========================================
|
||
// 认证相关 DTO
|
||
// ==========================================
|
||
|
||
/**
|
||
* LoginReq
|
||
* 作用:登录请求参数
|
||
*/
|
||
type LoginReq struct {
|
||
// 账号(邮箱或手机号)
|
||
Account string `json:"account" binding:"required"`
|
||
// 密码
|
||
Password string `json:"password" binding:"required"`
|
||
// 记住我
|
||
Remember bool `json:"remember,omitempty"`
|
||
}
|
||
|
||
/**
|
||
* RegisterReq
|
||
* 作用:注册请求参数
|
||
*/
|
||
type RegisterReq struct {
|
||
// 邮箱
|
||
Email string `json:"email" binding:"required,email"`
|
||
// 手机号
|
||
Phone string `json:"phone" binding:"required"`
|
||
// 密码
|
||
Password string `json:"password" binding:"required,min=8"`
|
||
// 确认密码
|
||
ConfirmPassword string `json:"confirm_password" binding:"required"`
|
||
// 验证码(可选)
|
||
Code string `json:"code,omitempty"`
|
||
// 同意用户协议
|
||
AgreeTerms bool `json:"agree_terms" binding:"required"`
|
||
}
|
||
|
||
/**
|
||
* LoginResponse
|
||
* 作用:登录响应
|
||
*/
|
||
type LoginResponse struct {
|
||
// Token
|
||
Token string `json:"token"`
|
||
// 用户信息
|
||
User User `json:"user"`
|
||
}
|
||
|
||
/**
|
||
* RegisterResponse
|
||
* 作用:注册响应
|
||
*/
|
||
type RegisterResponse struct {
|
||
// Token
|
||
Token string `json:"token"`
|
||
// 用户信息
|
||
User User `json:"user"`
|
||
}
|
||
|
||
/**
|
||
* SendCodeReq
|
||
* 作用:发送验证码请求
|
||
*/
|
||
type SendCodeReq struct {
|
||
// 邮箱或手机号
|
||
Target string `json:"target" binding:"required"`
|
||
// 类型 - "email" 或 "sms"
|
||
Type string `json:"type" binding:"required,oneof=email sms"`
|
||
}
|
||
|
||
// ==========================================
|
||
// 朋友圈相关实体 (Moments)
|
||
// ==========================================
|
||
|
||
/**
|
||
* Moment
|
||
* 对应数据库表:moments
|
||
* 作用:朋友圈动态表
|
||
*/
|
||
type Moment struct {
|
||
// 动态ID
|
||
ID uint `gorm:"primaryKey;comment:动态ID" json:"id"`
|
||
// 发布者ID
|
||
UserID string `gorm:"type:varchar(100);index;comment:发布者ID" json:"user_id"`
|
||
// 文字内容
|
||
Content string `gorm:"type:text;comment:文字内容" json:"content"`
|
||
// 媒体类型: 0=纯文字 1=图片 2=视频
|
||
MediaType int8 `gorm:"type:tinyint;default:0;comment:媒体类型" json:"media_type"`
|
||
// 媒体URL列表(JSON数组)
|
||
MediaURLs string `gorm:"type:text;comment:媒体URL列表" json:"media_urls"`
|
||
// 位置信息
|
||
Location string `gorm:"type:varchar(255);comment:位置信息" json:"location"`
|
||
// 可见性: 0=公开 1=仅好友 2=部分好友可见 3=部分好友不可见
|
||
Visibility int8 `gorm:"type:tinyint;default:0;comment:可见性" json:"visibility"`
|
||
// 可见/不可见用户ID列表(JSON数组)
|
||
VisibleUserIDs string `gorm:"type:text;comment:可见用户ID列表" json:"visible_user_ids"`
|
||
// @的用户ID列表(JSON数组)
|
||
MentionUserIDs string `gorm:"type:text;comment:@的用户ID列表" json:"mention_user_ids"`
|
||
// 话题标签(JSON数组)
|
||
TopicTags string `gorm:"type:varchar(500);comment:话题标签" json:"topic_tags"`
|
||
// 点赞数
|
||
LikeCount int `gorm:"type:int;default:0;comment:点赞数" json:"like_count"`
|
||
// 评论数
|
||
CommentCount int `gorm:"type:int;default:0;comment:评论数" json:"comment_count"`
|
||
// 是否已删除
|
||
IsDeleted bool `gorm:"type:tinyint(1);default:0;comment:是否已删除" json:"-"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 更新时间
|
||
UpdatedAt time.Time `gorm:"autoUpdateTime;comment:更新时间" json:"updated_at"`
|
||
// 关联字段(不存储在数据库中)
|
||
User *User `gorm:"-" json:"user,omitempty"`
|
||
IsLiked bool `gorm:"-" json:"is_liked"`
|
||
Likes []MomentLike `gorm:"-" json:"likes,omitempty"`
|
||
Comments []MomentComment `gorm:"-" json:"comments,omitempty"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (Moment) TableName() string {
|
||
return "moments"
|
||
}
|
||
|
||
/**
|
||
* MomentLike
|
||
* 对应数据库表:moment_likes
|
||
* 作用:动态点赞表
|
||
*/
|
||
type MomentLike struct {
|
||
// 主键ID
|
||
ID uint `gorm:"primaryKey;comment:主键ID" json:"id"`
|
||
// 动态ID
|
||
MomentID uint `gorm:"type:bigint;index;comment:动态ID" json:"moment_id"`
|
||
// 点赞用户ID
|
||
UserID string `gorm:"type:varchar(100);index;comment:点赞用户ID" json:"user_id"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 关联字段(不存储在数据库中)
|
||
User *User `gorm:"-" json:"user,omitempty"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (MomentLike) TableName() string {
|
||
return "moment_likes"
|
||
}
|
||
|
||
/**
|
||
* MomentComment
|
||
* 对应数据库表:moment_comments
|
||
* 作用:动态评论表
|
||
*/
|
||
type MomentComment struct {
|
||
// 评论ID
|
||
ID uint `gorm:"primaryKey;comment:评论ID" json:"id"`
|
||
// 动态ID
|
||
MomentID uint `gorm:"type:bigint;index;comment:动态ID" json:"moment_id"`
|
||
// 评论者ID
|
||
UserID string `gorm:"type:varchar(100);index;comment:评论者ID" json:"user_id"`
|
||
// 回复的评论ID(NULL为直接评论)
|
||
ReplyToCommentID *uint `gorm:"type:bigint;index;comment:回复的评论ID" json:"reply_to_comment_id"`
|
||
// 回复的用户ID
|
||
ReplyToUserID string `gorm:"type:varchar(100);comment:回复的用户ID" json:"reply_to_user_id"`
|
||
// 评论内容
|
||
Content string `gorm:"type:text;comment:评论内容" json:"content"`
|
||
// 是否已删除
|
||
IsDeleted bool `gorm:"type:tinyint(1);default:0;comment:是否已删除" json:"-"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;comment:创建时间" json:"created_at"`
|
||
// 关联字段(不存储在数据库中)
|
||
User *User `gorm:"-" json:"user,omitempty"`
|
||
ReplyToUser *User `gorm:"-" json:"reply_to_user,omitempty"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (MomentComment) TableName() string {
|
||
return "moment_comments"
|
||
}
|
||
|
||
/**
|
||
* MomentNotification
|
||
* 对应数据库表:moment_notifications
|
||
* 作用:朋友圈通知表
|
||
*/
|
||
type MomentNotification struct {
|
||
// 通知ID
|
||
ID uint `gorm:"primaryKey;comment:通知ID" json:"id"`
|
||
// 接收通知的用户ID
|
||
UserID string `gorm:"type:varchar(100);index;comment:接收通知的用户ID" json:"user_id"`
|
||
// 触发通知的用户ID
|
||
FromUserID string `gorm:"type:varchar(100);comment:触发通知的用户ID" json:"from_user_id"`
|
||
// 关联的动态ID
|
||
MomentID uint `gorm:"type:bigint;index;comment:关联的动态ID" json:"moment_id"`
|
||
// 通知类型: 1=点赞 2=评论 3=回复 4=@提及
|
||
Type int8 `gorm:"type:tinyint;comment:通知类型" json:"type"`
|
||
// 关联的评论ID
|
||
CommentID *uint `gorm:"type:bigint;comment:关联的评论ID" json:"comment_id"`
|
||
// 是否已读
|
||
IsRead bool `gorm:"type:tinyint(1);default:0;index;comment:是否已读" json:"is_read"`
|
||
// 创建时间
|
||
CreatedAt time.Time `gorm:"autoCreateTime;index;comment:创建时间" json:"created_at"`
|
||
// 关联字段(不存储在数据库中)
|
||
FromUser *User `gorm:"-" json:"from_user,omitempty"`
|
||
Moment *Moment `gorm:"-" json:"moment,omitempty"`
|
||
Comment *MomentComment `gorm:"-" json:"comment,omitempty"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (MomentNotification) TableName() string {
|
||
return "moment_notifications"
|
||
}
|
||
|
||
// ==========================================
|
||
// 朋友圈相关 DTO
|
||
// ==========================================
|
||
|
||
/**
|
||
* CreateMomentReq
|
||
* 作用:发布动态请求参数
|
||
*/
|
||
type CreateMomentReq struct {
|
||
// 文字内容
|
||
Content string `json:"content"`
|
||
// 媒体类型: 0=纯文字 1=图片 2=视频
|
||
MediaType int8 `json:"media_type"`
|
||
// 媒体URL列表
|
||
MediaURLs []string `json:"media_urls"`
|
||
// 位置信息
|
||
Location string `json:"location,omitempty"`
|
||
// 可见性: 0=公开 1=仅好友 2=部分好友可见 3=部分好友不可见
|
||
Visibility int8 `json:"visibility"`
|
||
// 可见/不可见用户ID列表
|
||
VisibleUserIDs []string `json:"visible_user_ids,omitempty"`
|
||
// @的用户ID列表
|
||
MentionUserIDs []string `json:"mention_user_ids,omitempty"`
|
||
// 话题标签
|
||
TopicTags []string `json:"topic_tags,omitempty"`
|
||
}
|
||
|
||
/**
|
||
* CreateCommentReq
|
||
* 作用:发表评论请求参数
|
||
*/
|
||
type CreateCommentReq struct {
|
||
// 评论内容
|
||
Content string `json:"content" binding:"required"`
|
||
// 回复的评论ID(可选,回复评论时使用)
|
||
ReplyToCommentID *uint `json:"reply_to_comment_id,omitempty"`
|
||
}
|
||
|
||
/**
|
||
* MomentNotifPayload
|
||
* 作用:WebSocket 推送朋友圈通知的数据结构
|
||
*/
|
||
type MomentNotifPayload struct {
|
||
// 通知类型: "like", "comment", "reply", "mention"
|
||
Type string `json:"type"`
|
||
// 动态ID
|
||
MomentID uint `json:"moment_id"`
|
||
// 触发通知的用户
|
||
FromUser *User `json:"from_user"`
|
||
// 评论内容(评论/回复时使用)
|
||
Content string `json:"content,omitempty"`
|
||
// 评论ID
|
||
CommentID uint `json:"comment_id,omitempty"`
|
||
}
|
||
|
||
// 朋友圈通知类型常量
|
||
const (
|
||
MomentNotifTypeLike = 1 // 点赞
|
||
MomentNotifTypeComment = 2 // 评论
|
||
MomentNotifTypeReply = 3 // 回复
|
||
MomentNotifTypeMention = 4 // @提及
|
||
)
|
||
|
||
// 动态可见性常量
|
||
const (
|
||
MomentVisibilityPublic = 0 // 公开
|
||
MomentVisibilityFriendsOnly = 1 // 仅好友可见
|
||
MomentVisibilityPartialVisible = 2 // 部分好友可见
|
||
MomentVisibilityPartialHidden = 3 // 部分好友不可见
|
||
)
|
||
|
||
// 媒体类型常量
|
||
const (
|
||
MomentMediaTypeText = 0 // 纯文字
|
||
MomentMediaTypeImage = 1 // 图片
|
||
MomentMediaTypeVideo = 2 // 视频
|
||
)
|
||
|
||
// ==========================================
|
||
// 常量定义
|
||
// ==========================================
|
||
|
||
const (
|
||
// Redis Key 前缀: 用户所在节点映射 (Hash结构或String结构)
|
||
KeyUserNodeMap = "ws:user:node:"
|
||
// Redis Channel: 集群广播频道
|
||
ChanClusterBroadcast = "ws:cluster:broadcast"
|
||
|
||
// 文件大小限制(字节)
|
||
MaxImageSize = 10 * 1024 * 1024 // 10MB
|
||
MaxVideoSize = 500 * 1024 * 1024 // 500MB
|
||
MaxAudioSize = 50 * 1024 * 1024 // 50MB
|
||
MaxFileSize = 100 * 1024 * 1024 // 100MB
|
||
|
||
// 消息类型常量
|
||
MessageTypeText = 0 // 文本
|
||
MessageTypeImage = 1 // 图片
|
||
MessageTypeAudio = 2 // 语音
|
||
MessageTypeVideo = 3 // 视频
|
||
MessageTypeSystem = 4 // 系统消息
|
||
MessageTypeFriendNotif = 5 // 好友通知
|
||
MessageTypeSignal = 6 // 信令消息
|
||
MessageTypeGroupNotif = 7 // 群通知
|
||
MessageTypeFile = 8 // 文件
|
||
MessageTypeMoments = 9 // 朋友圈通知(预留)
|
||
)
|