Skip to content

好学探索 · 技术架构设计 ​

配套:docs/策划文档.md(内部档案)


1. 总体架构 ​

┌─────────────────────────────────────────────────────────────┐
│  Client(Web PWA / 后续 Capacitor App)                       │
│  iOS27 Liquid Glass UI · 竖滑 Feed · 随手拍 · 片库管理         │
└───────────────────────────┬─────────────────────────────────┘
                            │ HTTPS / LAN HTTP
                            │ Cookie + Bearer Session
┌───────────────────────────▼─────────────────────────────────┐
│  Docker Compose                                             │
│  ┌──────────────┐  ┌─────────────┐  ┌────────────────────┐  │
│  │  api         │  │  worker     │  │  db (sqlite/pg)    │  │
│  │  Node 22     │─▶│  扫描/刮削   │─▶│  元数据·互动·任务   │  │
│  │  Express API │  │  缩略图     │  └────────────────────┘  │
│  └──────┬───────┘  └──────┬──────┘                          │
│         │                 │                                   │
│         ▼                 ▼                                   │
│  /media/*  bind mounts(NAS/本地)  /data(配置·上传·缓存)    │
└─────────────────────────────────────────────────────────────┘
          │ 在线认证/刮削
          ▼
   好学 PT · 寸光集 · 豆瓣 · TMDB

原则

  1. 厚后端:鉴权、扫描、刮削、权限、路径安全都在服务端
  2. 媒体直出:视频文件走 Range 流式,不经无谓转码(MVP)
  3. 账号外置:不自建用户密码库,复用好学/寸光集(与 jiapu 一致)
  4. 可插拔源:Storage Adapter + Scraper Provider 接口化

2. 目录结构 ​

HX-Tanqu/
├── docker-compose.yml
├── .env.example
├── README.md
├── docs/
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
│       ├── index.js              # 入口
│       ├── config.js
│       ├── db/                   # schema + repo
│       ├── auth/                 # jiapu 同构登录链
│       ├── routes/               # HTTP 路由
│       ├── services/             # feed/library/social
│       ├── storage/              # local/webdav adapters
│       └── scrapers/             # douban/tmdb/pt/ptang
├── frontend/
│   ├── index.html
│   ├── public/
│   └── src/
│       ├── main.js
│       ├── styles/ios27.css
│       ├── auth/
│       ├── api/
│       ├── components/
│       └── views/
├── data/                         # 运行时数据(volume)
└── scripts/

3. 认证架构(对齐 D:\jiapu) ​

3.1 登录链 ​

输入 login + password (+ twoStepCode?)
        │
        ▼
  含 @ ? ──是──▶ [寸光集在线 → 寸光集本地 → 好学本地]
        │否
        ▼
  是 admin 类?─是─▶ [寸光集本地/admin]
        │否
        ▼
  [好学在线 → 好学本地 → 寸光集本地]

3.2 好学在线(hxpt) ​

  1. GET/访问 login.php 建 Cookie 会话
  2. POST /api/challenge → { secret, challenge }
  3. clientHash = sha256(password)
  4. serverSideHash = sha256(secret + clientHash)
  5. response = hmac_sha256(challenge, serverSideHash)
  6. POST takelogin.php form:username/response/two_step_code
  7. 302 到首页即成功

3.3 寸光集在线(ptang) ​

  • POST https://ptang.top/api/auth/login JSON { email, password }
  • 成功返回 user 对象

3.4 会话 ​

  • SESSION_SECRET 签名 JWT-like:base64url(payload).base64url(hmac)
  • Cookie 名:tanqu_session;同时支持 Authorization: Bearer
  • 对外用户:{ id, username, email, source, sourceLabel, avatar? }
  • id 前缀:hxpt: / ptang:

4. 数据模型(核心表) ​

users_cache ​

登录成功后的资料缓存(非密码)

media_sources ​

  • id, name, type(local|webdav|pt|ptang), root_path/url, config_json, enabled

media_items ​

  • id, source_id, path, rel_path, title, sort_title
  • duration, width, height, size, mtime
  • poster_path, fingerprint
  • category_ids_json, series_id, episode_no
  • meta_json, scraped_at, created_at

categories ​

  • id, user_id(nullable 全局), name, icon, sort, visible, folder_bind

interactions ​

  • user_id, media_id, liked, collected, progress_sec, updated_at

comments ​

  • id, user_id, media_id, parent_id, body, created_at

scrape_jobs ​

  • id, target_type(item|folder), target_id, providers[], status, result_json

captures ​

  • id, user_id, media_id, local_path, created_at

默认 SQLite(/data/tanqu.db),可通过 DATABASE_URL 切 PostgreSQL。


5. 模块设计 ​

5.1 Storage Adapter ​

js
interface StorageAdapter {
  list(dir): Promise<Entry[]>
  stat(path): Promise<Stat>
  openReadStream(path, { start, end }): Readable
  exists(path): Promise<boolean>
}
  • LocalAdapter:读 bind mount,严格 root jail
  • WebdavAdapter:v0.2

5.2 Library Scanner ​

  • 队列化目录遍历
  • 指纹:size + mtime + rel_path(可升级 hash 抽样)
  • 产出/更新 media_items,删除丢失文件(软删)

5.3 Stream Service ​

  • GET /api/media/:id/stream 支持 HTTP Range
  • 校验登录 + 分类可见性 + 路径仍在 jail 内
  • MIME 探测,缓存缩略图 GET /api/media/:id/poster

5.4 Feed Service ​

  • 输入:user, tab, cursor, limit
  • 过滤:visible categories、用户屏蔽
  • 排序:精选分 = 新入库权重 + 未看完 + 点赞偏好
  • 返回卡片 DTO(播放地址、互动态、元数据)

5.5 Scraper Providers ​

js
interface ScraperProvider {
  id: 'douban' | 'tmdb' | 'pt' | 'ptang'
  search(query, type): Promise<Candidate[]>
  detail(externalId): Promise<Metadata>
}
  • 统一归一化:title/original_title/year/overview/poster/actors/genres/rating/episodes

5.6 Social Service ​

  • like toggle / collect toggle / comment CRUD / history upsert
  • 全部 user 维度隔离

6. Docker 部署拓扑 ​

yaml
services:
  api:      # 提供静态前端 + REST + 视频流
  worker:   # 扫描与刮削(可与 api 同进程 MVP)
  # db:     # 可选 postgres

卷:

  • tanqu-data:/data 配置、数据库、上传、海报缓存
  • ${NAS_MOVIES}:/media/movies:ro
  • ${NAS_SHORTS}:/media/shorts:ro

环境变量见 .env.example。


7. 安全设计 ​

  1. 路径穿越:所有文件访问 path.resolve 后必须仍以 root 为前缀
  2. 登录限流:15 分钟窗口失败次数(同 jiapu)
  3. CORS:可配置白名单;App 跨域 credentials
  4. 上传限制:随手拍大小/时长上限
  5. 密钥:TANQU_AUTH_SECRET 至少 32 字符
  6. 刮削密钥:TMDB API Key 仅存服务端

8. 性能策略 ​

点策略
列表游标分页,避免深 offset
海报本地缓存 + 长缓存头
视频直链 Range;可选 nginx 加速后续
扫描worker 单飞锁,防并发双扫
SQLiteWAL;重负载可迁 PG

9. 与 jiapu 的复用边界 ​

复用不复用
登录链、CookieJar、session 签名思想家谱业务/WASM 布局
Docker 一键部署体验云谱同步协议
前端 session.js 模式家谱 UI

10. 技术选型 ​

层选型原因
运行时Node.js 22与 jiapu 认证代码同构易迁
HTTPExpress清晰中间件、Range 友好
DBbetter-sqlite3 / sql.js 可切换私有化零运维
前端原生 ES Module + CSS轻、可控液态玻璃细节
容器Docker Compose用户要求与落地简单
后续 AppCapacitor与 jiapu 一致可复用经验

11. 多端客户端架构 ​

frontend/ (共享 UI)
    ├── web 静态资源 ──▶ Docker api 托管
    ├── desktop/Electron 加载 dist 或远程 api
    ├── mobile Capacitor (android/ios)
    └── harmony ArkWeb 加载 dist 或远程 api
  • 业务 UI 禁止在五端分叉复制;差异收敛到 platform 桥
  • 电脑端负责窗口/快捷键/协议关联
  • 移动端/鸿蒙/iOS 负责相机、安全存储、状态栏、返回手势
  • 详细矩阵与发版节奏见 docs/多端方案.md(内部档案)

目录增量:

desktop/                 # Electron
mobile/android|ios       # Capacitor
harmony/                 # DevEco 工程