feat: PDF 页签从 iframe 改为构建期组件挂载,清理 iframe 配置与文档

前后端分离:UI/交互在 zPDF_package,能力由 zTools2 的 /api/pdf/* REST API 提供。
组件经同源 fetch 调用,httpOnly cookie(zk_pdf)经反代第一方自动携带,无需 CORS。
与 timeTableFix 集成范式完全一致。

- src/modules/pdf/Pdf.vue:iframe 包装器重写为组件挂载包装器,套 PageShell +
  透传 :locale;删除 pageSrc/getLiveness/scheduleFailCheck/openExternal 等 iframe 逻辑
- src/modules/pdf/index.js:注释从 iframe 改为构建期组件 import(requiresAlive 探针保留)
- src/config/app.config.js:移除 pdf.pagePath(iframe src),保留探针配置
- src/i18n/{zh-CN,en}.js:移除 pdf.openExternal(iframe 降级按钮文案,已无用)
- docs/submodule-zPDF_package.md:集成方式改为构建期组件 import,补 cookie 认证说明
- docs/deployment.md:拓扑去 /api/pdf 页面行,措辞改为组件 fetch
- third_party/zPDF_package:子模块指针升级到 4d12b61(去 iframe 表述)
This commit is contained in:
2026-07-27 17:14:07 +08:00
parent 304ebc9448
commit ae540a1a70
8 changed files with 50 additions and 142 deletions

View File

@@ -8,16 +8,15 @@ zPDF_package 功能涉及三个项目协同:**zMainPage**父站Vue3 静
浏览器 -> Apache(:80)
├── 静态文件 /var/www/html zMainPage 构建产物:主页 + 页签)
└── 反代 /api/ -> zTools2(127.0.0.1:6867)
├── /api/pdf PDF 转换页面iframe 嵌入源)
├── /api/pdf/* PDF 转换 APIcookie 用户)
├── /api/pdf-admin PDF 管理页Basic Auth
├── /api/static/pdf* 前端静态资源
└── MySQL(3306) + uploads/
```
PDF 页签 = zMainPage 用 iframe 嵌入 zTools2 的 `/api/pdf` 页面**同源相对路径**cookie 第一方生效,与环境无关)。
PDF 页签 = zMainPage 构建期 import zPDF_package 的 `App.vue` 作为组件(非 iframe经同源 fetch 调用 zTools2 的 `/api/pdf/*` REST API**同源相对路径**cookie 第一方生效,与环境无关)。
> **路由约定**zTools2 所有入口(页面 / 静态 / 探针 / WS / API统一挂在 `/api/` 下,反代与 vite proxy 只需一条 `/api/` 规则。前端 iframe fetch 一律用同源相对路径(`/api/pdf`、`/api/health` 等),自动指向**当前环境**的 zTools2无需区分 dev/prod也不会误打到其它环境域名。详见 zTools2 README「路由约定」。
> **路由约定**zTools2 所有入口(页面 / 静态 / 探针 / WS / API统一挂在 `/api/` 下,反代与 vite proxy 只需一条 `/api/` 规则。前端(无论是 iframe 嵌入页还是组件 fetch API一律用同源相对路径(`/api/pdf/jobs`、`/api/health` 等),自动指向**当前环境**的 zTools2无需区分 dev/prod也不会误打到其它环境域名。详见 zTools2 README「路由约定」。
---
@@ -34,7 +33,9 @@ cd zTools2
# 或python -m uvicorn app.main:app --host 127.0.0.1 --port 6867
```
访问http://127.0.0.1:6867/api/pdfPDF 页、http://127.0.0.1:6867/docsAPI 文档)。
访问http://127.0.0.1:6867/api/pdf-adminPDF 管理、http://127.0.0.1:6867/docsAPI 文档)。
> 用户侧 PDF 页面由 zMainPage 的 zPDF_package 组件提供(构建期 importzTools2 仅提供 `/api/pdf/*` REST API 与 `/api/pdf-admin` 管理页。
### 2. zPDF_package 前端独立运行
@@ -57,7 +58,7 @@ npm install
npm run dev # http://localhost:5173
```
> 独立模式下 PDF 页签的 iframe 用同源相对路径 `/api/pdf`,经 vite proxy 转发到本地 zTools2127.0.0.1:6867。如需指向其它环境的 zTools2改 `src/config/app.config.js` 的 `pdf.baseUrl` 为该环境地址(含协议与域名)后重新 `npm run dev`,或设 `VITE_API_BASE` 环境变量。
> 独立模式下 PDF 页签的 zPDF_package 组件经同源相对路径 `/api/pdf/*` 调用 zTools2,经 vite proxy 转发到本地 zTools2127.0.0.1:6867。如需指向其它环境的 zTools2改 `src/config/app.config.js` 的 `pdf.baseUrl` 为该环境地址(含协议与域名)后重新 `npm run dev`,或设 `VITE_API_BASE` 环境变量。
---
@@ -77,7 +78,7 @@ cd zMainPage
3. 配置 Apache vhost`/etc/apache2/sites-available/zmainpage.conf`)反代 `/api/``127.0.0.1:6867`(含 WebSocket靠 proxy_wstunnel 透传 `/api/ws`
4. 重启 zTools2除非 `--no-restart`
部署后访问 http://localhost/ 即主页PDF 页签 iframe 同源加载 `/api/pdf`
部署后访问 http://localhost/ 即主页PDF 页签渲染 zPDF_package 组件并经同源 fetch 调用 `/api/pdf/*`
> 已有 HTTPS vhost 时:`deploy.sh` 不会覆盖(仅首次写入)。手动在现有 vhost 加 `ProxyPass /api/ http://127.0.0.1:6867/api/` 一条规则即可(需 `a2enmod proxy_wstunnel` 以支持 WebSocket

View File

@@ -4,11 +4,13 @@ zPDF_packagePDF 转换前端)作为 **git submodule** 被 mainPage 引入
## 集成方式
mainPage 侧的 `src/modules/pdf/Pdf.vue` **iframe** 嵌入 zTools2 托管的 `/pdf` 页面(`https://f.zikai.wang/pdf`,套 `PageShell` 统一容器与标题,并持有 KeepAlive 匹配名 `defineOptions({ name: 'pdf' })`
mainPage 侧的 `src/modules/pdf/Pdf.vue` 包装器 import 子模块的 `src/App.vue` 作为组件,套 `PageShell` 统一容器与标题,并持有 KeepAlive 匹配名 `defineOptions({ name: 'pdf' })`
- **iframe 同源嵌入**(非组件 importPDF 转换有后端依赖zTools2 的 `/api/pdf/*`iframe 嵌入使页面与 API 同源(均在 `f.zikai.wang`),用户 cookie`zk_pdf`)第一方自然生效,无需给 zTools2 加 CORS不受第三方 cookie 限制。与白板页签的嵌入方式一致
- 页签带 `requiresAlive: healthUrl('pdf')`zTools2 不可达时隐藏页签并卸载组件;直链进入则显示降级提示与「在新标签页打开」
- zPDF_package 源码作为 submodule 管理,其 `npm run build` 产物部署到 zTools2 托管。mainPage 构建不编译子模块iframe 集成,非构建期组件集成)
- 子模块 `App.vue` 保持纯净(不持 name、不依赖宿主可独立 `npm run build` / `npm test` / 部署
- **构建期集成(非 iframe**,共享 mainPage 的构建与 KeepAlive 缓存。前后端分离UI/交互在 zPDF_package能力由 zTools2 的 `/api/pdf/*` REST API 提供
- 子模块样式已隔离scoped + `zpdf-` 前缀类名),全局重置仅在独立 app 的 `main.js` 加载,不污染宿主
- 页签带 `requiresAlive: healthUrl('pdf')`zTools2 不可达时隐藏页签并卸载组件。
- **认证**:用户身份凭 httpOnly cookie`zk_pdf`samesite=lax标识。该 cookie 在首次 `POST /api/pdf/jobs`(上传)的响应里种下,与页面路由无关。组件经同源 fetch 调用 `/api/pdf/*`,反代使 `/api/` 与主页同源cookie 自动携带,无需 CORS。
## 克隆(含子模块)
@@ -36,7 +38,7 @@ npm run build # 重新构建 main
git push # 推送 mainPagegitlink
```
> 推送顺序:先确保子模块的 commit 已推到 zPDF_package.git再推 mainPage 的 gitlink。
> 推送顺序:先确保子模块的 commit 已推到 zPDF_package.git再推 mainPage 的 gitlink,否则别人 clone mainPage 时拉不到子模块对应 commit
## 移除子模块集成(仅移除 mainPage 页签,不影响 zPDF_package 本身)
@@ -53,10 +55,10 @@ git commit -m "chore: 移除 zPDF_package 子模块集成"
| 维度 | timeTableFix / z449 | zPDF_package |
|------|---------------------|--------------|
| 集成方式 | 构建期组件 import共享构建/KeepAlive | iframe 嵌入 zTools2 托管页 |
| 集成方式 | 构建期组件 import共享构建/KeepAlive | 构建期组件 import共享构建/KeepAlive |
| 后端依赖 | 无(纯前端) | 有zTools2 `/api/pdf/*` |
| 同源/CORS | 不涉及 | 同源f.zikai.wang,无需 CORS |
| cookie | 不涉及 | 第一方 httpOnly cookie 自然生效 |
| mainPage 是否编译子模块 | 是import .vue | iframe |
| 同源/CORS | 不涉及 | 同源经反代,无需 CORS |
| cookie | 不涉及 | httpOnly `zk_pdf`,同源自动携带(首次上传种下) |
| mainPage 是否编译子模块 | 是import .vue | import .vue |
> zPDF_package 仍作为 submodule 管理源码,便于独立开发/测试/升级;其构建产物部署到 zTools2mainPage 经 iframe 引用 zTools2 的 `/pdf`
> 三个子项目timeTableFix / z449 / zPDF_package均采用构建期组件 import 集成,无 iframe。zPDF_package 额外依赖 zTools2 后端 API页签带存活探针