package models import ( "encoding/json" "time" "gorm.io/gorm" ) // JSONB 已定义在 collection_asset.go(复用) // ========== 1. 举报分类字典 ========== type ReportCategory struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` Code string `gorm:"type:varchar(50);not null;uniqueIndex;column:code"` Name string `gorm:"type:varchar(50);not null;column:name"` Description *string `gorm:"type:varchar(200);column:description"` Severity int16 `gorm:"not null;default:1;column:severity"` Enabled bool `gorm:"not null;default:true;column:enabled"` SortOrder int32 `gorm:"not null;default:0;column:sort_order"` CreatedAt int64 `gorm:"not null;column:created_at"` UpdatedAt int64 `gorm:"not null;column:updated_at"` } func (ReportCategory) TableName() string { return "report_categories" } func (c *ReportCategory) BeforeCreate(tx *gorm.DB) error { now := unixMilliNow() if c.CreatedAt == 0 { c.CreatedAt = now } c.UpdatedAt = now return nil } func (c *ReportCategory) BeforeUpdate(tx *gorm.DB) error { c.UpdatedAt = unixMilliNow() return nil } // ========== 2. 反馈分类字典 ========== type FeedbackCategory struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` Code string `gorm:"type:varchar(50);not null;uniqueIndex;column:code"` Name string `gorm:"type:varchar(50);not null;column:name"` Description *string `gorm:"type:varchar(200);column:description"` Enabled bool `gorm:"not null;default:true;column:enabled"` SortOrder int32 `gorm:"not null;default:0;column:sort_order"` CreatedAt int64 `gorm:"not null;column:created_at"` UpdatedAt int64 `gorm:"not null;column:updated_at"` } func (FeedbackCategory) TableName() string { return "feedback_categories" } func (c *FeedbackCategory) BeforeCreate(tx *gorm.DB) error { now := unixMilliNow() if c.CreatedAt == 0 { c.CreatedAt = now } c.UpdatedAt = now return nil } func (c *FeedbackCategory) BeforeUpdate(tx *gorm.DB) error { c.UpdatedAt = unixMilliNow() return nil } // ========== 3. 举报工单主表 ========== type Report struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` ReporterID int64 `gorm:"not null;column:reporter_id"` StarID *int64 `gorm:"column:star_id"` TargetType string `gorm:"type:varchar(30);not null;column:target_type"` TargetID int64 `gorm:"not null;column:target_id"` TargetSnapshot JSONB `gorm:"type:jsonb;not null;column:target_snapshot"` TriggeredAutoHide bool `gorm:"not null;default:false;column:triggered_auto_hide"` CategoryCode string `gorm:"type:varchar(50);not null;column:category_code"` Description *string `gorm:"type:varchar(500);column:description"` IsAnonymous bool `gorm:"not null;default:false;column:is_anonymous"` Status string `gorm:"type:varchar(20);not null;default:'pending';column:status"` IsAutoHidden bool `gorm:"not null;default:false;column:is_auto_hidden"` ClaimedBy *int64 `gorm:"column:claimed_by"` ClaimedAt *int64 `gorm:"column:claimed_at"` ResolvedAction *string `gorm:"type:varchar(20);column:resolved_action"` ResolvedBy *int64 `gorm:"column:resolved_by"` ResolvedAt *int64 `gorm:"column:resolved_at"` ResolutionNote *string `gorm:"type:varchar(500);column:resolution_note"` CreatedAt int64 `gorm:"not null;column:created_at"` UpdatedAt int64 `gorm:"not null;column:updated_at"` } func (Report) TableName() string { return "reports" } func (r *Report) BeforeCreate(tx *gorm.DB) error { now := unixMilliNow() if r.CreatedAt == 0 { r.CreatedAt = now } r.UpdatedAt = now return nil } func (r *Report) BeforeUpdate(tx *gorm.DB) error { r.UpdatedAt = unixMilliNow() return nil } // ========== 4. 举报证据图 ========== type ReportEvidence struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` ReportID int64 `gorm:"not null;column:report_id"` OSSKey string `gorm:"type:varchar(255);not null;column:oss_key"` OSSURL *string `gorm:"type:varchar(500);column:oss_url"` SortOrder int32 `gorm:"not null;default:0;column:sort_order"` CreatedAt int64 `gorm:"not null;column:created_at"` } func (ReportEvidence) TableName() string { return "report_evidence" } func (e *ReportEvidence) BeforeCreate(tx *gorm.DB) error { if e.CreatedAt == 0 { e.CreatedAt = unixMilliNow() } return nil } // ========== 5. 反馈工单 ========== type Feedback struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` UserID int64 `gorm:"not null;column:user_id"` StarID *int64 `gorm:"column:star_id"` CategoryCode string `gorm:"type:varchar(50);not null;column:category_code"` Title string `gorm:"type:varchar(100);not null;column:title"` Content string `gorm:"type:text;not null;column:content"` Contact *string `gorm:"type:varchar(320);column:contact"` IsAnonymous bool `gorm:"not null;default:false;column:is_anonymous"` Status string `gorm:"type:varchar(20);not null;default:'pending';column:status"` ClaimedBy *int64 `gorm:"column:claimed_by"` ClaimedAt *int64 `gorm:"column:claimed_at"` RepliedBy *int64 `gorm:"column:replied_by"` RepliedAt *int64 `gorm:"column:replied_at"` ReplyContent *string `gorm:"type:text;column:reply_content"` ClosedBy *int64 `gorm:"column:closed_by"` ClosedAt *int64 `gorm:"column:closed_at"` ArchivedBy *int64 `gorm:"column:archived_by"` ArchivedAt *int64 `gorm:"column:archived_at"` CreatedAt int64 `gorm:"not null;column:created_at"` UpdatedAt int64 `gorm:"not null;column:updated_at"` } func (Feedback) TableName() string { return "feedbacks" } func (f *Feedback) BeforeCreate(tx *gorm.DB) error { now := unixMilliNow() if f.CreatedAt == 0 { f.CreatedAt = now } f.UpdatedAt = now return nil } func (f *Feedback) BeforeUpdate(tx *gorm.DB) error { f.UpdatedAt = unixMilliNow() return nil } // ========== 6. 反馈截图 ========== type FeedbackEvidence struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` FeedbackID int64 `gorm:"not null;column:feedback_id"` OSSKey string `gorm:"type:varchar(255);not null;column:oss_key"` OSSURL *string `gorm:"type:varchar(500);column:oss_url"` SortOrder int32 `gorm:"not null;default:0;column:sort_order"` CreatedAt int64 `gorm:"not null;column:created_at"` } func (FeedbackEvidence) TableName() string { return "feedback_evidence" } func (e *FeedbackEvidence) BeforeCreate(tx *gorm.DB) error { if e.CreatedAt == 0 { e.CreatedAt = unixMilliNow() } return nil } // ========== 7. 审核动作流水 ========== type ModerationAction struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` ReportID *int64 `gorm:"column:report_id"` FeedbackID *int64 `gorm:"column:feedback_id"` AdminID int64 `gorm:"not null;column:admin_id"` ActionType string `gorm:"type:varchar(30);not null;column:action_type"` TargetType *string `gorm:"type:varchar(30);column:target_type"` TargetID *int64 `gorm:"column:target_id"` Note *string `gorm:"type:varchar(500);column:note"` Success bool `gorm:"not null;column:success"` ErrorMessage *string `gorm:"type:varchar(500);column:error_message"` CreatedAt int64 `gorm:"not null;column:created_at"` } func (ModerationAction) TableName() string { return "moderation_actions" } func (a *ModerationAction) BeforeCreate(tx *gorm.DB) error { if a.CreatedAt == 0 { a.CreatedAt = unixMilliNow() } return nil } // ========== 8. 对象受管控状态 ========== type ModerationTargetStatus struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` TargetType string `gorm:"type:varchar(30);not null;column:target_type"` TargetID int64 `gorm:"not null;column:target_id"` IsWarned bool `gorm:"not null;default:false;column:is_warned"` WarnCount int32 `gorm:"not null;default:0;column:warn_count"` LastWarnedAt *int64 `gorm:"column:last_warned_at"` LastActionType string `gorm:"type:varchar(30);not null;column:last_action_type"` Reason *string `gorm:"type:varchar(200);column:reason"` Source string `gorm:"type:varchar(30);not null;column:source"` SourceReportID *int64 `gorm:"column:source_report_id"` OperatorAdminID *int64 `gorm:"column:operator_admin_id"` CreatedAt int64 `gorm:"not null;column:created_at"` UpdatedAt int64 `gorm:"not null;column:updated_at"` } func (ModerationTargetStatus) TableName() string { return "moderation_target_status" } func (m *ModerationTargetStatus) BeforeCreate(tx *gorm.DB) error { now := unixMilliNow() if m.CreatedAt == 0 { m.CreatedAt = now } m.UpdatedAt = now return nil } func (m *ModerationTargetStatus) BeforeUpdate(tx *gorm.DB) error { m.UpdatedAt = unixMilliNow() return nil } // ========== 9. 管理员操作日志 ========== type AdminAuditLog struct { ID int64 `gorm:"primaryKey;autoIncrement;column:id"` AdminID int64 `gorm:"not null;column:admin_id"` Action string `gorm:"type:varchar(50);not null;column:action"` ResourceType *string `gorm:"type:varchar(30);column:resource_type"` ResourceID *int64 `gorm:"column:resource_id"` IP *string `gorm:"type:varchar(500);column:ip"` UserAgent *string `gorm:"type:varchar(500);column:user_agent"` Extra JSONB `gorm:"type:jsonb;column:extra"` CreatedAt int64 `gorm:"not null;column:created_at"` } func (AdminAuditLog) TableName() string { return "admin_audit_logs" } func (l *AdminAuditLog) BeforeCreate(tx *gorm.DB) error { if l.CreatedAt == 0 { l.CreatedAt = unixMilliNow() } return nil } // unixMilliNow returns current Unix millisecond timestamp func unixMilliNow() int64 { return time.Now().UnixMilli() } // ToJSONB marshals any value to JSONB bytes func ToJSONB(v interface{}) (JSONB, error) { return JSONB(mustMarshal(v)), nil } func mustMarshal(v interface{}) []byte { b, err := json.Marshal(v) if err != nil { return []byte("null") } return b }