feat: 友链/书库/移动端导航/排行榜等多模块功能
新增模块: - 友链(friendlink)后端处理 + 前端管理页与友链板 - 书库(library):导入、章节、封面、阅读页、横竖版自适应 AdaptiveCoverSlot - 顶栏导航(header_nav)配置与 MobileTabBar/MobileRailDrawers 移动端抽屉 - 排行榜 service 测试、站点页面测试、时间线发布(timeline_release) 其它改动: - 后端 handlers/services 全量小幅调整 - 前端组件、库函数、URL/品牌/站点 URL 工具更新 - Lightbox 图片、MdEntries 条目卡、coverColor 派生色相等前端能力
This commit is contained in:
@@ -62,8 +62,8 @@ func InitDB(dsn string) error {
|
||||
&ChatRoom{}, &ChatRoomMember{}, &ChatMessage{},
|
||||
&PointLedger{}, &PostContentUnlock{}, &PostAttachment{}, &PostAttachmentUnlock{},
|
||||
&Badge{}, &UserBadge{},
|
||||
&PostPollVote{}, &PostLotteryEntry{}, &Ad{}, &SidebarWidget{},
|
||||
&ImportRecord{},
|
||||
&PostPollVote{}, &PostLotteryEntry{}, &Ad{}, &SidebarWidget{}, &FriendLink{},
|
||||
&ImportRecord{}, &LibraryDoc{}, &LibraryFile{}, &LibrarySection{},
|
||||
); err != nil {
|
||||
return fmt.Errorf("自动迁移失败: %w", err)
|
||||
}
|
||||
|
||||
@@ -522,6 +522,52 @@ type SitePage struct {
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// LibraryDoc 书库条目(书籍/文档/纯 HTML 页展示;文件独立目录存储,仅经 API 消费)
|
||||
type LibraryDoc struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Slug string `gorm:"size:64;uniqueIndex;not null" json:"slug"`
|
||||
Title string `gorm:"size:200;not null" json:"title"`
|
||||
Description string `gorm:"type:text" json:"description"` // markdown 介绍,可空
|
||||
CoverURL string `gorm:"size:512" json:"cover_url"` // 可选图片封面(/uploads/images)
|
||||
Published bool `gorm:"not null;index" json:"published"`
|
||||
SortOrder int `gorm:"not null;default:0" json:"sort_order"`
|
||||
// EntriesAuto 全章节条目卡模式:开启后章节内容免写 [entries] 壳,
|
||||
// 「## 标题 + @tags/@summary/字段::值/@source 指令行」自动识别为条目卡(个别章节用 [entries:off] 例外)
|
||||
EntriesAuto bool `gorm:"not null;default:false" json:"entries_auto"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// LibraryFile 书库文件(html/pdf/epub 等;存 data/library,不进公开静态目录)
|
||||
type LibraryFile struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
DocID uint `gorm:"index;not null;default:0" json:"doc_id"`
|
||||
UserID uint `gorm:"index;not null" json:"user_id"` // 上传管理员
|
||||
Name string `gorm:"size:256;not null" json:"name"` // 原始文件名
|
||||
StoredName string `gorm:"size:64;not null" json:"-"` // 磁盘文件名
|
||||
Ext string `gorm:"size:16;not null;default:''" json:"ext"`
|
||||
MIME string `gorm:"size:128;not null;default:application/octet-stream" json:"mime"`
|
||||
Size int `gorm:"not null;default:0" json:"size"`
|
||||
DownloadCount int `gorm:"not null;default:0" json:"download_count"`
|
||||
SortOrder int `gorm:"not null;default:0" json:"sort_order"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// LibrarySection 书库章节(两级树:ParentID 空=章,非空=节;正文 markdown)
|
||||
type LibrarySection struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
DocID uint `gorm:"index;not null;default:0" json:"doc_id"`
|
||||
ParentID *uint `gorm:"index" json:"parent_id"` // nil=章;非空=节,父必须是同条目的章
|
||||
Title string `gorm:"size:200;not null" json:"title"`
|
||||
Content string `gorm:"type:text" json:"content"`
|
||||
SortOrder int `gorm:"not null;default:0" json:"sort_order"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// SiteSetting 站点级键值设置(如历史在线峰值 peak_online)
|
||||
type SiteSetting struct {
|
||||
Key string `gorm:"primaryKey;size:64" json:"key"`
|
||||
@@ -542,6 +588,24 @@ type SidebarWidget struct {
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// FriendLink 友情链接;申请审批制,status=pending 经管理员 approve 后前台可见
|
||||
type FriendLink struct {
|
||||
ID uint `gorm:"primarykey" json:"id"`
|
||||
Name string `gorm:"size:64;not null" json:"name"`
|
||||
URL string `gorm:"size:512;not null" json:"url"`
|
||||
Description string `gorm:"size:255" json:"description"`
|
||||
LogoURL string `gorm:"size:512" json:"logo_url"`
|
||||
Category string `gorm:"size:32;index" json:"category"`
|
||||
ReciprocalURL string `gorm:"size:512" json:"reciprocal_url"` // 申请人填写的回链地址,供站长核对
|
||||
SortOrder int `gorm:"not null;default:0;index" json:"sort_order"`
|
||||
Status string `gorm:"size:16;not null;default:'pending';index" json:"status"` // pending|approved|rejected
|
||||
ApplicantUserID *uint `gorm:"index" json:"applicant_user_id,omitempty"` // 后台直接新建时为 nil
|
||||
RejectReason string `gorm:"size:255" json:"reject_reason,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
}
|
||||
|
||||
// SiteDailyStats 站点日维度访问量(轻量 PV/UV)
|
||||
type SiteDailyStats struct {
|
||||
Date time.Time `gorm:"type:date;primaryKey" json:"date"`
|
||||
|
||||
Reference in New Issue
Block a user