feat: 书库导入导出/图片变体/书籍搜索/小组件运行时等

新增:
- 书库导入导出(library_import/library_export)及测试
- 图片变体生成(image_variants)与响应式图片(responsiveImage)
- 书籍搜索(bookSearch)+ BookSearch/LibrarySearchGrid 组件
- 小组件运行时(widgetRuntime)与静态检查(widgetLint)
- 上传缓存中间件(upload_cache)与字体 CSS 提取脚本

其它:
- 后端 handlers/services 全量调整
- 前端页面、组件、库函数与配置更新
This commit is contained in:
2026-10-01 03:06:05 +08:00
parent 7fbd6ba699
commit ff2ab286fb
141 changed files with 7527 additions and 1407 deletions

View File

@@ -457,37 +457,37 @@ type PostAttachmentDTO struct {
// PostDetail 帖子详情(含可见性裁剪与附件)
type PostDetail struct {
ID uint `json:"id"`
BoardID uint `json:"board_id"`
UserID uint `json:"user_id"`
Title string `json:"title"`
Content string `json:"content"`
Tags string `json:"tags"`
PostType string `json:"post_type"`
ContentAccess string `json:"content_access"`
AccessPoints int `json:"access_points"`
TypeMeta string `json:"type_meta"`
TypeStatus string `json:"type_status,omitempty"`
Pinned int `json:"pinned"`
Recommended bool `json:"recommended"`
Locked bool `json:"locked"` // 管理员手动锁定:普通用户不可编辑/回复(staff 豁免)
Status string `json:"status"`
LikeCount int `json:"like_count"`
ViewCount int `json:"view_count"`
CommentCount int `json:"comment_count"`
Liked bool `json:"liked"`
Favorited bool `json:"favorited"` // 当前查看者是否已收藏(详情接口实时填充)
Edited bool `json:"edited"` // 是否存在编辑历史快照(决定"更新于/编辑历史"入口展示)
ID uint `json:"id"`
BoardID uint `json:"board_id"`
UserID uint `json:"user_id"`
Title string `json:"title"`
Content string `json:"content"`
Tags string `json:"tags"`
PostType string `json:"post_type"`
ContentAccess string `json:"content_access"`
AccessPoints int `json:"access_points"`
TypeMeta string `json:"type_meta"`
TypeStatus string `json:"type_status,omitempty"`
Pinned int `json:"pinned"`
Recommended bool `json:"recommended"`
Locked bool `json:"locked"` // 管理员手动锁定:普通用户不可编辑/回复(staff 豁免)
Status string `json:"status"`
LikeCount int `json:"like_count"`
ViewCount int `json:"view_count"`
CommentCount int `json:"comment_count"`
Liked bool `json:"liked"`
Favorited bool `json:"favorited"` // 当前查看者是否已收藏(详情接口实时填充)
Edited bool `json:"edited"` // 是否存在编辑历史快照(决定"更新于/编辑历史"入口展示)
// 最后一条已发布评论时间;null=无回复(旧帖判定回落 created_at)
LastReplyAt *time.Time `json:"last_reply_at,omitempty"`
// 旧帖回复确认提示:按查看者实时计算,命中才返回;前端存在即弹确认框
NecroReply *NecroReplyHint `json:"necro_reply,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Board model.Board `json:"board"`
User model.User `json:"user"`
ContentLocked bool `json:"content_locked"`
AccessHint string `json:"access_hint,omitempty"`
NecroReply *NecroReplyHint `json:"necro_reply,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Board model.Board `json:"board"`
User model.User `json:"user"`
ContentLocked bool `json:"content_locked"`
AccessHint string `json:"access_hint,omitempty"`
Attachments []PostAttachmentDTO `json:"attachments"`
Question *QuestionState `json:"question,omitempty"`
Poll *PollState `json:"poll,omitempty"`
@@ -620,7 +620,7 @@ func buildPostDetail(post *model.Post) *PostDetail {
ContentAccess: model.NormalizeContentAccess(post.ContentAccess),
AccessPoints: post.AccessPoints, TypeMeta: post.TypeMeta,
TypeStatus: ComputeTypeStatus(post.PostType, post.TypeMeta),
Pinned: post.Pinned, Recommended: post.Recommended, Locked: post.Locked, Status: post.Status,
Pinned: post.Pinned, Recommended: post.Recommended, Locked: post.Locked, Status: post.Status,
LikeCount: post.LikeCount, ViewCount: post.ViewCount, CommentCount: post.CommentCount,
Liked: post.Liked, CreatedAt: post.CreatedAt, UpdatedAt: post.UpdatedAt,
Board: post.Board, User: post.User,