✨ feat(bookSource): 聚合书源适配阅读 app 并完善评论体验

- 聚合书源取代早期书源版本:发现页筛选宫格/分类宫格、x:t:m:d: 前缀搜索、
  fqtab 类型随书切换、段评气泡(内置六种样式可配);showCmt 能力检测,魔改版
  原地弹窗(点遮罩关闭)、官方阅读降级 startBrowser;jsLib 不引用规则变量,
  searchUrl 修正编码与作用域
- 评论页:注入绝对 API_BASE,修复弹窗 WebView 内切换排序/懒加载失败;
  externalBaseURL 识别 X-Forwarded-Proto,气泡 ident 不再硬编码 http;
  顶栏固定(拖拽把手)+评论区独立滚动
- 部署:证书方案从 certbot 迁移到 acme.sh(CERT_DIR 可配置);新增服务生命
  周期参数 --stop/--start/--no-restart/--no-autostart;--clean 一键清理全部
  部署内容(服务/nginx/二进制/证书,含 certbot 残留),acme.sh 定位抽为
  find_acme_sh 供 init/clean 共用
- 忽略 .codegraph 本地索引目录
This commit is contained in:
chenxin committed 2026-10-10 13:21:37 +08:00
1 parent 49d0a371fb
commit c3ddf659b0
7 files changed
+342 -76

No files matched your search

+14 -2
View File
@@ -12,6 +12,16 @@ import (
"time"
)
// externalBaseURL 取外部可访问的基础 URL(nginx 反代下识别 X-Forwarded-Proto,
// 避免生成 http:// 链接被 301,弹窗 WebView 内 fetch 对 301 处理不稳)
func externalBaseURL(r *http.Request) string {
scheme := "http"
if p := r.Header.Get("X-Forwarded-Proto"); p != "" {
scheme = p
}
return scheme + "://" + r.Host
}
// validateParams 验证必需参数
func validateParams(r *http.Request, required ...string) (map[string]string, error) {
params := make(map[string]string)
@@ -207,7 +217,7 @@ func HandleReviewHTML(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusOK)
html := generateReviewHTML(data, params["item_id"], bookID, para, page, pageSize, sort)
html := generateReviewHTML(r, data, params["item_id"], bookID, para, page, pageSize, sort)
fmt.Fprint(w, html)
}
@@ -318,6 +328,7 @@ var reviewTmpl = template.Must(template.New("review").Parse(reviewHTML))
// reviewPageData 评论页模板数据
type reviewPageData struct {
ItemID, BookID string
BaseURL string
ParaPlus1, Para, Sort int
Total, NextOffset int
PageSize, CommentCount int
@@ -327,7 +338,7 @@ type reviewPageData struct {
}
// generateReviewHTML 生成评论 HTML 页面
func generateReviewHTML(data map[string]interface{}, itemID, bookID string, para, page, pageSize, sort int) string {
func generateReviewHTML(r *http.Request, data map[string]interface{}, itemID, bookID string, para, page, pageSize, sort int) string {
total := 0
hasMore := false
nextOffset := 0
@@ -383,6 +394,7 @@ func generateReviewHTML(data map[string]interface{}, itemID, bookID string, para
var b strings.Builder
if err := reviewTmpl.Execute(&b, reviewPageData{
ItemID: itemID, BookID: bookID,
BaseURL: externalBaseURL(r),
ParaPlus1: para + 1, Para: para, Sort: sort,
Total: total, NextOffset: nextOffset,
PageSize: pageSize, CommentCount: len(pageComments),