901 lines
32 KiB
Markdown
901 lines
32 KiB
Markdown
# PPT 文档导入与呈现服务 — 规划设计及实施方案
|
||
|
||
## 一、概述
|
||
|
||
### 1.1 背景与痛点
|
||
|
||
PPT(PowerPoint / Keynote / WPS 演示文稿)是企业内外部演讲、培训、方案汇报的核心文档格式。然而在大屏呈现场景中,PPT 面临以下突出痛点:
|
||
|
||
| 痛点 | 说明 |
|
||
|------|------|
|
||
| **终端碎片化** | 大屏涵盖智能电视机(Android)、机顶盒(Android)、Windows 各版本、鸿蒙 TV 等,PPT 在不同平台渲染效果差异显著 |
|
||
| **字体与排版漂移** | 缺少字体导致替代渲染,页面布局错位,精心排版的效果无法还原 |
|
||
| **演讲者被迫自带 PC** | 为保证呈现一致性,演讲者常常只能连接自己的笔记本电脑,增加准备成本和安全风险 |
|
||
| **互动能力缺失** | 原生 PPT 演示模式缺乏观众互动(投票、提问、弹幕、反馈)能力 |
|
||
| **协作效率低** | PPT 通过网盘或邮件传递,缺乏版本管理、多人协作、权限控制 |
|
||
|
||
### 1.2 目标
|
||
|
||
基于 [ICT 服务平台](ICT服务平台概要.md) 的统一认证底座(OpenLDAP + Keycloak)和 Git 基础设施(Gitea),构建 **PPT 文档导入与呈现服务平台**,实现:
|
||
|
||
- 在云端将 PPT 转化为 Web 页面,终端以**浏览器**为统一呈现载体
|
||
- 覆盖全部泛化终端(Android TV、Android STB、Windows、鸿蒙 TV、iPad 等)
|
||
- 互动信息(评论、投票、提问、弹幕)与 PPT-Web 每页画面精确绑定
|
||
- 基于 Git 管理个人文档与工作组文档,支持多组合协作关系
|
||
- 用户界面保持文件目录树方式,符合日常使用习惯
|
||
|
||
### 1.3 核心设计原则
|
||
|
||
- **浏览器即终端**:PPT 转 Web 后,任何支持现代浏览器的设备均可精确呈现,从根本上消除终端差异
|
||
- **Git 为唯一真实源**:PPT 原文件及转换产物均存储于 Git 仓库,版本可追溯
|
||
- **开源优先,商业增强**:核心链路采用开源方案,高保真转换环节引入商业方案保障效果
|
||
- **认证复用**:全部接入 ICT 平台 Keycloak SSO
|
||
- **自动化驱动**:Git 推送即触发 PPT 转换、发布、同步,零人工干预
|
||
|
||
### 1.4 用户角色
|
||
|
||
| 角色 | 说明 | 典型场景 |
|
||
|------|------|---------|
|
||
| 演讲者 (Presenter) | PPT 上传者与现场演讲控制者 | 上传 PPT 到 Git,远程/现场控制翻页 |
|
||
| 观众 (Audience) | 通过大屏或个人设备观看演示的人员 | 浏览器观看 PPT-Web、扫码参与互动 |
|
||
| 协作者 (Collaborator) | 参与 PPT 文档协同编辑与版本管理的成员 | 通过 Git 分支协作修改 PPT 资料 |
|
||
| 管理员 (Admin) | 管理文档空间、权限、转换策略的 IT 人员 | 配置仓库权限与转换规则 |
|
||
|
||
---
|
||
|
||
## 二、系统架构
|
||
|
||
### 2.1 整体架构图
|
||
|
||
```plantuml
|
||
@startuml
|
||
skinparam componentStyle rectangle
|
||
skinparam nodesep 30
|
||
skinparam ranksep 40
|
||
title PPT 文档导入与呈现服务 - 系统架构
|
||
|
||
' ===== 用户层 =====
|
||
actor "演讲者" as Presenter
|
||
actor "观众" as Audience
|
||
|
||
' ===== 终端层 =====
|
||
node "演讲者终端" as PClient {
|
||
component "VS Code + Qoder" as IDE
|
||
}
|
||
|
||
node "泛化终端 (浏览器统一呈现)" as AClient {
|
||
component "Android TV / STB" as TV
|
||
component "Windows / Mac" as WinMac
|
||
component "鸿蒙 TV / iPad" as HM
|
||
}
|
||
|
||
' ===== 应用服务层 =====
|
||
node "互联网应用服务器" as AppServer {
|
||
component "Nginx + SSL" as Nginx
|
||
component "Keycloak SSO" as KC
|
||
|
||
package "文档管理" {
|
||
component "Gitea" as Gitea
|
||
component "MeiliSearch" as Search
|
||
}
|
||
|
||
package "PPT 转换引擎" {
|
||
component "SlideForge" as SF
|
||
component "ONLYOFFICE" as OO
|
||
component "LibreOffice" as LO
|
||
}
|
||
|
||
package "演示与互动" {
|
||
component "SlidePortal" as Portal
|
||
component "InteractHub" as Interact
|
||
}
|
||
}
|
||
|
||
' ===== 数据层 =====
|
||
node "私有云 [数据后端]" as PCloud {
|
||
database "PostgreSQL" as DB
|
||
database "OpenLDAP" as LDAP
|
||
storage "Git 仓库存储" as Store
|
||
}
|
||
|
||
' == 演讲者流 ==
|
||
Presenter -down-> IDE : 上传 PPT
|
||
IDE -down-> Gitea : git push (SSH)
|
||
|
||
' == 观众流 ==
|
||
Audience -down-> AClient
|
||
AClient -down-> Nginx : HTTPS
|
||
|
||
' == 接入与认证 ==
|
||
Nginx -down-> KC : 认证校验
|
||
Nginx -down-> Portal : 演示页面
|
||
|
||
' == 转换链 ==
|
||
Gitea -right-> SF : Webhook 触发
|
||
SF -down-> OO : PPTX 转 HTML
|
||
SF -down-> LO : 旧格式转换
|
||
SF -right-> Portal : Web 幻灯片
|
||
|
||
' == 互动 ==
|
||
Portal -down-> Interact : 互动事件
|
||
|
||
' == 数据存储 ==
|
||
KC -down-> LDAP : 用户目录
|
||
Gitea -down-> Store : 仓库数据
|
||
SF -down-> DB : 转换元数据
|
||
Interact -down-> DB : 互动数据
|
||
@enduml
|
||
```
|
||
|
||
### 2.2 核心组件清单
|
||
|
||
| 组件 | 技术方案 | 用途 | 许可证 |
|
||
|------|---------|------|--------|
|
||
| PPT 转换调度 | **自研 SlideForge**(Node.js) | 接收 Webhook,调度转换引擎,管理转换产物 | — |
|
||
| 反馈引擎 | **FeedbackEngine**(SlideForge 子模块) | 互动数据聚合、反馈报告生成、修订闭环管理 | — |
|
||
| PPT 转 HTML(主引擎) | **ONLYOFFICE Document Server** | 高保真 PPTX 转 HTML | AGPL v3 |
|
||
| PPT 转 HTML(兼容引擎) | **LibreOffice Headless** | 旧格式(PPT/ODP)转换 | MPL 2.0 |
|
||
| PPT 转 HTML(高保真) | **Aspose.Slides Cloud** | 复杂动画与特殊排版的精确还原 | 商业授权 |
|
||
| Web 幻灯片框架 | **Reveal.js** | 浏览器端幻灯片呈现、翻页、全屏 | MIT |
|
||
| 实时互动 | **自研 InteractHub**(Socket.io) | 投票、提问、弹幕、遥控翻页 | — |
|
||
| 演示平台 | **自研 SlidePortal**(Next.js) | 文件管理 UI、演示控制台、观众端 | — |
|
||
| Git 仓库 | **Gitea**(已有) | PPT 文件存储与版本管理 | MIT |
|
||
| 全文检索 | **MeiliSearch**(已有) | PPT 标题、标签、内容搜索 | MIT |
|
||
| 认证中心 | **Keycloak**(已有) | OIDC SSO 统一登录 | Apache 2.0 |
|
||
| 反向代理 | **Nginx**(已有) | SSL 终止、路由分发、WebSocket 代理 | BSD |
|
||
|
||
---
|
||
|
||
## 三、PPT 转 Web 关键技术
|
||
|
||
### 3.1 技术路线概览
|
||
|
||
PPT 转 Web 是本系统的**核心技术环节**,直接决定终端呈现质量。业界存在以下主要技术路线:
|
||
|
||
```
|
||
PPT 原文件
|
||
│
|
||
├─ 路线 A:PPT → HTML(直接转换)
|
||
│ └─ ONLYOFFICE / Aspose.Slides / GroupDocs
|
||
│
|
||
├─ 路线 B:PPT → PDF → HTML(两步转换)
|
||
│ └─ LibreOffice → pdf2htmlEX
|
||
│
|
||
├─ 路线 C:PPT → SVG/PNG + JSON → Reveal.js(解构重建)
|
||
│ └─ Apache POI / python-pptx → 自定义渲染
|
||
│
|
||
└─ 路线 D:PPT → 在线编辑器实时渲染
|
||
└─ ONLYOFFICE Viewer / Microsoft Graph API
|
||
```
|
||
|
||
### 3.2 方案详细对比
|
||
|
||
| 维度 | ONLYOFFICE | LibreOffice | Aspose.Slides | pdf2htmlEX 管线 | POI + Reveal.js | MS Graph API |
|
||
|------|-----------|-------------|---------------|----------------|-----------------|--------------|
|
||
| **类型** | 开源 AGPL v3 | 开源 MPL 2.0 | 商业 | 开源 GPL v3 | 开源 Apache 2.0 | 云服务 |
|
||
| **转换质量** | ★★★★☆ | ★★★☆☆ | ★★★★★ | ★★★★☆ | ★★★☆☆ | ★★★★★ |
|
||
| **字体保真** | 优 | 中(依赖系统字体) | 优(字体嵌入) | 优(PDF 字体) | 差 | 优 |
|
||
| **动画支持** | CSS 动画还原 | 不支持 | CSS/JS 动画 | 不支持 | 需自定义 | 原生动画 |
|
||
| **母版/图表** | 完整支持 | 基本支持 | 完整支持 | 视觉保留 | 需自行解析 | 完整支持 |
|
||
| **自托管** | Docker 部署 | 原生/Docker | JAR/Docker | 原生/Docker | 纯代码 | 仅云端 |
|
||
| **旧格式 PPT** | 支持 | 良好 | 支持 | 间接 | 仅 PPTX | 支持 |
|
||
| **ODP/Keynote** | ODP 支持 | 良好 | 有限 | 间接 | 不支持 | 有限 |
|
||
| **并发性能** | 中(~5 并发/实例) | 中(进程隔离) | 高 | 中 | 高 | 高(弹性) |
|
||
| **年成本** | 免费(社区版) | 免费 | ~30K RMB/服务器 | 免费 | 免费 | ~20K RMB/年 |
|
||
| **集成难度** | 中 | 低(CLI) | 低(REST API) | 中 | 高 | 低(REST) |
|
||
|
||
### 3.3 推荐方案:三级混合转换引擎
|
||
|
||
采用**三级转换策略**,在效果与成本之间取得最优平衡:
|
||
|
||
```plantuml
|
||
@startuml
|
||
skinparam componentStyle rectangle
|
||
title PPT 转 Web 三级混合转换引擎
|
||
|
||
start
|
||
:SlideForge 接收 PPT 文件;
|
||
:解析文件格式与复杂度;
|
||
note right
|
||
检查项:
|
||
动画数量/SmartArt/图表
|
||
嵌入字体/媒体/母版复杂度
|
||
end note
|
||
|
||
if (PPTX 且复杂度 <= 阈值 ?) then (是)
|
||
:ONLYOFFICE 转换;
|
||
note right: 开源主引擎, 覆盖约 80%
|
||
else (否)
|
||
if (PPT/ODP/旧格式 ?) then (是)
|
||
:LibreOffice 转换;
|
||
note right: 旧格式兼容引擎
|
||
else (PPTX 高复杂度)
|
||
:Aspose.Slides 转换;
|
||
note right: 商业高保真引擎
|
||
endif
|
||
endif
|
||
|
||
:Reveal.js 封装后处理;
|
||
note right
|
||
注入翻页框架 + 互动 SDK
|
||
嵌入字体子集(WOFF2)
|
||
压缩图片(WebP) + 生成缩略图
|
||
end note
|
||
|
||
:存入 Git 仓库 + 注册 PostgreSQL;
|
||
stop
|
||
@enduml
|
||
```
|
||
|
||
#### 三级引擎定位
|
||
|
||
| 引擎 | 定位 | 覆盖场景 | 预计占比 |
|
||
|------|------|---------|---------|
|
||
| **ONLYOFFICE** | 主引擎 | 标准 PPTX,中低复杂度 | ~80% |
|
||
| **LibreOffice** | 兼容引擎 | PPT (旧格式)、ODP、Keynote 导出 | ~10% |
|
||
| **Aspose.Slides** | 高保真引擎 | 复杂动画、特殊排版、精确还原 | ~10% |
|
||
|
||
### 3.4 转换后处理:Reveal.js 封装
|
||
|
||
无论哪个引擎产出 HTML,SlideForge 均进行统一后处理,封装为 **Reveal.js** 格式:
|
||
|
||
```
|
||
转换引擎产出
|
||
│
|
||
├─ 每页幻灯片 → <section> 标签
|
||
├─ 注入 Reveal.js 框架(翻页/全屏/进度条/演讲者视图)
|
||
├─ 注入 InteractHub SDK(每页互动面板 + WebSocket)
|
||
├─ 字体子集嵌入(fonttools → WOFF2,仅保留使用字符)
|
||
└─ 图片优化(sharp → WebP 转换 + 响应式多尺寸)
|
||
```
|
||
|
||
### 3.5 转换质量保障
|
||
|
||
| 措施 | 说明 |
|
||
|------|------|
|
||
| **自动截图对比** | 转换后逐页截图,与 LibreOffice 渲染的参考 PDF 对比相似度(Puppeteer + pixelmatch) |
|
||
| **人工校验标记** | 演讲者在 SlidePortal 中逐页预览,可标记"需优化"触发高级引擎重试 |
|
||
| **引擎降级重试** | 转换失败或相似度低于阈值时,自动切换更高级引擎重试 |
|
||
| **字体白名单** | 维护常用中英文字体库,缺失字体自动提示上传或从字体库补充 |
|
||
|
||
---
|
||
|
||
## 四、Git 文档管理体系
|
||
|
||
### 4.1 仓库结构
|
||
|
||
PPT 文档管理复用 ICT 平台的 Gitea 基础设施,按组织层级划分仓库:
|
||
|
||
| 仓库类型 | 命名规范 | 说明 |
|
||
|---------|---------|------|
|
||
| **个人文档** | `slides-{username}` | 个人 PPT 资料,私有仓库 |
|
||
| **工作组文档** | `slides-{group}` | 部门/项目组共享,按组权限 |
|
||
| **公开演示** | `slides-public` | 对外发布的演示资料 |
|
||
| **模板库** | `slides-templates` | 企业 PPT 模板,全员可读 |
|
||
|
||
#### 仓库目录结构示例
|
||
|
||
```
|
||
slides-marketing/ # 市场部工作组仓库
|
||
├── 2026-Q1/
|
||
│ ├── 新品发布会.pptx
|
||
│ ├── 客户方案-ABC公司.pptx
|
||
│ └── 季度总结.pptx
|
||
├── templates/
|
||
│ ├── 标准汇报模板.pptx
|
||
│ └── 产品介绍模板.pptx
|
||
├── .slideforge.yml # 转换配置
|
||
└── README.md
|
||
```
|
||
|
||
### 4.2 Git 协作优势(对比网盘)
|
||
|
||
| 维度 | Git 仓库管理 | 网盘管理 |
|
||
|------|-------------|---------|
|
||
| **版本管理** | 完整 Git 历史,任意版本可回溯 | 无版本或仅有限快照 |
|
||
| **协作模式** | 分支 + 合并请求,多人并行不冲突 | 文件锁定或覆盖冲突 |
|
||
| **权限控制** | 按仓库/分支/路径细粒度控制 | 按文件夹粗粒度控制 |
|
||
| **自动化** | Webhook 触发转换/发布/通知 | 需人工操作 |
|
||
| **多组合协作** | Fork 后独立修改,跨组共享,MR 合并 | 复制粘贴,难以追踪来源 |
|
||
| **审计** | 每次变更有作者、时间、说明 | 无或有限审计 |
|
||
| **离线使用** | 本地完整仓库,离线可用 | 依赖网络 |
|
||
|
||
### 4.3 多组合协作关系
|
||
|
||
Git 的分支与 Fork 机制天然支持跨部门多组合协作:
|
||
|
||
```plantuml
|
||
@startuml
|
||
skinparam componentStyle rectangle
|
||
title Git 多组合协作模式
|
||
|
||
package "市场部仓库" as MKT {
|
||
component "main" as Main
|
||
component "feature/新品发布" as F1
|
||
}
|
||
|
||
package "研发部 Fork" as RD {
|
||
component "技术内容补充" as RDWork
|
||
}
|
||
|
||
package "设计部 Fork" as DS {
|
||
component "视觉优化" as DSWork
|
||
}
|
||
|
||
actor "市场部成员" as M
|
||
actor "研发部成员" as R
|
||
actor "设计部成员" as D
|
||
|
||
M -down-> F1 : 内容编写
|
||
R -down-> RDWork : 技术补充
|
||
D -down-> DSWork : 视觉优化
|
||
RDWork -right-> Main : Merge Request
|
||
DSWork -right-> Main : Merge Request
|
||
F1 -down-> Main : 分支合并
|
||
@enduml
|
||
```
|
||
|
||
---
|
||
|
||
## 五、终端泛化呈现
|
||
|
||
### 5.1 目标终端矩阵
|
||
|
||
| 终端类型 | 操作系统 | 浏览器内核 | 分辨率 | 输入方式 |
|
||
|---------|---------|-----------|--------|---------|
|
||
| 智能电视机 | Android TV | Chromium WebView | 1080p / 4K | 遥控器 |
|
||
| 大屏机顶盒 | Android | Chromium WebView | 1080p / 4K | 遥控器 |
|
||
| 鸿蒙 TV | HarmonyOS | ArkWeb (Chromium) | 1080p / 4K | 遥控器 |
|
||
| Windows PC | Windows 10/11 | Chrome / Edge | 多种 | 键鼠 / 翻页笔 |
|
||
| Mac | macOS | Safari / Chrome | 多种 | 键鼠 / 翻页笔 |
|
||
| iPad / 平板 | iPadOS / Android | Safari / Chrome | 多种 | 触屏 |
|
||
| 手机(控制端) | iOS / Android | Safari / Chrome | 多种 | 触屏 |
|
||
|
||
### 5.2 浏览器统一呈现架构
|
||
|
||
核心思路:**所有终端均通过浏览器访问 PPT-Web 页面,不安装任何原生 PPT 应用**。
|
||
|
||
```
|
||
云端 PPT → Reveal.js Web 幻灯片
|
||
│
|
||
├─ Android TV / STB → WebView 全屏打开
|
||
├─ 鸿蒙 TV → ArkWeb 全屏打开
|
||
├─ Windows / Mac → Chrome/Edge/Safari 全屏
|
||
├─ iPad / 平板 → Safari/Chrome 全屏
|
||
└─ 手机 → 浏览器打开(演讲者遥控端)
|
||
```
|
||
|
||
### 5.3 终端适配策略
|
||
|
||
| 维度 | 策略 |
|
||
|------|------|
|
||
| **分辨率** | Reveal.js `width/height` + CSS `scale` 自适应,幻灯片按原始比例等比缩放 |
|
||
| **字体** | 转换时嵌入字体子集(WOFF2),不依赖终端系统字体 |
|
||
| **遥控器** | 拦截遥控器方向键 → 映射为 Reveal.js 上/下/左/右翻页 |
|
||
| **触屏** | Reveal.js 原生支持滑动翻页 |
|
||
| **翻页笔** | USB 翻页笔发送 Page Up/Down,Reveal.js 原生支持 |
|
||
| **全屏** | Fullscreen API 自动进入全屏;遥控器返回键退出 |
|
||
| **弱网** | Service Worker 缓存全部资源,首次加载后离线可翻页 |
|
||
|
||
---
|
||
|
||
## 六、互动反馈系统
|
||
|
||
### 6.1 互动功能矩阵
|
||
|
||
互动信息与 PPT-Web **每页画面精确绑定**,每一页幻灯片可独立配置互动组件:
|
||
|
||
| 互动功能 | 说明 | 绑定粒度 |
|
||
|---------|------|---------|
|
||
| **实时投票** | 演讲者发起单选/多选投票,观众扫码参与 | 绑定到具体页 |
|
||
| **在线提问 (Q&A)** | 观众提交问题,可点赞,演讲者选择展示 | 绑定到具体页 |
|
||
| **弹幕** | 观众发送弹幕,叠加显示在幻灯片上方 | 绑定到具体页 |
|
||
| **实时反应** | 观众发送表情反应,悬浮动画展示 | 绑定到具体页 |
|
||
| **标注批注** | 审阅者对具体页面留下文字批注 | 绑定到具体页 |
|
||
| **演讲者注释** | 仅演讲者可见的备注与提示 | 绑定到具体页 |
|
||
| **远程遥控** | 演讲者通过手机控制翻页、激光笔 | 全局 |
|
||
|
||
### 6.2 互动技术架构
|
||
|
||
```plantuml
|
||
@startuml
|
||
skinparam componentStyle rectangle
|
||
skinparam nodesep 30
|
||
skinparam ranksep 40
|
||
title 互动反馈系统架构
|
||
|
||
node "演讲者手机" as Phone {
|
||
component "遥控端 (翻页/激光笔)" as Remote
|
||
}
|
||
|
||
node "观众手机" as APhone {
|
||
component "互动页面 (投票/提问/弹幕)" as APage
|
||
}
|
||
|
||
node "互联网应用服务器" as Server {
|
||
component "InteractHub" as Hub
|
||
component "Redis (在线状态缓存)" as Redis
|
||
}
|
||
|
||
node "大屏终端" as Screen {
|
||
component "Reveal.js 幻灯片 (同步翻页)" as Slides
|
||
component "互动叠加层 (实时推送)" as Overlay
|
||
}
|
||
|
||
database "PostgreSQL\n(持久化互动数据)" as DB
|
||
|
||
Remote -down-> Hub : WebSocket
|
||
APage -down-> Hub : WebSocket
|
||
Hub -down-> Slides : WebSocket
|
||
Hub -down-> Overlay : WebSocket
|
||
Hub -right-> Redis
|
||
Hub -right-> DB
|
||
@enduml
|
||
```
|
||
|
||
### 6.3 观众接入方式
|
||
|
||
观众通过扫描大屏二维码即时接入互动:
|
||
|
||
```
|
||
大屏当前页展示会话二维码
|
||
→ 观众手机扫码
|
||
→ 打开 https://slide.writech.cn/interact/{session_id}
|
||
→ WebSocket 建立连接
|
||
→ 实时参与当前页的投票/提问/弹幕
|
||
→ 翻页时互动面板自动切换到对应新页
|
||
```
|
||
|
||
### 6.4 互动数据与页面绑定模型
|
||
|
||
每条互动数据均绑定 `session_id + slide_index`,确保回放时可精确还原每页互动:
|
||
|
||
```
|
||
Session(演示会话)
|
||
├── slide_index: 0
|
||
│ ├── votes: [{question, options, results}]
|
||
│ ├── questions: [{user, content, upvotes}]
|
||
│ └── reactions: {count_by_type}
|
||
├── slide_index: 1
|
||
│ ├── danmaku: [{user, content, timestamp}]
|
||
│ └── annotations: [{user, position, content}]
|
||
└── slide_index: N
|
||
└── ...
|
||
```
|
||
|
||
---
|
||
|
||
## 七、演示反馈闭环
|
||
|
||
### 7.1 闭环流程概述
|
||
|
||
演示互动数据不仅服务于现场体验,更构成**从演示到修订的完整闭环**:每场演示结束后,系统自动聚合互动数据、生成结构化反馈报告,推送至 PPT 原始编辑者,驱动文档持续优化迭代。
|
||
|
||
```plantuml
|
||
@startuml
|
||
skinparam componentStyle rectangle
|
||
title PPT 编辑版本闭环流程
|
||
|
||
start
|
||
:编辑者创建/修改 PPT 并推送到 Git;
|
||
:SlideForge 自动转换为 Web 幻灯片;
|
||
:演讲者发起演示会话;
|
||
|
||
:观众互动环节;
|
||
note right
|
||
并行采集
|
||
----
|
||
观众提问
|
||
观众投票
|
||
弹幕 / 表情反应
|
||
审阅者批注
|
||
end note
|
||
|
||
:InteractHub 采集并持久化互动数据;
|
||
:演示会话结束;
|
||
:FeedbackEngine 聚合互动数据;
|
||
note right
|
||
按页聚合 - 每页独立统计
|
||
跨场次聚合 - 同一 PPT 多次演示
|
||
end note
|
||
|
||
:生成结构化反馈报告;
|
||
:反馈报告提交至 Git 仓库;
|
||
:MsgHub 通知原始编辑者;
|
||
:编辑者审阅反馈报告;
|
||
|
||
if (需要修订 ?) then (是)
|
||
:创建修订分支, 修改 PPT;
|
||
:推送新版本, 自动触发转换;
|
||
note right: 新版本 commit 引用反馈报告
|
||
else (否)
|
||
:标记已审阅, 无需修订;
|
||
endif
|
||
|
||
stop
|
||
@enduml
|
||
```
|
||
|
||
### 7.2 互动数据聚合
|
||
|
||
FeedbackEngine 在演示结束后从 PostgreSQL 提取互动数据,按两个维度进行聚合:
|
||
|
||
#### 逐页聚合
|
||
|
||
每页幻灯片独立生成反馈摘要:
|
||
|
||
| 数据维度 | 聚合内容 | 来源 |
|
||
|---------|---------|------|
|
||
| **提问** | 问题列表、点赞数排序、是否已回答 | Q&A 模块 |
|
||
| **投票** | 各选项得票率、参与人数 | 投票模块 |
|
||
| **弹幕关键词** | 高频词提取、情感倾向 | 弹幕模块 |
|
||
| **反应统计** | 各表情类型的分布 | 反应模块 |
|
||
| **批注** | 审阅者标注内容汇总 | 批注模块 |
|
||
| **停留时长** | 该页展示时长与全文均值的对比 | 翻页事件 |
|
||
|
||
#### 跨场次聚合
|
||
|
||
同一 PPT 可能被多次演示,FeedbackEngine 支持跨场次合并:
|
||
|
||
| 策略 | 说明 |
|
||
|------|------|
|
||
| **累计统计** | 所有场次的提问、投票、反应数据累加 |
|
||
| **趋势对比** | 对比不同场次同一页的反馈变化 |
|
||
| **最新优先** | 修订建议以最近一次演示的反馈为主 |
|
||
| **版本关联** | 每次聚合标注对应的 PPT commit hash |
|
||
|
||
### 7.3 反馈报告
|
||
|
||
FeedbackEngine 生成的报告以 **Markdown** 存入 Git 仓库,与 PPT 源文件同目录管理:
|
||
|
||
```
|
||
slides-marketing/
|
||
├── 新品发布会.pptx
|
||
├── 新品发布会.feedback/
|
||
│ ├── 2026-03-20_会议室A.md # 单次演示反馈
|
||
│ ├── 2026-03-25_客户现场.md # 单次演示反馈
|
||
│ └── _summary.md # 跨场次汇总报告
|
||
└── .slideforge.yml
|
||
```
|
||
|
||
#### 报告内容结构
|
||
|
||
每份反馈报告包含以下板块:
|
||
|
||
| 板块 | 内容 |
|
||
|------|------|
|
||
| **演示概况** | 文件名、版本 hash、演讲者、日期、时长、观众数、互动参与率 |
|
||
| **逐页反馈** | 每页的提问列表(含赞数排序)、投票结果、弹幕关键词、情感倾向、批注汇总、停留时长异常标记 |
|
||
| **整体分析** | 全场互动率、情感曲线(逐页正/中/负占比)、高频关键词 Top 10、未回答问题清单 |
|
||
| **修订建议** | 基于数据的具体改进建议:高频提问对应补充内容、负面情感页优化表述、停留过短页扩充内容 |
|
||
|
||
#### 单次反馈报告示例
|
||
|
||
```markdown
|
||
# 演示反馈报告
|
||
|
||
## 演示概况
|
||
|
||
| 项目 | 内容 |
|
||
|------|------|
|
||
| 文件 | 新品发布会.pptx |
|
||
| 版本 | commit abc1234 |
|
||
| 演讲者 | 张三 |
|
||
| 日期 | 2026-03-20 |
|
||
| 时长 | 45 分钟 |
|
||
| 观众数 | 32 人 |
|
||
| 互动参与率 | 78% |
|
||
|
||
## 逐页反馈
|
||
|
||
### 第 3 页 - "产品架构"
|
||
|
||
- 停留时长: 4分12秒 (全文平均 3分)
|
||
- 提问 (5条):
|
||
1. "架构中缓存层用的是什么方案?" (12赞)
|
||
2. "支持私有化部署吗?" (8赞)
|
||
- 投票: "您认为该架构是否满足需求?"
|
||
完全满足 45% / 基本满足 40% / 需改进 15%
|
||
- 情感倾向: 正面 72%, 中性 20%, 负面 8%
|
||
|
||
## 整体分析
|
||
|
||
- 观众参与度: 高 (78%)
|
||
- 第 7-9 页负面情绪上升
|
||
- 高频关键词: 价格、部署、兼容性
|
||
- 未回答问题: 3 条
|
||
|
||
## 修订建议
|
||
|
||
1. 第 3 页: 补充缓存方案说明
|
||
2. 第 7 页: 定价策略引发较多负面反馈, 建议优化表述
|
||
3. 第 12 页: 停留时长过短, 考虑扩充内容
|
||
```
|
||
|
||
### 7.4 编辑者修订工作流
|
||
|
||
反馈报告生成后驱动 PPT 编辑者完成修订闭环:
|
||
|
||
| 步骤 | 操作 | 说明 |
|
||
|------|------|------|
|
||
| 1 | 接收通知 | MsgHub 推送反馈通知至编辑者 |
|
||
| 2 | 查看反馈 | 在 SlidePortal 反馈看板中查看报告 |
|
||
| 3 | 逐页审阅 | 对照 PPT-Web 查看每页的互动数据与建议 |
|
||
| 4 | 创建分支 | 在 Gitea 中创建 `revision/{date}` 分支 |
|
||
| 5 | 修订 PPT | 在本地修改 PPT 文件并推送 |
|
||
| 6 | 自动转换 | SlideForge 自动触发新版本转换 |
|
||
| 7 | 关闭反馈 | 修订 commit 引用反馈报告,状态自动更新为“已修订” |
|
||
|
||
#### 反馈状态流转
|
||
|
||
| 状态 | 说明 |
|
||
|------|------|
|
||
| **待审阅** | 报告生成后初始状态 |
|
||
| **审阅中** | 编辑者已打开报告 |
|
||
| **修订中** | 编辑者已创建修订分支 |
|
||
| **已修订** | 修订版本已推送并完成转换 |
|
||
| **已关闭** | 编辑者标记无需修订 |
|
||
|
||
### 7.5 反馈看板
|
||
|
||
SlidePortal 为编辑者提供**反馈看板**视图,集中展示所有待处理反馈:
|
||
|
||
```
|
||
+------------------------------------------------------+
|
||
| 反馈看板 [全部/待处理] |
|
||
+------------------------------------------------------+
|
||
| 新品发布会.pptx |
|
||
| [待审阅] 03-25 客户现场 28人 互动率82% 建议4条 |
|
||
| [已修订] 03-20 会议室A 32人 互动率78% 建议3条 |
|
||
| [汇总] 2 场演示, 未回答问题 5 条 |
|
||
| |
|
||
| 季度总结.pptx |
|
||
| [待审阅] 03-22 全员大会 156人 互动率45% 建议6条 |
|
||
+------------------------------------------------------+
|
||
```
|
||
|
||
### 7.6 版本关联与追溯
|
||
|
||
反馈报告与 PPT 版本形成双向可追溯的关联:
|
||
|
||
| 关联关系 | 说明 |
|
||
|---------|------|
|
||
| 反馈报告 -> 演示版本 | 报告中记录演示时的 PPT commit hash |
|
||
| 修订版本 -> 反馈报告 | 修订 commit message 中引用反馈报告文件名 |
|
||
| 反馈报告 -> 修订版本 | 报告状态更新为“已修订”并记录新 commit hash |
|
||
| 跨场次汇总 -> 版本区间 | 汇总报告标注所覆盖的版本与场次列表 |
|
||
|
||
修订提交遵循以下 commit message 格式:
|
||
|
||
```
|
||
fix(slides): 根据反馈优化定价策略页
|
||
|
||
Feedback-Report: 新品发布会.feedback/2026-03-25_客户现场.md
|
||
- 第 3 页: 补充缓存方案说明
|
||
- 第 7 页: 调整定价策略表述
|
||
- 第 12 页: 增加技术细节
|
||
```
|
||
|
||
### 7.7 技术实现
|
||
|
||
FeedbackEngine 作为 SlideForge 的子模块,负责互动数据聚合与报告生成:
|
||
|
||
```
|
||
FeedbackEngine (SlideForge 子模块)
|
||
├─ SessionCollector — 从 PostgreSQL 提取会话互动数据
|
||
├─ PageAggregator — 按页聚合提问/投票/反应/批注
|
||
├─ CrossSessionMerger — 跨场次数据合并与趋势分析
|
||
├─ SentimentAnalyzer — 弹幕与反应的情感倾向统计
|
||
├─ ReportGenerator — Markdown 反馈报告生成
|
||
├─ GitCommitter — 报告写入 Git 仓库
|
||
└─ MsgHub Client — 通知编辑者
|
||
```
|
||
|
||
| 触发方式 | 说明 |
|
||
|---------|------|
|
||
| **会话结束** | 演示结束 5 分钟后自动生成该场次反馈报告 |
|
||
| **手动请求** | 编辑者在 SlidePortal 中手动生成跨场次汇总 |
|
||
| **定时汇总** | 每周一自动生成上周所有演示的汇总报告 |
|
||
|
||
---
|
||
|
||
## 八、用户界面
|
||
|
||
### 8.1 文件目录树
|
||
|
||
SlidePortal 以**文件目录树**为核心导航,与本地文件管理器体验一致:
|
||
|
||
```
|
||
+------------------------------------------------------+
|
||
| 我的演示文稿 [搜索] |
|
||
+------------------------------------------------------+
|
||
| [+] 个人文档 (slides-zhangsan) |
|
||
| [+] 2026-Q1 |
|
||
| [-] 技术方案汇报.pptx 已转换 |
|
||
| [-] 项目进展周报.pptx 已转换 |
|
||
| [-] 新功能演示.pptx 转换中... |
|
||
| [+] 模板 |
|
||
| |
|
||
| [+] 工作组文档 |
|
||
| [+] 市场部 (slides-marketing) |
|
||
| [-] 新品发布会.pptx 已转换 |
|
||
| [-] 客户方案-ABC.pptx 已转换 |
|
||
| [+] 研发部 (slides-rd) |
|
||
| [+] 公开演示 (slides-public) |
|
||
| |
|
||
| [+] 企业模板库 (slides-templates) |
|
||
+------------------------------------------------------+
|
||
```
|
||
|
||
### 8.2 文档操作
|
||
|
||
选中 PPT 文件后可执行的操作:
|
||
|
||
| 操作 | 说明 |
|
||
|------|------|
|
||
| **在线预览** | 浏览器内直接预览转换后的 Web 幻灯片 |
|
||
| **开始演示** | 创建演示会话,生成观众接入二维码,进入全屏 |
|
||
| **下载原文件** | 下载 PPT 原始文件(需有权限) |
|
||
| **查看历史版本** | 查看 Git 提交历史,可回溯任意版本 |
|
||
| **分享链接** | 生成带权限控制的分享链接 |
|
||
| **重新转换** | 手动触发重新转换(更换引擎或修复问题) |
|
||
| **互动数据** | 查看历次演示会话的互动统计 |
|
||
|
||
### 8.3 演讲者控制台
|
||
|
||
演讲者启动演示后,手机端显示控制台:
|
||
|
||
```
|
||
+---------------------------+
|
||
| 演讲者控制台 |
|
||
+---------------------------+
|
||
| |
|
||
| < 上一页 3/15 下一页 > |
|
||
| |
|
||
| +-------------------+ |
|
||
| | 当前页缩略图 | |
|
||
| | | |
|
||
| +-------------------+ |
|
||
| |
|
||
| 演讲者备注: |
|
||
| "这里强调 Q1 增长..." |
|
||
| |
|
||
| 已用时 12:35 |
|
||
| |
|
||
| [发起投票] [Q&A面板] |
|
||
| [激光笔] [结束演示] |
|
||
+---------------------------+
|
||
```
|
||
|
||
---
|
||
|
||
## 九、转换配置
|
||
|
||
### 9.1 仓库级配置
|
||
|
||
每个 Git 仓库根目录的 `.slideforge.yml` 定义转换策略:
|
||
|
||
```yaml
|
||
# .slideforge.yml
|
||
conversion:
|
||
default_engine: onlyoffice # 默认转换引擎
|
||
fallback_engine: libreoffice # 备用引擎
|
||
high_fidelity_engine: aspose # 高保真引擎
|
||
complexity_threshold: 5 # 复杂度阈值(超过则用高保真引擎)
|
||
|
||
fonts:
|
||
embed: true # 嵌入字体子集
|
||
fallback_fonts:
|
||
- "Noto Sans SC"
|
||
- "Microsoft YaHei"
|
||
|
||
output:
|
||
format: revealjs
|
||
image_quality: 85
|
||
image_format: webp
|
||
generate_thumbnail: true
|
||
generate_pdf: true # 同时生成 PDF 版本
|
||
|
||
interaction:
|
||
default_features: [vote, qna, reaction]
|
||
danmaku: false # 弹幕默认关闭
|
||
```
|
||
|
||
### 9.2 文件级配置
|
||
|
||
单个 PPT 可通过同目录 `.meta.yml` 覆盖仓库配置:
|
||
|
||
```yaml
|
||
# 新品发布会.meta.yml
|
||
conversion:
|
||
engine: aspose # 强制使用高保真引擎
|
||
|
||
interaction:
|
||
danmaku: true # 此演示开启弹幕
|
||
vote_slides: [3, 7, 12] # 第 3/7/12 页预设投票
|
||
|
||
publish:
|
||
access: login # 需登录观看
|
||
share_expires: "2026-06-30"
|
||
```
|
||
|
||
---
|
||
|
||
## 十、部署方案
|
||
|
||
### 10.1 服务部署清单
|
||
|
||
全部服务运行于**互联网应用服务器**(腾讯云 / 阿里云),数据后端在私有云:
|
||
|
||
| 服务 | 部署方式 | 运行位置 | 端口 |
|
||
|------|---------|---------|------|
|
||
| SlideForge 转换调度 | Docker (Node.js) | 互联网应用服务器 | 3010 |
|
||
| ONLYOFFICE Document Server | Docker | 互联网应用服务器 | 8000 |
|
||
| LibreOffice Headless | Docker (gotenberg) | 互联网应用服务器 | 3030 |
|
||
| SlidePortal 演示平台 | Docker (Next.js) | 互联网应用服务器 | 3011 |
|
||
| InteractHub 互动中心 | Docker (Node.js) | 互联网应用服务器 | 3012 |
|
||
| Redis | Docker(已有) | 互联网应用服务器 | 6379 |
|
||
| PostgreSQL | 原生安装(已有) | 私有云 | 5432 |
|
||
| Gitea | Docker(已有) | 互联网应用服务器 | 22/443 |
|
||
| Keycloak | Docker(已有) | 互联网应用服务器 | 8443 |
|
||
|
||
### 10.2 Nginx 路由规则
|
||
|
||
```nginx
|
||
# SlidePortal 演示平台
|
||
location /slides/ {
|
||
proxy_pass http://127.0.0.1:3011;
|
||
}
|
||
|
||
# InteractHub WebSocket
|
||
location /ws/interact/ {
|
||
proxy_pass http://127.0.0.1:3012;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
}
|
||
|
||
# SlideForge Webhook(仅限 Gitea 内部调用)
|
||
location /hook/slideforge {
|
||
allow 127.0.0.1;
|
||
deny all;
|
||
proxy_pass http://127.0.0.1:3010;
|
||
}
|
||
|
||
# ONLYOFFICE(仅限 SlideForge 内部调用)
|
||
location /onlyoffice/ {
|
||
allow 127.0.0.1;
|
||
deny all;
|
||
proxy_pass http://127.0.0.1:8000;
|
||
}
|
||
|
||
# 转换后的静态幻灯片资源
|
||
location /slide-assets/ {
|
||
alias /var/www/slide-assets/;
|
||
expires 30d;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 十一、实施路线图
|
||
|
||
| 阶段 | 任务 | 预计周期 |
|
||
|------|------|--------|
|
||
| **第一阶段:基础转换** | ONLYOFFICE + LibreOffice 部署,SlideForge 调度开发 | 第 1-3 周 |
|
||
| **第一阶段** | Reveal.js 封装与后处理流水线开发 | 第 2-3 周 |
|
||
| **第一阶段** | Gitea Webhook 对接,Git 推送自动触发转换 | 第 3 周 |
|
||
| **第二阶段:演示平台** | SlidePortal MVP(目录树 + 在线预览 + 开始演示) | 第 4-5 周 |
|
||
| **第二阶段** | 演讲者手机控制台(遥控翻页 + 演讲者备注) | 第 5-6 周 |
|
||
| **第二阶段** | 终端适配测试(Android TV / 鸿蒙 TV / Windows / iPad) | 第 6-7 周 |
|
||
| **第三阶段:互动系统** | InteractHub 核心开发(WebSocket + 投票 + Q&A) | 第 7-8 周 |
|
||
| **第三阶段** | 弹幕与实时反应功能 | 第 8-9 周 |
|
||
| **第三阶段** | 观众扫码接入 + 互动数据与页面绑定 | 第 9 周 |
|
||
| **第四阶段:质量优化** | 转换质量自动检测(逐页截图对比) | 第 10 周 |
|
||
| **第四阶段** | Aspose.Slides 商业引擎集成(高保真场景) | 第 10-11 周 |
|
||
| **第四阶段** | 字体管理与嵌入优化 | 第 11 周 |
|
||
| **第五阶段:协作增强** | 多组合协作(Fork / Merge Request 流程) | 第 12 周 |
|
||
| **第五阶段** | FeedbackEngine 互动数据聚合与反馈报告生成 | 第 12-13 周 |
|
||
| **第五阶段** | 反馈看板 + 修订工作流 + 版本关联追溯 | 第 13-14 周 |
|
||
| **第五阶段** | 全链路测试与上线 | 第 14-15 周 |
|