Skip to content

Notion Files Management v2.0.0-Beta-0 重构首发

时间:2026-06-28 Tag 归档v1.5.2-legacy-wpf 指向重构前的最后一个 C# 提交(c46c08d)。

移除

  • 全部 C# / WPF 桌面代码:
    • .cs / .xaml / .csproj / .sln / .csproj.user
    • Models/ Services/ Utils/ Views/ .vs/
    • PUBLIST-*.bat
    • AppConfig.cs AppVersion.cs AssemblyInfo.cs
    • MainWindow.xaml(.cs) App.xaml(.cs)
  • Scripts/ 目录(已平移到 backend/scripts/
  • screenshot/(WPF 截图)

新增

后端 (backend/)

  • app/main.py —— FastAPI 入口,SessionMiddleware、路由聚合、缓存清理线程、前端静态托管、SPA fallback
  • app/config.py —— Config 类:env + config.json 合并
  • app/deps.py —— require_auth 依赖
  • app/taskregistry.py —— 任务注册表 + SSE 推送(核心)
  • app/staging.py —— 暂存目录 / zip 打包 / TTL 清理 / 日志列表
  • app/notion_facade.py —— Notion 业务 facade(替代原 C# 的 Main 类,按任务隔离)
  • app/app_version.py —— BASE_VERSION = "2.0.0",按当前渠道派生 2.0.0-Beta;文档修订号 N 仅用于 CHANGELOG/docs 的章节区分,代码 APP_VERSION 不带 N
  • app/routers/auth.py —— 登录/登出/检查
  • app/routers/settings.py —— 配置读写
  • app/routers/version.py —— 代理远程 version.json(公开)
  • app/routers/notices.py —— 公告列表/详情(已读管理 + 本地缓存)
  • app/routers/scan.py —— 启动扫描 + 拉取文件列表
  • app/routers/download.py —— 启动下载 + 单文件/zip 流式取回
  • app/routers/upload.py —— 收文件 + 启动上传(文件/文件夹)
  • app/routers/tools.py —— 4 个 Notion 工具(页面大小、迁移、去后缀、属性查询)
  • app/routers/tasks.py —— 任务列表 / SSE 事件流 / 取消
  • app/routers/system.py —— 日志/清缓存/重启
  • scripts/scan.py —— 新的 ScanSession(从 main.py 流式扫描逻辑提取,每任务独立)
  • scripts/{notion,download,upload,migrate,batch_rename,page_size_update,logger}.py —— 从原 Scripts/ 几乎未改地平移
  • tests/__init__.py tests/test_smoke.py —— pytest 冒烟测试

前端 (frontend/)

  • package.json + vite.config.ts + tsconfig.json + index.html
  • src/main.ts —— createApp、Pinia、Router、Element Plus(暗色 + zh-cn)、全局注册 icons
  • src/App.vue —— 根路由 + 全局主题色注入
  • src/router.ts —— 路由表 + 鉴权守卫
  • src/api/client.ts —— axios 实例 + 401 自动跳转登录
  • src/stores/auth.ts —— 鉴权状态
  • src/stores/config.ts —— 配置状态
  • src/composables/useTask.ts —— SSE 订阅 composablereactive state 模式)
  • src/utils/pageId.ts —— NotionPageId TS 移植
  • src/utils/format.ts —— 大小/时间格式化
  • src/assets/main.css —— 全局暗色样式
  • src/layouts/MainLayout.vue —— 侧栏 + 顶栏 + router-view
  • src/views/Login.vue —— 登录页
  • src/views/Dashboard.vue —— 主页
  • src/views/Notice.vue —— 公告(markdown-it 渲染)
  • src/views/Upload.vue —— 上传(文件/文件夹)
  • src/views/Download.vue —— 下载(流式扫描→勾选→下载)
  • src/views/Tools.vue —— 4 工具(4 个 tab)
  • src/views/Settings.vue —— 设置

部署

  • docker/Dockerfile —— 多阶段:node 构建前端 → python:3.11-slim 运行
  • docker/docker-compose.yml —— 单容器 + volume
  • deploy/nfm.spec —— PyInstaller 打包规范
  • deploy/run.py —— PyInstaller 入口
  • deploy/systemd/nfm.service —— systemd unit(venv+uvicorn)

文档

  • README.md —— 完全重写为 Web 版(Docker / 独立部署 / 功能表)
  • AI/README.md + AI/OVERVIEW.md + AI/ARCHITECTURE.md + AI/COMMANDS.md + AI/GOTCHAS.md + AI/CHANGELOG.md —— 新增的 AI 交接文档系统

关键设计决策

  1. 每任务一个 Download 实例:原 C# 的 Main.downloader 全局状态会导致多用户冲突。Facade 每次 start_downloadnew Download
  2. 每任务一个 Upload 实例:同理,文件路径按 file_path 隔离。
  3. ScanSession 独立实例:流式扫描的 _scan_status / download_list / _stream_probe_queue 是状态,跨任务会污染。
  4. SSE 终态事件统一为 done:避免与 EventSource 原生 error 事件冲突。
  5. useTask 返回 reactive state:避免 vue 模板中嵌套 ref 不自动解包的坑。
  6. 同步 facade 方法直接调用:fastapi 路由 async 调 sync facade,省去 anyio.to_thread 开销(start_* 都不阻塞)。

验证

  • ✅ 后端 py_compile 通过
  • ✅ 后端 app 加载 34 个路由
  • ✅ pytest 冒烟 4/4 通过
  • ✅ 前端 vue-tsc 零错误
  • ✅ 前端 vite build 成功
  • ✅ 集成:vite (5173) → uvicorn (18765) 全链路
  • ✅ 鉴权:未登录 401 / 错密码 401 / 正密码 200 / cookie 携带
  • ✅ 公开端点(/api/version)无需鉴权

已知限制

  • 后端默认端口已统一为 :18765vite.config.ts、Docker/systemd/Windows 入口需保持一致。
  • 全局 Notion 速率限制器(ratelimit.py)未实现。
  • 后端没有 pageId normalize 工具(依赖前端 utils/pageId.ts)。
  • 断点续传未实现。
  • PyInstaller / systemd 文档已写但未在干净环境实际部署验证。

渠道机制(Status / Beta)

时间:2026-06-28 背景:原 C# 版本区分 Status(正式版)和 Beta(预发布)两个渠道,重构时未保留。补上。

设计

  • 语义Status = 正式版,Beta = 预发布。channel 字段在 config.json 中,启动时通过 NFM_CHANNEL 环境变量覆盖。
  • 默认值Beta
  • API 隔离Statusnfm.ruibin-ningh.top/*Betabeta.nfm.ruibin-ningh.top/*不同渠道的版本更新/公告走不同 endpoint,避免 Beta 用户被 Status 强升,也避免 Status 用户收到 Beta 内容。
  • Web 不可改:Settings 页不暴露 channel 字段(防止误改),仅展示当前渠道。

变更

  • backend/app/app_version.py —— 新增 VALID_CHANNELS / DEFAULT_CHANNEL / current_channel()
  • backend/app/config.py —— channel 加入 _DEFAULTSload()NFM_CHANNEL env 覆盖;_bootstrap 首次启动写入 channel;新增 Config.channel 属性
  • backend/app/routers/version.py —— 按 channel 选择 endpoint;新增 GET /api/version/channel 公开端点返回当前渠道
  • backend/app/routers/notices.py —— 按 channel 选择公告 endpoint
  • backend/app/routers/settings.py —— SettingsIn 显式排除 channel(仅 env 改)
  • frontend/src/views/Settings.vue —— 当前版本后展示渠道徽章(正式版/预发布 Beta)
  • frontend/src/layouts/MainLayout.vue —— 顶栏新增渠道徽章

启动方式

bash
# Status(正式版,默认)
NFM_CHANNEL=Status uvicorn app.main:app --app-dir backend

# Beta(预发布)
NFM_CHANNEL=Beta uvicorn app.main:app --app-dir backend

验证

$ curl -s http://127.0.0.1:18765/api/version/channel
{"channel":"Status","valid":["Status","Beta"]}

$ NFM_CHANNEL=Beta ... curl -s .../api/version/channel
{"channel":"Beta","valid":["Status","Beta"]}

$ curl -s -b cookie .../api/settings
{...,"channel":"Status"}

✓ 前端 vue-tsc 零错误
✓ vite (5173) → uvicorn (18765) 全链路,channel 字段经 vite proxy 透传

Released under the MIT License.