This commit introduces several architectural improvements and optimizations across the codebase: - **Performance & Reliability**: - Implemented Redis pipelining in `ConversationCache.CacheMessage` to reduce network round-trips. - Added a circuit breaker to the JPush client to prevent cascading failures. - Introduced batch deletion and batch member addition capabilities in repositories. - Added message idempotency support using `client_msg_id` and a Redis-based cache. - Optimized WebSocket handling with connection limits (total and per-user) and improved error logging. - **Code Refactoring**: - Refactored `Router` to use a `RouterDeps` struct, simplifying the constructor and improving maintainability. - Unified model ID generation logic using new `id_helper.go` (supporting UUID and Snowflake). - Standardized JSON serialization/deserialization in models using `json_helper.go`. - Refactored DTO conversion logic, specifically for `UserResponse` (using functional options) and `Report` responses. - Removed redundant/deprecated DTOs like `PostDetailResponse` and `TradeItemDetailResponse`. - **Cache Improvements**: - Enhanced `LayeredCache` with `SetRaw` to avoid double-encoding when promoting values from Redis to local cache. - Added `DeleteBatch` support to the cache interface. - **Other Changes**: - Cleaned up `config.go` by removing redundant default values and explicit environment variable overrides. - Improved WebSocket registration flow to handle connection limits gracefully.
80 lines
3.0 KiB
Go
80 lines
3.0 KiB
Go
package model
|
||
|
||
import (
|
||
"time"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// CommentStatus 评论状态
|
||
type CommentStatus string
|
||
|
||
const (
|
||
CommentStatusDraft CommentStatus = "draft"
|
||
CommentStatusPending CommentStatus = "pending"
|
||
CommentStatusPublished CommentStatus = "published"
|
||
CommentStatusRejected CommentStatus = "rejected"
|
||
CommentStatusDeleted CommentStatus = "deleted"
|
||
)
|
||
|
||
// Comment 评论实体
|
||
type Comment struct {
|
||
ID string `json:"id" gorm:"type:varchar(36);primaryKey"`
|
||
PostID string `json:"post_id" gorm:"type:varchar(36);not null;index:idx_comments_post_parent_status_created,priority:1"`
|
||
UserID string `json:"user_id" gorm:"type:varchar(36);index;not null"`
|
||
ParentID *string `json:"parent_id" gorm:"type:varchar(36);index:idx_comments_post_parent_status_created,priority:2"` // 父评论 ID(支持嵌套)
|
||
RootID *string `json:"root_id" gorm:"type:varchar(36);index:idx_comments_root_status_created,priority:1"` // 根评论 ID(用于高效查询)
|
||
Content string `json:"content" gorm:"type:text;not null"`
|
||
Segments MessageSegments `json:"segments,omitempty" gorm:"type:text"`
|
||
Images string `json:"images" gorm:"type:text"` // 图片URL列表,JSON数组格式
|
||
|
||
// 关联
|
||
User *User `json:"-" gorm:"foreignKey:UserID"`
|
||
Replies []*Comment `json:"-" gorm:"-"` // 子回复(手动加载,非 GORM 关联)
|
||
|
||
// 审核状态
|
||
Status CommentStatus `json:"status" gorm:"type:varchar(20);default:published;index:idx_comments_post_parent_status_created,priority:3;index:idx_comments_root_status_created,priority:2"`
|
||
ReviewedAt *time.Time `json:"reviewed_at" gorm:"type:timestamp"`
|
||
ReviewedBy string `json:"reviewed_by" gorm:"type:varchar(50)"`
|
||
RejectReason string `json:"reject_reason" gorm:"type:varchar(500)"`
|
||
|
||
// 统计
|
||
LikesCount int `json:"likes_count" gorm:"default:0"`
|
||
RepliesCount int `json:"replies_count" gorm:"default:0"`
|
||
|
||
// 软删除
|
||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||
|
||
// 时间戳
|
||
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime;index:idx_comments_post_parent_status_created,priority:4,sort:asc;index:idx_comments_root_status_created,priority:3,sort:asc"`
|
||
UpdatedAt time.Time `json:"updated_at" gorm:"autoUpdateTime"`
|
||
}
|
||
|
||
// BeforeCreate 创建前生成UUID
|
||
func (c *Comment) BeforeCreate(tx *gorm.DB) error {
|
||
SetUUIDIfEmpty(&c.ID)
|
||
return nil
|
||
}
|
||
|
||
func (Comment) TableName() string {
|
||
return "comments"
|
||
}
|
||
|
||
// CommentLike 评论点赞
|
||
type CommentLike struct {
|
||
ID string `json:"id" gorm:"type:varchar(36);primaryKey"`
|
||
CommentID string `json:"comment_id" gorm:"type:varchar(36);not null;uniqueIndex:idx_comment_like_user,priority:1"`
|
||
UserID string `json:"user_id" gorm:"type:varchar(36);not null;uniqueIndex:idx_comment_like_user,priority:2"`
|
||
CreatedAt time.Time `json:"created_at" gorm:"autoCreateTime"`
|
||
}
|
||
|
||
// BeforeCreate 创建前生成UUID
|
||
func (cl *CommentLike) BeforeCreate(tx *gorm.DB) error {
|
||
SetUUIDIfEmpty(&cl.ID)
|
||
return nil
|
||
}
|
||
|
||
func (CommentLike) TableName() string {
|
||
return "comment_likes"
|
||
}
|