重构小程序图标组件,替换传统 emoji 为 SVG 图标,提升视觉一致性和可维护性。更新多个页面以使用新图标组件,优化用户界面体验。同时,调整了数据加载逻辑,确保更高效的状态管理和用户交互。
This commit is contained in:
@@ -223,6 +223,10 @@ func WarmBookPartsCache() {
|
||||
}
|
||||
|
||||
// BookAllChapters GET /api/book/all-chapters 返回所有章节(列表,来自 chapters 表)
|
||||
//
|
||||
// Deprecated: 小程序已迁移至 book/parts + chapters-by-part + book/stats,id↔mid 从各接口响应积累。
|
||||
// 保留以兼容旧版/管理端,计划后续下线。
|
||||
//
|
||||
// 排序须与管理端 PUT /api/db/book action=reorder 一致:按 sort_order 升序,同序按 id
|
||||
// 免费判断:system_config.free_chapters / chapter_config.freeChapters 优先于 chapters.is_free
|
||||
// 支持 excludeFixed=1:排除序言、尾声、附录(目录页固定模块,不参与中间篇章)
|
||||
@@ -398,6 +402,29 @@ func BookChaptersByPart(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"success": true, "data": list})
|
||||
}
|
||||
|
||||
// getOrderedChapterList 获取按 sort_order+id 排序的章节列表(复用 all-chapters 缓存)
|
||||
func getOrderedChapterList() []model.Chapter {
|
||||
var list []model.Chapter
|
||||
if cache.Get(context.Background(), cache.KeyAllChapters("default"), &list) && len(list) > 0 {
|
||||
return list
|
||||
}
|
||||
allChaptersCache.mu.RLock()
|
||||
if allChaptersCache.key == "default" && time.Now().Before(allChaptersCache.expires) && len(allChaptersCache.data) > 0 {
|
||||
list = allChaptersCache.data
|
||||
allChaptersCache.mu.RUnlock()
|
||||
return list
|
||||
}
|
||||
allChaptersCache.mu.RUnlock()
|
||||
db := database.DB()
|
||||
if err := db.Model(&model.Chapter{}).Select(allChaptersSelectCols).
|
||||
Order("COALESCE(sort_order, 999999) ASC, id ASC").
|
||||
Find(&list).Error; err != nil || len(list) == 0 {
|
||||
return nil
|
||||
}
|
||||
sortChaptersByNaturalID(list)
|
||||
return list
|
||||
}
|
||||
|
||||
// BookChapterByMID GET /api/book/chapter/by-mid/:mid 按自增主键 mid 查询(新链接推荐)
|
||||
func BookChapterByMID(c *gin.Context) {
|
||||
midStr := c.Param("mid")
|
||||
@@ -618,6 +645,38 @@ func findChapterAndRespond(c *gin.Context, whereFn func(*gorm.DB) *gorm.DB) {
|
||||
"sectionTitle": ch.SectionTitle,
|
||||
"isFree": isFree,
|
||||
}
|
||||
// 文章详情内直接输出上一篇/下一篇,省去单独请求
|
||||
if list := getOrderedChapterList(); len(list) > 0 {
|
||||
idx := -1
|
||||
for i, item := range list {
|
||||
if item.ID == ch.ID {
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if idx >= 0 {
|
||||
toItem := func(c *model.Chapter) gin.H {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
t := c.SectionTitle
|
||||
if t == "" {
|
||||
t = c.ChapterTitle
|
||||
}
|
||||
return gin.H{"id": c.ID, "mid": c.MID, "title": t}
|
||||
}
|
||||
if idx > 0 {
|
||||
out["prev"] = toItem(&list[idx-1])
|
||||
} else {
|
||||
out["prev"] = nil
|
||||
}
|
||||
if idx < len(list)-1 {
|
||||
out["next"] = toItem(&list[idx+1])
|
||||
} else {
|
||||
out["next"] = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
if isFreeFromConfig {
|
||||
out["price"] = float64(0)
|
||||
} else if ch.Price != nil {
|
||||
|
||||
Reference in New Issue
Block a user