加强了多个组件的预览百分比处理。

在 API 中新增了章节专属的预览百分比,并更新了相关模型和处理器。
改进了阅读场景下确定有效预览百分比的逻辑。
更新了小程序配置,加入了新的阅读页面入口。
This commit is contained in:
Alex-larget
2026-03-25 17:21:55 +08:00
parent d8362bc7a9
commit ae7402fafa
9 changed files with 233 additions and 82 deletions

View File

@@ -58,14 +58,14 @@ func sortChaptersByNaturalID(list []model.Chapter) {
var allChaptersSelectCols = []string{
"mid", "id", "part_id", "part_title", "chapter_id", "chapter_title",
"section_title", "word_count", "is_free", "price", "sort_order", "status",
"is_new", "edition_standard", "edition_premium", "hot_score", "created_at", "updated_at",
"is_new", "edition_standard", "edition_premium", "hot_score", "preview_percent", "created_at", "updated_at",
}
// chapterMetaCols 章节详情元数据(不含 content用于 content 缓存命中时的轻量查询
var chapterMetaCols = []string{
"mid", "id", "part_id", "part_title", "chapter_id", "chapter_title",
"section_title", "word_count", "is_free", "price", "sort_order", "status",
"is_new", "edition_standard", "edition_premium", "hot_score", "created_at", "updated_at",
"is_new", "edition_standard", "edition_premium", "hot_score", "preview_percent", "created_at", "updated_at",
}
// allChaptersCache 内存缓存,减轻 DB 压力30 秒 TTL
@@ -643,6 +643,17 @@ func getUnpaidPreviewPercent(db *gorm.DB) int {
return 20
}
// effectivePreviewPercent 章节 preview_percent 优先1~100否则用全局 unpaid_preview_percent
func effectivePreviewPercent(db *gorm.DB, ch *model.Chapter) int {
if ch != nil && ch.PreviewPercent != nil {
p := *ch.PreviewPercent
if p >= 1 && p <= 100 {
return p
}
}
return getUnpaidPreviewPercent(db)
}
// previewContent 取内容的前 percent%(不少于 100 字,上限 500 字),并追加省略提示
func previewContent(content string, percent int) string {
total := utf8.RuneCountInString(content)
@@ -712,12 +723,13 @@ func findChapterAndRespond(c *gin.Context, whereFn func(*gorm.DB) *gorm.DB) {
isPremium := ch.EditionPremium != nil && *ch.EditionPremium
hasFullAccess := isFree || checkUserChapterAccess(db, userID, ch.ID, isPremium)
var returnContent string
var unpaidPreviewPercent int // 未解锁时试读比例system_config.unpaid_preview_percent);已解锁时不写入响应
// 未解锁:正文截取用「章节覆盖 全局」;响应里顶层 previewPercent 仅表示全局默认data.previewPercent 表示章节私有model omitempty
var effectiveUnpaidPreviewPercent int
if hasFullAccess {
returnContent = ch.Content
} else {
unpaidPreviewPercent = getUnpaidPreviewPercent(db)
returnContent = previewContent(ch.Content, unpaidPreviewPercent)
effectiveUnpaidPreviewPercent = effectivePreviewPercent(db, &ch)
returnContent = previewContent(ch.Content, effectiveUnpaidPreviewPercent)
}
// data 中的 content 必须与外层 content 一致,避免泄露完整内容给未授权用户
@@ -740,7 +752,7 @@ func findChapterAndRespond(c *gin.Context, whereFn func(*gorm.DB) *gorm.DB) {
"hasFullAccess": hasFullAccess,
}
if !hasFullAccess {
out["previewPercent"] = unpaidPreviewPercent
out["previewPercent"] = getUnpaidPreviewPercent(db)
}
// 文章详情内直接输出上一篇/下一篇,省去单独请求
if list := getOrderedChapterList(); len(list) > 0 {