refactor: 统一 BaseModel 嵌入,修复 primaryKey 大小写不一致
Some checks failed
CI / Lint + Build (push) Has been cancelled

变更模型:
- Post: 嵌入 BaseModel,移除手动 ID/CreatedAt/UpdatedAt/DeletedAt
- Comment: 嵌入 BaseModel,保留 is_deleted 自定义软删除
- Announcement: 嵌入 BaseModel
- Category: 嵌入 BaseModel
- Folder + FolderItem: 嵌入 BaseModel
- CommunityFund: primaryKey → primarykey (统一小写)
This commit is contained in:
2026-06-22 03:09:19 +08:00
parent 2449a27eb5
commit c3c7390498
6 changed files with 52 additions and 70 deletions

View File

@ -4,14 +4,13 @@ import "time"
// Announcement 公告 // Announcement 公告
type Announcement struct { type Announcement struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
Title string `gorm:"type:varchar(200);not null" json:"title"`
Content string `gorm:"type:text;not null" json:"content"` Title string `gorm:"type:varchar(200);not null" json:"title"`
Type string `gorm:"type:varchar(20);default:info" json:"type"` // info / warning / success / error Content string `gorm:"type:text;not null" json:"content"`
IsActive bool `gorm:"default:true" json:"is_active"` Type string `gorm:"type:varchar(20);default:info" json:"type"` // info / warning / success / error
StartAt *time.Time `json:"start_at,omitempty"` IsActive bool `gorm:"default:true" json:"is_active"`
EndAt *time.Time `json:"end_at,omitempty"` StartAt *time.Time `json:"start_at,omitempty"`
Sort int `gorm:"default:0" json:"sort"` EndAt *time.Time `json:"end_at,omitempty"`
CreatedAt time.Time `json:"created_at"` Sort int `gorm:"default:0" json:"sort"`
UpdatedAt time.Time `json:"updated_at"`
} }

View File

@ -1,17 +1,14 @@
package model package model
import "time"
// Category 文章分类(两级树形结构) // Category 文章分类(两级树形结构)
type Category struct { type Category struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
Name string `gorm:"type:varchar(50);not null" json:"name"`
Slug string `gorm:"type:varchar(50);not null;uniqueIndex" json:"slug"` Name string `gorm:"type:varchar(50);not null" json:"name"`
Description string `gorm:"type:varchar(200);default:''" json:"description,omitempty"` Slug string `gorm:"type:varchar(50);not null;uniqueIndex" json:"slug"`
ParentID *uint `gorm:"index" json:"parent_id,omitempty"` Description string `gorm:"type:varchar(200);default:''" json:"description,omitempty"`
Sort int `gorm:"default:0" json:"sort"` ParentID *uint `gorm:"index" json:"parent_id,omitempty"`
CreatedAt time.Time `json:"created_at"` Sort int `gorm:"default:0" json:"sort"`
UpdatedAt time.Time `json:"updated_at"`
// 非 DB 字段(树形填充) // 非 DB 字段(树形填充)
Children []Category `gorm:"-" json:"children,omitempty"` Children []Category `gorm:"-" json:"children,omitempty"`

View File

@ -4,18 +4,17 @@ import "time"
// Comment 评论模型 // Comment 评论模型
type Comment struct { type Comment struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
PostID uint `gorm:"index;not null" json:"post_id"`
RootID uint `gorm:"index;not null" json:"root_id"` // 根评论ID顶级评论指向自身 PostID uint `gorm:"index;not null" json:"post_id"`
ParentID *uint `gorm:"index" json:"parent_id"` // 评论IDNULL=顶级评论 RootID uint `gorm:"index;not null" json:"root_id"` // 评论ID顶级评论指向自身
ReplyToUID uint `gorm:"default:0" json:"reply_to_uid"` // 被回复者UID ParentID *uint `gorm:"index" json:"parent_id"` // 父评论IDNULL=顶级评论
Body string `gorm:"type:text;not null" json:"body"` // 评论内容(纯文本 + 图片URL ReplyToUID uint `gorm:"default:0" json:"reply_to_uid"` // 被回复者UID
IsDeleted bool `gorm:"default:false;index" json:"is_deleted"` Body string `gorm:"type:text;not null" json:"body"` // 评论内容(纯文本 + 图片URL
LikesCount int `gorm:"default:0" json:"likes_count"` IsDeleted bool `gorm:"default:false;index" json:"is_deleted"`
DislikesCount int `gorm:"default:0" json:"dislikes_count"` // 仅后台可见 LikesCount int `gorm:"default:0" json:"likes_count"`
UserID uint `gorm:"index;not null" json:"user_id"` DislikesCount int `gorm:"default:0" json:"dislikes_count"` // 仅后台可见
CreatedAt time.Time `json:"created_at"` UserID uint `gorm:"index;not null" json:"user_id"`
UpdatedAt time.Time `json:"updated_at"`
// 非数据库字段(联表查询填充) // 非数据库字段(联表查询填充)
AuthorName string `gorm:"-:migration;<-:false;column:author_name" json:"author_name,omitempty"` AuthorName string `gorm:"-:migration;<-:false;column:author_name" json:"author_name,omitempty"`
@ -26,7 +25,6 @@ type Comment struct {
// RepliesCount 回复数非DB字段查询填充 // RepliesCount 回复数非DB字段查询填充
RepliesCount int `gorm:"-:migration;<-:false" json:"replies_count,omitempty"` RepliesCount int `gorm:"-:migration;<-:false" json:"replies_count,omitempty"`
// Mentions 有效@提及映射 original_username -> {uid, 当前显示名}非DB字段批量查询填充 // Mentions 有效@提及映射 original_username -> {uid, 当前显示名}非DB字段批量查询填充
// key=创建时的原始@用户名value={uid,当前显示名},用户改名后链接仍有效且显示新名
Mentions map[string]MentionInfo `gorm:"-" json:"mentions,omitempty"` Mentions map[string]MentionInfo `gorm:"-" json:"mentions,omitempty"`
} }

View File

@ -1,10 +1,7 @@
package model package model
import "time"
// CommunityFund 公户余额单行表id=1 // CommunityFund 公户余额单行表id=1
type CommunityFund struct { type CommunityFund struct {
ID uint `gorm:"primaryKey" json:"id"` ID uint `gorm:"primarykey" json:"id"`
Balance int `gorm:"not null;default:0" json:"balance"` // 余额×10允许负数 Balance int `gorm:"not null;default:0" json:"balance"` // 余额×10允许负数
UpdatedAt time.Time `json:"updated_at"`
} }

View File

@ -1,17 +1,16 @@
package model package model
import "time" // time imported by common.go
// Folder 收藏夹 // Folder 收藏夹
type Folder struct { type Folder struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
UserID uint `gorm:"index;not null" json:"user_id"`
Name string `gorm:"type:varchar(50);not null" json:"name"` UserID uint `gorm:"index;not null" json:"user_id"`
Description string `gorm:"type:varchar(200);default:''" json:"description"` Name string `gorm:"type:varchar(50);not null" json:"name"`
IsPublic bool `gorm:"default:false" json:"is_public"` Description string `gorm:"type:varchar(200);default:''" json:"description"`
IsDefault bool `gorm:"default:false" json:"is_default"` IsPublic bool `gorm:"default:false" json:"is_public"`
CreatedAt time.Time `json:"created_at"` IsDefault bool `gorm:"default:false" json:"is_default"`
UpdatedAt time.Time `json:"updated_at"`
// 联表查询填充(非数据库字段) // 联表查询填充(非数据库字段)
ItemCount int64 `gorm:"-:migration;<-:false;column:item_count" json:"item_count,omitempty"` ItemCount int64 `gorm:"-:migration;<-:false;column:item_count" json:"item_count,omitempty"`
@ -19,11 +18,11 @@ type Folder struct {
// FolderItem 收藏记录 // FolderItem 收藏记录
type FolderItem struct { type FolderItem struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
FolderID uint `gorm:"index;not null" json:"folder_id"`
PostID uint `gorm:"index;not null" json:"post_id"` FolderID uint `gorm:"index;not null" json:"folder_id"`
UserID uint `gorm:"index;not null" json:"user_id"` PostID uint `gorm:"index;not null" json:"post_id"`
CreatedAt time.Time `json:"created_at"` UserID uint `gorm:"index;not null" json:"user_id"`
// 联表查询填充 // 联表查询填充
PostTitle string `gorm:"-:migration;<-:false;column:post_title" json:"post_title,omitempty"` PostTitle string `gorm:"-:migration;<-:false;column:post_title" json:"post_title,omitempty"`

View File

@ -1,14 +1,11 @@
package model package model
import ( import "time"
"time"
"gorm.io/gorm"
)
// Post 帖子/文章模型 // Post 帖子/文章模型
type Post struct { type Post struct {
ID uint `gorm:"primarykey" json:"id"` BaseModel
Title string `gorm:"type:varchar(200);not null" json:"title"` Title string `gorm:"type:varchar(200);not null" json:"title"`
Body string `gorm:"type:text" json:"body"` // Markdown content Body string `gorm:"type:text" json:"body"` // Markdown content
Excerpt string `gorm:"type:varchar(500)" json:"excerpt"` // plain text summary for list Excerpt string `gorm:"type:varchar(500)" json:"excerpt"` // plain text summary for list
@ -31,20 +28,15 @@ type Post struct {
PinnedAt *time.Time `json:"pinned_at,omitempty"` // 置顶时间 PinnedAt *time.Time `json:"pinned_at,omitempty"` // 置顶时间
ScheduledAt *time.Time `gorm:"index" json:"scheduled_at,omitempty"` // 定时发布时间 ScheduledAt *time.Time `gorm:"index" json:"scheduled_at,omitempty"` // 定时发布时间
AllowComment bool `gorm:"default:true" json:"allow_comment"` AllowComment bool `gorm:"default:true" json:"allow_comment"`
CommentsCount int `gorm:"default:0" json:"comments_count"` // 评论数(冗余计数器) CommentsCount int `gorm:"default:0" json:"comments_count"` // 评论数(冗余计数器)
TotalEnergyReceived int `gorm:"default:0" json:"total_energy_received"` // 文章累计被赋能域能乘10冗余计数 TotalEnergyReceived int `gorm:"default:0" json:"total_energy_received"` // 文章累计被赋能域能乘10冗余计数
LikesCount int `gorm:"default:0" json:"likes_count"` // 点赞数(冗余计数器) LikesCount int `gorm:"default:0" json:"likes_count"` // 点赞数(冗余计数器)
DislikesCount int `gorm:"default:0" json:"dislikes_count"` // 踩数(冗余计数器,仅后台可见) DislikesCount int `gorm:"default:0" json:"dislikes_count"` // 踩数(冗余计数器,仅后台可见)
FavoritesCount int `gorm:"default:0" json:"favorites_count"` // 收藏数(冗余计数器) FavoritesCount int `gorm:"default:0" json:"favorites_count"` // 收藏数(冗余计数器)
ViewsCount int `gorm:"default:0" json:"views_count"` // 阅读数(冗余计数器,已登录去重) ViewsCount int `gorm:"default:0" json:"views_count"` // 阅读数(冗余计数器,已登录去重)
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// 非数据库字段(联表查询填充) // 非数据库字段(联表查询填充)
// gorm:"-:migration" 指定不创建/迁移该列,"<-:false" 禁止写入,"column:author_name" 允许
// 从 JOIN 查询的 users.username AS author_name 别名中读取
AuthorName string `gorm:"-:migration;<-:false;column:author_name" json:"author_name,omitempty"` AuthorName string `gorm:"-:migration;<-:false;column:author_name" json:"author_name,omitempty"`
} }