更新
This commit is contained in:
@@ -0,0 +1,526 @@
|
|||||||
|
# Writech ICT 服务平台规划设计及实施方案
|
||||||
|
|
||||||
|
## 一、概述
|
||||||
|
|
||||||
|
### 1.1 目标
|
||||||
|
|
||||||
|
基于公司现有 IT 服务资源(详见 [IT服务资源](../IT资源/IT服务资源.md)),构建面向 **2E(企业员工)、2B(合作伙伴)、2C(最终消费者)** 三类用户的统一 ICT 服务平台,实现:
|
||||||
|
|
||||||
|
- 企业员工全线上办公
|
||||||
|
- 全部基础系统与业务系统统一登录,采用**免密码秘钥认证**
|
||||||
|
- 视频之外的全部业务上 SSL 安全保障
|
||||||
|
- 应用服务器可按需弹性扩缩
|
||||||
|
- 核心数据安全自主可控
|
||||||
|
|
||||||
|
### 1.2 基础设施概况
|
||||||
|
|
||||||
|
| 服务器 | 云平台 | 服务区 | IP | 绑定域名 | 定位 |
|
||||||
|
|--------|--------|--------|-----|---------|------|
|
||||||
|
| 腾讯云应用服务器 | 腾讯云 | 广州 | 106.55.191.177 | writech.cn | 大陆数据服务,面向国内用户 |
|
||||||
|
| 阿里云应用服务器 | 阿里云 | 新加坡 | 47.84.109.13 | writech.ai | 品牌站点与海外服务 |
|
||||||
|
| 私有云应用服务器 | 私有云 | 企业 | 118.141.37.23 | — | 数据源站、用户账户信息源 |
|
||||||
|
|
||||||
|
### 1.3 核心架构原则
|
||||||
|
|
||||||
|
- **私有云不直面终端用户**:私有云仅对应用服务器提供数据支撑(数据库、文件存储、身份源),不直接面向 2B / 2C / 2E 用户
|
||||||
|
- **公有云承载互联网服务**:员工在线工作系统、AI 客服、商城、客户支持等全部运行在腾讯云/阿里云应用服务器上
|
||||||
|
- **弹性扩缩**:应用服务器及其上应用可按需增减,平台架构须适应服务器动态变化
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、文档与资料管理体系
|
||||||
|
|
||||||
|
### 2.1 Git 仓库统一管理
|
||||||
|
|
||||||
|
企业全部文档资料均基于 Git 仓库管理和存放,涵盖以下类别:
|
||||||
|
|
||||||
|
| 类别 | 说明 | 典型仓库示例 |
|
||||||
|
|------|------|------------|
|
||||||
|
| 原始资料 | 产品需求、技术方案、会议纪要 | docs、project-plan |
|
||||||
|
| 证件资料 | 企业证照、商标、专利、软著 | certificates、IP-doc |
|
||||||
|
| 媒体宣传资料 | 品牌素材、产品图片、宣传视频脚本 | web-doc、media-assets |
|
||||||
|
| 软件源代码 | 产品代码、固件代码、SDK 代码 | 各产品独立仓库 |
|
||||||
|
| 软件开发工具 | 构建脚本、CI/CD 配置、开发环境配置 | devtools、ci-config |
|
||||||
|
|
||||||
|
### 2.2 Git 服务部署
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────┐
|
||||||
|
│ Git 服务 (Gitea) │
|
||||||
|
│ 运行于:互联网应用服务器 │
|
||||||
|
│ │
|
||||||
|
│ · SSH (22/tcp) — 代码推拉(SSH 秘钥认证) │
|
||||||
|
│ · HTTPS (443/tcp) — Web UI(SSO 秘钥登录) │
|
||||||
|
│ · 仓库数据存储 — 私有云 NFS/Samba 挂载 │
|
||||||
|
└─────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Git 服务**(推荐 Gitea 轻量自托管)运行在互联网应用服务器上,面向员工提供服务
|
||||||
|
- **仓库数据**实际存储于私有云大容量存储,通过内网挂载
|
||||||
|
- 所有 Git 操作均通过 **SSH 秘钥认证**,无密码
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、统一登录与秘钥认证体系
|
||||||
|
|
||||||
|
### 3.1 设计目标
|
||||||
|
|
||||||
|
所有企业基础系统与业务应用必须实现**统一登录**,且全部采用**免密码秘钥登录**,杜绝密码泄露风险。在手机/移动场景下,支持**微信扫码登录**作为秘钥认证的等价替代——微信扫码本质上仍是秘钥认证,手机端微信持有用户凭证(OpenID),相当于手机即秘钥载体。
|
||||||
|
|
||||||
|
需纳入统一登录的系统清单:
|
||||||
|
|
||||||
|
| 分类 | 系统 | 认证方式 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 基础设施 | Git (Gitea) | SSH 秘钥 + Web SSO |
|
||||||
|
| 基础设施 | Samba 文件共享 | Kerberos + 秘钥 |
|
||||||
|
| 基础设施 | 数据库应用 | 客户端证书 |
|
||||||
|
| 通信协作 | 腾讯企业邮箱 | SAML SSO 对接 |
|
||||||
|
| 开发工具 | 编译管理 (Jenkins/Drone) | Web SSO |
|
||||||
|
| 开发工具 | 项目管理 (Redmine/Plane) | Web SSO |
|
||||||
|
| 开发工具 | 测试管理 | Web SSO |
|
||||||
|
| 业务系统 | 技术论坛 | Web SSO |
|
||||||
|
| 业务系统 | 客户支持系统 | Web SSO |
|
||||||
|
| 业务系统 | 商城系统 | Web SSO |
|
||||||
|
| 业务系统 | AI 在线客服 | Web SSO |
|
||||||
|
|
||||||
|
### 3.2 认证架构
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 统一认证架构
|
||||||
|
|
||||||
|
node "私有云 (身份源)" as PCloud {
|
||||||
|
database "OpenLDAP\n用户目录" as LDAP
|
||||||
|
database "SSH 公钥库" as SSHKeys
|
||||||
|
}
|
||||||
|
|
||||||
|
node "互联网应用服务器" as AppServer {
|
||||||
|
component "Keycloak\nSSO 认证中心" as KC
|
||||||
|
component "Nginx\n反向代理" as Nginx
|
||||||
|
component "Git / CI / 项目管理\n论坛 / 商城 / 客服" as Apps
|
||||||
|
}
|
||||||
|
|
||||||
|
cloud "微信开放平台" as WX
|
||||||
|
|
||||||
|
actor "员工 / 合作伙伴 / 消费者" as User
|
||||||
|
|
||||||
|
User -down-> Nginx : HTTPS 访问
|
||||||
|
Nginx -down-> KC : 认证请求
|
||||||
|
KC -down-> LDAP : 用户验证
|
||||||
|
KC -right-> Apps : OIDC Token
|
||||||
|
KC -left-> WX : 微信扫码认证\n(Social IdP)
|
||||||
|
User -down-> Apps : SSH 秘钥访问 (Git)
|
||||||
|
Apps -down-> SSHKeys : 公钥校验
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 技术方案
|
||||||
|
|
||||||
|
#### 身份目录:OpenLDAP
|
||||||
|
|
||||||
|
- 部署于**私有云**,作为全局唯一的用户身份源
|
||||||
|
- 存储员工基本信息、组织架构、角色权限
|
||||||
|
- 存储每个用户的 SSH 公钥(`sshPublicKey` 属性)
|
||||||
|
- 所有系统通过 LDAP 协议查询用户信息
|
||||||
|
|
||||||
|
#### SSO 认证中心:Keycloak
|
||||||
|
|
||||||
|
- 部署于**互联网应用服务器**,面向所有用户提供认证服务
|
||||||
|
- 对接 OpenLDAP 作为用户联邦(User Federation)
|
||||||
|
- 支持 OIDC / SAML 协议,所有 Web 应用通过标准协议接入
|
||||||
|
- **免密码登录实现**:Keycloak 配置 WebAuthn(硬件安全秘钥/系统指纹)作为首选认证方式,禁用密码登录
|
||||||
|
- **微信扫码登录**:Keycloak 配置微信开放平台作为 Social Identity Provider,支持扫码登录作为秘钥认证的移动端替代
|
||||||
|
|
||||||
|
#### 免密码秘钥登录的三种场景
|
||||||
|
|
||||||
|
| 场景 | 方式 | 秘钥载体 | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **SSH 类服务**(Git 推拉、服务器运维) | SSH 秘钥对(Ed25519) | 电脑本地 `~/.ssh/` | 用户本地生成秘钥对,公钥注册到 LDAP,私钥留在本地 |
|
||||||
|
| **Web 类服务 — 电脑端** | WebAuthn 硬件秘钥 / 系统生物识别 | 硬件秘钥 / 电脑 | 用户注册硬件秘钥(如 YubiKey)或系统指纹/面容到 Keycloak |
|
||||||
|
| **Web 类服务 — 移动端** | 微信扫码登录 | 手机微信 | 手机扫描 Keycloak 登录页二维码,微信 OpenID 映射到 LDAP 用户 |
|
||||||
|
|
||||||
|
> **设计要点**:三种方式本质均为秘钥认证——SSH 秘钥存于电脑、WebAuthn 秘钥存于硬件/系统、微信凭证存于手机。三者绑定到同一 LDAP 身份,互为替代,用户按使用场景选择最便捷的方式。
|
||||||
|
|
||||||
|
#### 微信扫码登录与秘钥认证的绑定关系
|
||||||
|
|
||||||
|
微信扫码登录并非独立的认证体系,而是秘钥认证在移动场景下的延伸:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────────┐
|
||||||
|
│ 同一 LDAP 身份 │
|
||||||
|
│ (zhangsan@writech.cn / DN) │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ SSH 秘钥 │ │ WebAuthn │ │ 微信扫码 │ │
|
||||||
|
│ │ Ed25519 │ │ FIDO2 秘钥 │ │ OpenID 绑定 │ │
|
||||||
|
│ │ │ │ │ │ │ │
|
||||||
|
│ │ 载体:电脑 │ │ 载体:硬件 │ │ 载体:手机 │ │
|
||||||
|
│ │ 场景:CLI │ │ 场景:PC浏览器│ │ 场景:移动端 │ │
|
||||||
|
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ 三种秘钥绑定在同一身份上,禁用 LDAP 账户后全部失效 │
|
||||||
|
└──────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**技术实现**:
|
||||||
|
|
||||||
|
1. **Keycloak 配置微信 Social IdP**:在 Keycloak 管理后台添加「微信开放平台」作为 Identity Provider,配置 AppID 和 AppSecret
|
||||||
|
2. **OpenID 绑定**:员工首次使用时,先通过 WebAuthn 登录 Keycloak,在账户设置中「关联社交账号 → 微信」,扫码完成绑定。此后微信 OpenID 与 Keycloak 用户(即 LDAP 身份)建立 1:1 映射
|
||||||
|
3. **登录流程**:Keycloak 登录页显示「微信扫码登录」按钮 → 用户手机微信扫码 → 微信返回 OpenID → Keycloak 查找绑定的 LDAP 用户 → 校验 LDAP 账户状态(未禁用)→ 签发 OIDC Token → 登录成功
|
||||||
|
4. **安全保障**:LDAP 账户一旦禁用,即使微信 OpenID 绑定仍存在,Keycloak 在 Token 签发前会验证 LDAP 状态,登录请求将被拒绝
|
||||||
|
|
||||||
|
#### 腾讯企业邮箱对接
|
||||||
|
|
||||||
|
- 企业邮箱域名:`@writech.cn`
|
||||||
|
- 通过 Keycloak SAML IdP 对接腾讯企业邮箱的 SSO 登录
|
||||||
|
- 员工在 Keycloak 完成秘钥认证后,自动获得企业邮箱访问权
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、SSL 安全策略
|
||||||
|
|
||||||
|
### 4.1 覆盖范围
|
||||||
|
|
||||||
|
| 服务类型 | SSL 策略 | 说明 |
|
||||||
|
|---------|---------|------|
|
||||||
|
| Web 应用(全部) | **强制 HTTPS** | 包括 Git Web UI、SSO、论坛、商城、客服等 |
|
||||||
|
| API 接口(全部) | **强制 HTTPS** | 所有 RESTful / WebSocket / MQTT-over-WSS |
|
||||||
|
| SSH 服务 | SSH 协议自带加密 | Git 推拉、服务器运维 |
|
||||||
|
| 邮件服务 | TLS 加密 | 腾讯企业邮箱原生支持 |
|
||||||
|
| 视频流服务 | **豁免** | 实时视频流对延迟敏感,按需采用 SRTP 或不加密 |
|
||||||
|
|
||||||
|
### 4.2 证书方案:ZeroSSL + acme.sh 自动续期
|
||||||
|
|
||||||
|
全部服务器的 SSL 证书统一采用 **ZeroSSL 免费通配符证书**,由 writech.hk 服务器集中管理:
|
||||||
|
|
||||||
|
- **签发工具**:acme.sh + ZeroSSL ACME 接口
|
||||||
|
- **证书类型**:DV 通配符(`*.writech.cn`、`*.yink.ai`、`*.writech.ai`、`*.writech.hk`)
|
||||||
|
- **DNS 验证**:.ai / .hk 域名通过阿里云 DNS API(dns_ali),.cn 域名通过腾讯云 DNSPod API(dns_dp)
|
||||||
|
- **自动续期**:cron 每日检查,到期前 30 天自动续期
|
||||||
|
- **自动分发**:续期后通过 SCP 推送至全部应用服务器,自动 reload Nginx
|
||||||
|
|
||||||
|
### 4.3 新增应用服务器的证书部署
|
||||||
|
|
||||||
|
当按需新增应用服务器时,证书部署流程:
|
||||||
|
|
||||||
|
1. 在 writech.hk 的分发脚本(`deploy_certs.sh`)中添加新服务器地址
|
||||||
|
2. 配置 writech.hk 到新服务器的 SSH 免密登录(`ssh-copy-id`)
|
||||||
|
3. 手动触发一次分发或等待下次 cron 自动续期时同步
|
||||||
|
4. 新服务器 Nginx 配置引用标准证书路径(`/etc/ssl/certs/`、`/etc/ssl/private/`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、业务应用系统规划
|
||||||
|
|
||||||
|
### 5.1 系统部署总览
|
||||||
|
|
||||||
|
全部业务应用运行于**互联网应用服务器**(腾讯云 / 阿里云),私有云仅提供数据后端支撑:
|
||||||
|
|
||||||
|
| 系统 | 用户群体 | 部署位置 | 说明 |
|
||||||
|
|------|---------|---------|------|
|
||||||
|
| Git 代码托管 (Gitea) | 2E | 互联网应用服务器 | 企业文档与代码管理 |
|
||||||
|
| SSO 认证中心 (Keycloak) | 2E / 2B / 2C | 互联网应用服务器 | 全局统一登录 |
|
||||||
|
| 编译管理 (CI/CD) | 2E | 互联网应用服务器 | 自动构建、自动部署 |
|
||||||
|
| 项目管理 | 2E | 互联网应用服务器 | 任务跟踪、迭代管理 |
|
||||||
|
| 测试管理 | 2E | 互联网应用服务器 | 测试用例、缺陷跟踪 |
|
||||||
|
| 技术论坛 | 2E / 2B | 互联网应用服务器 | 技术交流、知识沉淀 |
|
||||||
|
| Samba 文件共享 | 2E | 互联网应用服务器 | 公共文件共享(VPN 接入) |
|
||||||
|
| 企业邮箱 | 2E | 腾讯企业邮箱 (SaaS) | @writech.cn 统一邮箱 |
|
||||||
|
| AI 在线客服 | 2B / 2C | 互联网应用服务器 | 基于 AI 基础能力的智能客服 |
|
||||||
|
| 客户支持系统 | 2B / 2C | 互联网应用服务器 | 工单、FAQ、文档中心 |
|
||||||
|
| 商城系统 | 2C | 互联网应用服务器 | 产品展示、在线购买 |
|
||||||
|
|
||||||
|
### 5.2 AI 在线客服
|
||||||
|
|
||||||
|
- 部署于互联网应用服务器,直接面向 2B / 2C 用户
|
||||||
|
- 基于云平台 AI 算力 API(腾讯云/阿里云 NLP、大模型接口)构建
|
||||||
|
- 功能:智能问答、产品咨询、售后引导、工单自动分派
|
||||||
|
- 知识库数据存储于私有云,AI 服务通过内网调取
|
||||||
|
|
||||||
|
### 5.3 员工在线工作系统
|
||||||
|
|
||||||
|
员工全线上办公,核心工具链均运行在互联网应用服务器上:
|
||||||
|
|
||||||
|
```
|
||||||
|
员工日常工作流
|
||||||
|
├─ Git — 文档编写、代码开发、版本管理
|
||||||
|
├─ CI/CD — 代码编译、自动测试、自动部署
|
||||||
|
├─ 项目管理 — 任务分派、进度跟踪、迭代规划
|
||||||
|
├─ 测试管理 — 用例编写、测试执行、缺陷跟踪
|
||||||
|
├─ 论坛 — 技术讨论、方案评审、知识分享
|
||||||
|
├─ 邮箱 — 对外沟通、商务协作
|
||||||
|
└─ Samba — 共享大文件(设计稿、固件包等)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、弹性扩缩策略
|
||||||
|
|
||||||
|
### 6.1 应用服务器动态管理
|
||||||
|
|
||||||
|
应用服务器及其上部署的应用会按需增减,平台设计须适应此动态变化:
|
||||||
|
|
||||||
|
#### 新增服务器流程
|
||||||
|
|
||||||
|
1. **资源开通**:在腾讯云/阿里云开通新云服务器实例
|
||||||
|
2. **基础配置**:安装 Nginx、Docker 等基础环境
|
||||||
|
3. **接入认证**:配置 Keycloak OIDC 客户端,接入统一登录
|
||||||
|
4. **证书部署**:在 writech.hk 分发脚本中添加新服务器,同步 SSL 证书
|
||||||
|
5. **DNS 解析**:按需添加子域名解析记录
|
||||||
|
6. **应用部署**:部署业务应用容器
|
||||||
|
7. **Nginx 反代**:配置反向代理和 SSL 终止
|
||||||
|
8. **注册到 LDAP**:如有新服务角色,在 LDAP 中添加对应服务条目
|
||||||
|
|
||||||
|
#### 缩减服务器流程
|
||||||
|
|
||||||
|
1. **业务迁移**:将应用和数据迁移至其他服务器
|
||||||
|
2. **DNS 摘除**:删除或更新相关 DNS 记录
|
||||||
|
3. **证书脚本清理**:从 `deploy_certs.sh` 中移除该服务器
|
||||||
|
4. **Keycloak 清理**:删除对应 OIDC 客户端配置
|
||||||
|
5. **资源释放**:销毁云服务器实例
|
||||||
|
|
||||||
|
### 6.2 配置即代码
|
||||||
|
|
||||||
|
所有服务器配置、部署脚本、Nginx 配置均纳入 Git 仓库管理,确保:
|
||||||
|
|
||||||
|
- 新服务器可通过脚本快速初始化
|
||||||
|
- 配置变更有版本记录,可回溯可审计
|
||||||
|
- 服务器增减时只需修改配置文件并执行部署脚本
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、账户生命周期管理
|
||||||
|
|
||||||
|
### 7.1 员工入职 — 开通账户
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 员工入职账户开通流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:IT管理员在 OpenLDAP 创建用户账户;
|
||||||
|
note right: 填写姓名、邮箱、部门、角色
|
||||||
|
:分配 @writech.cn 企业邮箱;
|
||||||
|
note right: 腾讯企业邮箱后台创建
|
||||||
|
|
||||||
|
:员工在个人电脑生成 SSH 秘钥对;
|
||||||
|
note right
|
||||||
|
ssh-keygen -t ed25519 -C "name@writech.cn"
|
||||||
|
生成 ~/.ssh/id_ed25519 (私钥)
|
||||||
|
和 ~/.ssh/id_ed25519.pub (公钥)
|
||||||
|
end note
|
||||||
|
|
||||||
|
:员工将公钥提交给 IT 管理员;
|
||||||
|
note right: 通过企业邮箱发送或内部系统上传
|
||||||
|
|
||||||
|
:IT管理员将公钥注册到 LDAP;
|
||||||
|
note right: 写入用户的 sshPublicKey 属性
|
||||||
|
|
||||||
|
:员工注册 WebAuthn 硬件秘钥/生物识别;
|
||||||
|
note right
|
||||||
|
登录 Keycloak 自助注册页面
|
||||||
|
插入 YubiKey 或使用系统指纹/面容
|
||||||
|
完成 WebAuthn 绑定
|
||||||
|
end note
|
||||||
|
|
||||||
|
:员工绑定微信扫码登录;
|
||||||
|
note right
|
||||||
|
在 Keycloak 账户设置中
|
||||||
|
选择 "关联社交账号 - 微信"
|
||||||
|
手机微信扫码完成 OpenID 绑定
|
||||||
|
此后可用微信扫码替代 WebAuthn 登录
|
||||||
|
end note
|
||||||
|
|
||||||
|
:账户开通完成;
|
||||||
|
note right
|
||||||
|
可访问:Git、CI/CD、项目管理、
|
||||||
|
测试管理、论坛、邮箱、Samba
|
||||||
|
认证方式:SSH秘钥 / WebAuthn / 微信扫码
|
||||||
|
end note
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 SSH 秘钥管理规范
|
||||||
|
|
||||||
|
#### 秘钥生成要求
|
||||||
|
|
||||||
|
| 项目 | 要求 |
|
||||||
|
|------|------|
|
||||||
|
| 算法 | Ed25519(推荐)或 RSA 4096 |
|
||||||
|
| 口令保护 | 私钥**必须**设置本地口令(passphrase) |
|
||||||
|
| 存储位置 | 私钥仅存于员工本人电脑 `~/.ssh/` 目录 |
|
||||||
|
| 备份 | 私钥禁止上传到云盘或共享目录;建议加密备份到个人 U 盘 |
|
||||||
|
|
||||||
|
#### 公钥注册流程
|
||||||
|
|
||||||
|
1. 员工本地执行 `ssh-keygen -t ed25519 -C "name@writech.cn"` 生成秘钥对
|
||||||
|
2. 将 `~/.ssh/id_ed25519.pub` 内容通过安全渠道提交给 IT 管理员
|
||||||
|
3. IT 管理员通过 LDAP 管理工具将公钥写入该用户条目
|
||||||
|
4. 写入后,员工即可通过 SSH 秘钥访问 Git、服务器等全部 SSH 类服务
|
||||||
|
5. 员工登录 Keycloak 自助页面,注册 WebAuthn 设备用于 Web 类服务
|
||||||
|
6. 员工在 Keycloak 账户设置中关联微信账号(扫码绑定 OpenID),作为移动端登录的替代方式
|
||||||
|
|
||||||
|
### 7.3 员工电脑更换 — 秘钥迁移
|
||||||
|
|
||||||
|
#### 推荐方案:生成新秘钥
|
||||||
|
|
||||||
|
1. 在新电脑上**重新生成**新的 SSH 秘钥对
|
||||||
|
2. 将新公钥提交给 IT 管理员
|
||||||
|
3. IT 管理员在 LDAP 中**追加**新公钥(保留旧公钥,过渡期并存)
|
||||||
|
4. 员工在新电脑验证全部系统可正常访问
|
||||||
|
5. IT 管理员**删除**旧公钥
|
||||||
|
6. 在 Keycloak 中注册新电脑的 WebAuthn 设备
|
||||||
|
|
||||||
|
> **注意**:微信扫码登录绑定与电脑无关(绑定在手机微信上),更换电脑不影响微信扫码登录。
|
||||||
|
|
||||||
|
#### 紧急方案:迁移旧秘钥
|
||||||
|
|
||||||
|
若需立即使用且来不及走流程:
|
||||||
|
|
||||||
|
1. 通过加密 U 盘将旧电脑 `~/.ssh/` 目录中的私钥文件拷贝到新电脑
|
||||||
|
2. 确认拷贝后,**立即安全擦除** U 盘中的秘钥文件
|
||||||
|
3. 在新电脑验证连接正常
|
||||||
|
4. **建议后续仍重新生成秘钥**并替换,降低私钥泄露风险
|
||||||
|
|
||||||
|
### 7.4 员工离职 — 权限回收
|
||||||
|
|
||||||
|
离职权限回收必须在**员工最后工作日当天完成**,流程如下:
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 员工离职权限回收流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:HR 通知 IT 管理员离职日期;
|
||||||
|
|
||||||
|
:IT管理员禁用 LDAP 账户;
|
||||||
|
note right
|
||||||
|
禁用后即时生效:
|
||||||
|
· SSH 秘钥认证失败(公钥已不可用)
|
||||||
|
· Web SSO 登录失败(LDAP 拒绝验证)
|
||||||
|
· 全部系统同步失效
|
||||||
|
end note
|
||||||
|
|
||||||
|
:删除 Keycloak 中该用户的 WebAuthn 设备
|
||||||
|
及微信 OpenID 绑定;
|
||||||
|
|
||||||
|
:在腾讯企业邮箱后台停用邮箱;
|
||||||
|
note right: 邮箱数据保留 90 天备查后删除
|
||||||
|
|
||||||
|
:回收企业设备(如有 YubiKey);
|
||||||
|
|
||||||
|
:从 LDAP 中删除用户公钥;
|
||||||
|
|
||||||
|
if (该员工有服务器 root/sudo 权限?) then (是)
|
||||||
|
:检查并轮换相关服务器的 deploy key;
|
||||||
|
:审计该员工最近操作日志;
|
||||||
|
endif
|
||||||
|
|
||||||
|
:归档离职员工资料;
|
||||||
|
:权限回收完成;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 关键要点
|
||||||
|
|
||||||
|
- **LDAP 禁用即全局失效**:由于所有系统的认证源都是 LDAP,禁用 LDAP 账户后,该员工立即无法访问任何系统,无需逐个系统处理
|
||||||
|
- **企业邮箱独立处理**:腾讯企业邮箱为 SaaS 服务,需在腾讯后台单独停用
|
||||||
|
- **秘钥残留无害**:即使离职员工仍持有私钥,由于公钥已从 LDAP 删除,私钥无法通过任何系统验证
|
||||||
|
- **微信绑定同步失效**:LDAP 账户禁用后,Keycloak 在微信扫码回调时会校验 LDAP 状态,拒绝签发 Token,无需单独解绑微信(但建议清理绑定记录)
|
||||||
|
- **特权账户审计**:对拥有 root/sudo 权限的离职员工,需额外审计操作记录并轮换相关 deploy key
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、系统部署拓扑
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title ICT 服务平台部署拓扑
|
||||||
|
|
||||||
|
node "阿里云 [新加坡]\nwritech.ai · 47.84.109.13" as ACloud {
|
||||||
|
component "Nginx + SSL" as ANginx
|
||||||
|
component "品牌官网" as Web
|
||||||
|
component "海外业务服务" as Overseas
|
||||||
|
}
|
||||||
|
|
||||||
|
cloud "互联网用户" as Users {
|
||||||
|
actor "2E 企业员工" as E
|
||||||
|
actor "2B 合作伙伴" as B
|
||||||
|
actor "2C 最终消费者" as C
|
||||||
|
}
|
||||||
|
|
||||||
|
node "腾讯云 [广州]\nwritech.cn · 106.55.191.177" as TCloud {
|
||||||
|
component "Nginx + SSL" as TNginx
|
||||||
|
component "Keycloak SSO" as SSO
|
||||||
|
|
||||||
|
package "员工工作系统" {
|
||||||
|
component "Git (Gitea)" as Git
|
||||||
|
component "CI/CD" as CICD
|
||||||
|
component "项目管理" as PM
|
||||||
|
}
|
||||||
|
|
||||||
|
package "对外业务系统" {
|
||||||
|
component "AI 在线客服" as AICust
|
||||||
|
component "商城 / 客户支持" as Biz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node "私有云 [数据后端]\n118.141.37.23" as PCloud {
|
||||||
|
database "OpenLDAP\n身份目录" as LDAP
|
||||||
|
database "SSH 公钥库" as Keys
|
||||||
|
database "核心数据库" as DB
|
||||||
|
storage "Git 仓库存储\nSamba 文件存储" as Store
|
||||||
|
}
|
||||||
|
|
||||||
|
node "writech.hk · 证书管理中心" as HK {
|
||||||
|
component "acme.sh + ZeroSSL" as ACME
|
||||||
|
}
|
||||||
|
|
||||||
|
' == 用户 → 阿里云(向上) ==
|
||||||
|
C -up-> ACloud : HTTPS
|
||||||
|
E -up-> ACloud
|
||||||
|
|
||||||
|
' == 用户 → 腾讯云(向下) ==
|
||||||
|
E -down-> TCloud : SSH / WebAuthn / 微信扫码
|
||||||
|
B -down-> TCloud : WebAuthn / 微信扫码 / API
|
||||||
|
C -down-> TCloud : WebAuthn / 微信扫码
|
||||||
|
|
||||||
|
' == 应用 → 数据后端 ==
|
||||||
|
SSO -down-> LDAP : 用户认证
|
||||||
|
Git -down-> Keys : 公钥校验
|
||||||
|
Git -down-> Store : 仓库数据
|
||||||
|
CICD -down-> Store
|
||||||
|
AICust -down-> DB : 知识库
|
||||||
|
Biz -down-> DB : 业务数据
|
||||||
|
|
||||||
|
' == 证书分发(虚线) ==
|
||||||
|
ACME ..> TNginx : 证书分发
|
||||||
|
ACME ..> ANginx : 证书分发
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、实施路线图
|
||||||
|
|
||||||
|
| 阶段 | 任务 | 预计周期 |
|
||||||
|
|------|------|---------|
|
||||||
|
| **第一阶段:基础设施** | 私有云部署 OpenLDAP,建立用户目录 | 第 1 周 |
|
||||||
|
| **第一阶段** | 互联网服务器部署 Keycloak,对接 LDAP | 第 1-2 周 |
|
||||||
|
| **第一阶段** | SSL 证书全覆盖(ZeroSSL + acme.sh 已就绪) | 第 1 周 |
|
||||||
|
| **第一阶段** | 部署 Git (Gitea),配置 SSH 秘钥认证 + SSO | 第 2 周 |
|
||||||
|
| **第二阶段:核心系统** | 部署 CI/CD、项目管理、测试管理,接入 SSO | 第 3-4 周 |
|
||||||
|
| **第二阶段** | 部署 Samba 文件共享,对接 LDAP 认证 | 第 3 周 |
|
||||||
|
| **第二阶段** | 腾讯企业邮箱 SAML SSO 对接 | 第 3 周 |
|
||||||
|
| **第二阶段** | 制定并发布员工秘钥管理规范 | 第 3 周 |
|
||||||
|
| **第三阶段:业务系统** | 部署技术论坛、客户支持系统,接入 SSO | 第 5-6 周 |
|
||||||
|
| **第三阶段** | 部署商城系统,接入 SSO | 第 5-6 周 |
|
||||||
|
| **第三阶段** | 部署 AI 在线客服,对接云平台 AI API | 第 6-8 周 |
|
||||||
|
| **第四阶段:运营优化** | 弹性扩缩自动化脚本开发 | 按需 |
|
||||||
|
| **第四阶段** | 全系统安全审计与渗透测试 | 按需 |
|
||||||
|
|||||||
@@ -0,0 +1,900 @@
|
|||||||
|
# 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 周 |
|
||||||
+276
-103
@@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
自然写科技拥有四个域名,各自承担明确的角色分工:
|
自然写科技拥有四个域名,各自承担明确的角色分工:
|
||||||
|
|
||||||
| 域名 | 角色 | 说明 |
|
| 域名 | 角色 | 注册/托管 | 说明 |
|
||||||
|------|------|------|
|
|------|------|----------|------|
|
||||||
| **yink.ai** | **品牌主域 / 全球前端** | 解析到香港服务器,对外统一宣传,所有营销材料、名片、包装统一使用此域名 |
|
| **yink.ai** | **品牌主域 / 全球前端** | **阿里云** | 解析到阿里云新加坡服务器,对外统一宣传,所有营销材料、名片、包装统一使用此域名 |
|
||||||
| writech.ai | 品牌辅助域 | 与 yink.ai 指向同一站点,301 跳转至 yink.ai,保留完整品牌名的可达性 |
|
| writech.ai | 品牌辅助域 | 阿里云 | 与 yink.ai 指向同一站点,301 跳转至 yink.ai,保留完整品牌名的可达性 |
|
||||||
| writech.cn | 大陆数据服务 | ICP 备案,承载 API、存储、AI 处理,所有用户数据留存于大陆 |
|
| writech.cn | 大陆数据服务 | 腾讯云 | ICP 备案已完成,承载 API、存储、AI 处理,所有用户数据留存于大陆 |
|
||||||
| writech.hk | 备用 / 香港节点 | 可作 yink.ai 的 CNAME 或香港 CDN 源站备用入口 |
|
| writech.hk | 备用 / 香港节点 | 阿里云 | 可作 yink.ai 的 CNAME 或备用入口 |
|
||||||
|
|
||||||
**为什么选择 yink.ai 作为品牌主域**:
|
**为什么选择 yink.ai 作为品牌主域**:
|
||||||
|
|
||||||
@@ -28,15 +28,15 @@
|
|||||||
|
|
||||||
### 2.1 首页(yink.ai)
|
### 2.1 首页(yink.ai)
|
||||||
|
|
||||||
- 部署于香港云服务器(阿里云 HK / 腾讯云 HK),并接入 **Cloudflare** 全球 CDN
|
- 部署于阿里云新加坡服务器(47.84.109.13),并接入**阿里云 CDN** 全球加速
|
||||||
- 页面为纯静态(HTML / CSS / JS),内容基本不变,CDN 全球缓存后访问极快
|
- 页面为纯静态(HTML / CSS / JS),内容基本不变,CDN 全球缓存后访问极快
|
||||||
- 大陆用户访问 yink.ai 属于"浏览境外网站",只要页面不含敏感内容,一般可正常访问(与 GitHub Pages、Notion 等性质相同)
|
- 大陆用户访问 yink.ai 属于"浏览境外网站",只要页面不含敏感内容,一般可正常访问(与 GitHub Pages、Notion 等性质相同)
|
||||||
- 访问 writech.ai 自动 301 跳转至 yink.ai,两个域名共享同一香港源站
|
- 访问 writech.ai 自动 301 跳转至 yink.ai,两个域名共享同一阿里云新加坡源站
|
||||||
- **首页服务器不存放任何用户数据**,仅作品牌展示与产品介绍
|
- **首页服务器不存放任何用户数据**,仅作品牌展示与产品介绍
|
||||||
|
|
||||||
### 2.2 大陆数据服务(writech.cn)
|
### 2.2 大陆数据服务(writech.cn)
|
||||||
|
|
||||||
独立 ICP 备案,部署于大陆云服务器(阿里云 / 腾讯云),承载全部后端业务:
|
writech.cn 已完成 ICP 备案,部署于腾讯云广州服务器(106.55.191.177),承载全部后端业务:
|
||||||
|
|
||||||
- 用户账号注册 / 登录 / 认证(OAuth2 / JWT)
|
- 用户账号注册 / 登录 / 认证(OAuth2 / JWT)
|
||||||
- 智能笔笔迹数据上传 / 下载
|
- 智能笔笔迹数据上传 / 下载
|
||||||
@@ -72,33 +72,35 @@ yink.ai 前端 JS
|
|||||||
|
|
||||||
### 2.4 海外数据服务(按需扩展)
|
### 2.4 海外数据服务(按需扩展)
|
||||||
|
|
||||||
当海外业务增长到需要独立节点时,通过 Cloudflare Worker 实现地区智能路由,无需改动客户端代码:
|
当海外业务增长到需要独立节点时,通过阿里云 CDN 边缘脚本(EdgeScript)或 API 网关实现地区智能路由,无需改动客户端代码:
|
||||||
|
|
||||||
```
|
```
|
||||||
用户访问 yink.ai 首页
|
用户访问 yink.ai 首页
|
||||||
└─ Cloudflare Worker 检测用户 IP 所在地区
|
└─ 阿里云 CDN 边缘节点检测用户 IP 所在地区
|
||||||
├─ 大陆用户 → API BaseURL = https://api.writech.cn
|
├─ 大陆用户 → API BaseURL = https://api.writech.cn
|
||||||
└─ 海外用户 → API BaseURL = https://api-sg.yink.ai(新加坡)
|
└─ 海外用户 → API BaseURL = https://api-sg.yink.ai(新加坡)
|
||||||
或 https://api-us.yink.ai(美西)
|
或 https://api-us.yink.ai(美西)
|
||||||
```
|
```
|
||||||
|
|
||||||
- 海外 API 节点部署于新加坡 / 美西云服务器,用户数据按所在地合规存储
|
- 海外 API 节点部署于新加坡 / 美西云服务器,用户数据按所在地合规存储
|
||||||
- Cloudflare Worker 提供 `/geo` 接口,前端 JS 首次加载时调用一次,缓存地区信息后动态切换 API BaseURL
|
- 阿里云 CDN 边缘脚本提供地区检测能力,前端 JS 首次加载时调用一次,缓存地区信息后动态切换 API BaseURL
|
||||||
- 海外节点与大陆节点通过消息队列异步同步必要的公共数据(如产品目录、固件版本),用户私有数据不跨境传输
|
- 海外节点与大陆节点通过消息队列异步同步必要的公共数据(如产品目录、固件版本),用户私有数据不跨境传输
|
||||||
|
|
||||||
### 2.5 DNS 规划
|
### 2.5 DNS 规划
|
||||||
|
|
||||||
| 记录 | 类型 | 指向 | 用途 |
|
.ai 和 .hk 域名 DNS 托管于**阿里云 DNS**,.cn 域名 DNS 托管于**腾讯云 DNSPod**:
|
||||||
|------|------|------|------|
|
|
||||||
| **yink.ai** | **A / Proxied** | **Cloudflare CDN → 香港源站** | **品牌主域首页** |
|
| 记录 | 类型 | 指向 | DNS 平台 | 用途 |
|
||||||
| www.yink.ai | CNAME | yink.ai | 带 www 访问 |
|
|------|------|------|---------|------|
|
||||||
| api.yink.ai | CNAME / Worker | Cloudflare Worker | 预留,可转发至 api.writech.cn |
|
| **yink.ai** | **A** | **阿里云新加坡服务器** | **阿里云 DNS** | **品牌主域首页** |
|
||||||
| api-sg.yink.ai | A | 新加坡服务器 | 海外 API(按需) |
|
| www.yink.ai | CNAME | yink.ai | 阿里云 DNS | 带 www 访问 |
|
||||||
| writech.ai | A / Proxied | Cloudflare CDN → 同一香港源站 | 辅助域,301 跳转至 yink.ai |
|
| api.yink.ai | CNAME | api.writech.cn | 阿里云 DNS | 预留,转发至大陆 API |
|
||||||
| www.writech.ai | CNAME | writech.ai | 301 跳转至 yink.ai |
|
| api-sg.yink.ai | A | 新加坡服务器 | 阿里云 DNS | 海外 API(按需) |
|
||||||
| writech.cn | A | 大陆云服务器 | 主备案域 |
|
| writech.ai | A | 阿里云新加坡服务器 | 阿里云 DNS | 辅助域,301 跳转至 yink.ai |
|
||||||
| api.writech.cn | A | 大陆 API 服务器 | 大陆数据 API |
|
| www.writech.ai | CNAME | writech.ai | 阿里云 DNS | 301 跳转至 yink.ai |
|
||||||
| writech.hk | CNAME | yink.ai | 香港备用入口 |
|
| writech.cn | A | 腾讯云广州服务器 | 腾讯云 DNSPod | 大陆数据服务(ICP 已备案) |
|
||||||
|
| api.writech.cn | A | 腾讯云广州服务器 | 腾讯云 DNSPod | 大陆数据 API |
|
||||||
|
| writech.hk | CNAME | yink.ai | 阿里云 DNS | 备用入口 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -114,20 +116,19 @@ yink.ai 前端 JS
|
|||||||
|
|
||||||
### 3.2 推荐方案
|
### 3.2 推荐方案
|
||||||
|
|
||||||
**方案 A — Cloudflare Email Routing(免费,适合早期)**
|
**方案 A — 免费邮件转发服务(适合早期)**
|
||||||
|
|
||||||
```
|
```
|
||||||
yink.ai DNS 托管于 Cloudflare
|
yink.ai DNS 托管于阿里云
|
||||||
└─ 开启 Cloudflare Email Routing(免费功能)
|
└─ 配置 MX 记录指向免费邮件转发服务(如 ImprovMX / ForwardEmail.net)
|
||||||
└─ MX 记录自动指向 Cloudflare 邮件路由服务器
|
└─ 将 xxx@yink.ai 转发到员工实际收件邮箱
|
||||||
└─ 将 xxx@yink.ai 转发到员工实际收件邮箱
|
├─ 个人员工:转发到各自的 Gmail / QQ 邮箱
|
||||||
├─ 个人员工:转发到各自的 Gmail / QQ 邮箱
|
└─ 客服角色:转发到飞书群邮箱 / 企业微信
|
||||||
└─ 客服角色:转发到飞书群邮箱 / 企业微信
|
|
||||||
└─ 发件配置:在 Gmail / Outlook 中添加"以其他地址发送"
|
└─ 发件配置:在 Gmail / Outlook 中添加"以其他地址发送"
|
||||||
配置 SMTP 凭据,对外显示 xxx@yink.ai 发出
|
配置 SMTP 凭据,对外显示 xxx@yink.ai 发出
|
||||||
```
|
```
|
||||||
|
|
||||||
优点:完全免费,5 分钟配置完成,无需购买额外服务
|
优点:免费或极低成本,配置简单,无需购买额外服务
|
||||||
适合:公司初创期,人员 20 人以内
|
适合:公司初创期,人员 20 人以内
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -194,69 +195,217 @@ writech.ai. MX 10 exmail.qq.com. # 同一邮件服务商
|
|||||||
writech.ai. TXT "v=spf1 include:spf.mail.qq.com ~all"
|
writech.ai. TXT "v=spf1 include:spf.mail.qq.com ~all"
|
||||||
```
|
```
|
||||||
|
|
||||||
> **说明**:以上记录中的具体值(MX 主机名、SPF include、DKIM 公钥)在选定邮件服务商后,由服务商管理后台提供,按实际值填写到 Cloudflare DNS 即可。writech.ai 辅助域的 MX 配置确保历史 @writech.ai 邮件可正常接收并转发至对应 @yink.ai 邮箱。
|
> **说明**:以上记录中的具体值(MX 主机名、SPF include、DKIM 公钥)在选定邮件服务商后,由服务商管理后台提供,按实际值填写到对应 DNS 托管平台(阿里云 DNS)即可。writech.ai 辅助域的 MX 配置确保历史 @writech.ai 邮件可正常接收并转发至对应 @yink.ai 邮箱。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 四、SSL / TLS 证书规划
|
## 四、SSL / TLS 证书规划
|
||||||
|
|
||||||
全站 HTTPS 是安全底线,四个域名及其子域均须配置 SSL 证书,且需兼顾成本、自动续期和多域名管理的便捷性。
|
全站 HTTPS 是安全底线,四个域名及其子域均须配置 SSL 证书。统一采用 **ZeroSSL** 作为证书签发服务,由 **writech.hk 服务器**集中运行 acme.sh 脚本完成所有域名的证书申请与自动续期,再分发至各业务服务器。
|
||||||
|
|
||||||
### 4.1 各域名证书方案
|
### 4.1 统一证书方案:ZeroSSL
|
||||||
|
|
||||||
| 域名 / 子域 | 推荐方案 | 证书类型 | 费用 | 有效期 / 续期 |
|
**为什么选择 ZeroSSL**:
|
||||||
|------------|---------|---------|------|---------------|
|
|
||||||
| yink.ai / www / api.yink.ai | Cloudflare Universal SSL | DV 通配符 | 免费 | 自动续期,无需人工介入 |
|
- 免费 DV 证书,90 天有效期,通过 ACME 协议自动续期
|
||||||
| writech.ai / www.writech.ai | Cloudflare Universal SSL | DV 通配符 | 免费 | 自动续期,与 yink.ai 同一 Cloudflare 账户 |
|
- 根证书为 Sectigo(原 Comodo),全球浏览器和设备信任链完整,兼容性优于 Let's Encrypt 在部分老旧设备上的表现
|
||||||
| writech.cn / api.writech.cn | 云厂商免费证书(阿里云 / 腾讯云)| DV 单域名 | 免费 | 1 年,到期前自动或手动续期 |
|
- 提供 Web 管理面板(zerossl.com),可随时查看已签发证书状态
|
||||||
| writech.hk | 随 yink.ai 走 Cloudflare | DV | 免费 | 自动 |
|
- 完整支持 ACME v2 协议,与 acme.sh 工具无缝集成
|
||||||
| 未来海外节点 api-sg / api-us | Let's Encrypt + Certbot 自动化 | DV 通配符 | 免费 | 90 天,cron 自动续期 |
|
- 支持通配符证书(Wildcard)和多域名 SAN 证书
|
||||||
|
|
||||||
|
**证书覆盖范围**:
|
||||||
|
|
||||||
|
| 域名 / 子域 | 证书类型 | 费用 | 有效期 / 续期 |
|
||||||
|
|------------|---------|------|---------------|
|
||||||
|
| yink.ai / *.yink.ai | DV 通配符 | 免费 | 90 天,acme.sh 自动续期 |
|
||||||
|
| writech.ai / *.writech.ai | DV 通配符 | 免费 | 90 天,acme.sh 自动续期 |
|
||||||
|
| writech.cn / *.writech.cn | DV 通配符 | 免费 | 90 天,acme.sh 自动续期 |
|
||||||
|
| writech.hk / *.writech.hk | DV 通配符 | 免费 | 90 天,acme.sh 自动续期 |
|
||||||
|
|
||||||
> **DV**(Domain Validation)= 域名验证型证书,签发快、免费,满足绝大多数场景。若未来需要在浏览器地址栏显示企业名称(绿色标识),可升级为 OV/EV 证书。
|
> **DV**(Domain Validation)= 域名验证型证书,签发快、免费,满足绝大多数场景。若未来需要在浏览器地址栏显示企业名称(绿色标识),可升级为 OV/EV 证书。
|
||||||
|
|
||||||
### 4.2 Cloudflare 侧(yink.ai / writech.ai)
|
### 4.2 证书管理架构
|
||||||
|
|
||||||
yink.ai 和 writech.ai 两个域名均托管到 Cloudflare 后,各自自动获得以下两层 TLS:
|
**writech.hk 服务器**承担证书集中管理节点的角色:
|
||||||
|
|
||||||
```
|
```
|
||||||
用户浏览器 ←─ Cloudflare Universal SSL(自动签发)─→ Cloudflare CDN 边缘节点
|
writech.hk 服务器(证书管理中心)
|
||||||
│
|
|
|
||||||
Cloudflare 边缘节点 ←─ Origin Certificate(15年有效)─→ 香港源站服务器
|
|-- acme.sh + ZeroSSL ACME
|
||||||
|
| |-- 申请/续期 yink.ai 通配符证书
|
||||||
|
| |-- 申请/续期 writech.ai 通配符证书
|
||||||
|
| |-- 申请/续期 writech.cn 通配符证书
|
||||||
|
| |-- 申请/续期 writech.hk 通配符证书
|
||||||
|
|
|
||||||
|
|-- cron 定时任务(每天凌晨 2:00 检查续期)
|
||||||
|
|
|
||||||
|
|-- 续期成功后自动分发证书文件
|
||||||
|
|-- SCP 推送至阿里云应用服务器
|
||||||
|
|-- SCP 推送至腾讯云应用服务器
|
||||||
|
|-- SCP 推送至私有云 Linux 服务器
|
||||||
|
|-- 各服务器执行 reload Nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
- **前端(浏览器 → CDN)**:Cloudflare 自动签发 Universal SSL 证书,覆盖 `yink.ai` 及 `*.yink.ai`(同理 `writech.ai` 及 `*.writech.ai`)所有子域,零配置
|
**通配符证书验证方式**:通配符证书必须通过 DNS TXT 记录验证(DNS-01 Challenge)。acme.sh 内置阿里云 / 腾讯云(DNSPod)DNS API 插件,可全自动完成 DNS 记录的添加与清理,无需人工干预。
|
||||||
- **回源(CDN → 源站)**:在 Cloudflare 控制台生成 Origin Certificate(免费,最长 15 年有效),安装到香港源站 Nginx,确保回源链路也加密
|
|
||||||
- **SSL 模式设为 Full (Strict)**:强制双向验证,杜绝中间人攻击
|
|
||||||
|
|
||||||
### 4.3 大陆侧(writech.cn)
|
### 4.3 acme.sh 安装与配置(writech.hk)
|
||||||
|
|
||||||
大陆 API 服务器不经过 Cloudflare,需独立申请和管理证书:
|
**首次安装 acme.sh**:
|
||||||
|
|
||||||
**方案 A — 云厂商免费证书(推荐)**
|
|
||||||
|
|
||||||
- 阿里云 / 腾讯云均提供 **免费 DV 证书**(每年可申请 20 张)
|
|
||||||
- 在控制台申请 → DNS 验证 → 自动签发 → 下载部署至 Nginx / API 网关
|
|
||||||
- 到期前云厂商会邮件提醒,可设置自动续期
|
|
||||||
|
|
||||||
**方案 B — Let's Encrypt + Certbot 自动化**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装 Certbot(以 Ubuntu + Nginx 为例)
|
# 安装 acme.sh(以普通用户身份运行,不要使用 root)
|
||||||
sudo apt install certbot python3-certbot-nginx
|
curl https://get.acme.sh | sh -s email=admin@yink.ai
|
||||||
|
|
||||||
# 申请证书(含 writech.cn 和 api.writech.cn)
|
# 将默认 CA 切换为 ZeroSSL
|
||||||
sudo certbot --nginx -d writech.cn -d api.writech.cn
|
acme.sh --set-default-ca --server zerossl
|
||||||
|
|
||||||
# 自动续期已默认配置,验证:
|
# 注册 ZeroSSL 账号(首次使用需要)
|
||||||
sudo certbot renew --dry-run
|
acme.sh --register-account --server zerossl \
|
||||||
|
--eab-kid "<YOUR_EAB_KID>" \
|
||||||
|
--eab-hmac-key "<YOUR_EAB_HMAC_KEY>"
|
||||||
```
|
```
|
||||||
|
|
||||||
- 完全免费,90 天有效期,Certbot cron 任务自动续期
|
> **EAB 凭据获取**:在 zerossl.com 注册账号后,进入 Developer 页面生成 EAB KID 和 HMAC Key。
|
||||||
- 适合自建服务器(非云厂商托管)场景
|
|
||||||
|
|
||||||
### 4.4 Nginx HTTPS 配置模板
|
**申请通配符证书**(.ai / .hk 域名使用阿里云 DNS API):
|
||||||
|
|
||||||
大陆 API 服务器的 Nginx 推荐配置:
|
```bash
|
||||||
|
# 配置阿里云 DNS API 凭据(用于 .ai 和 .hk 域名)
|
||||||
|
export Ali_Key="<YOUR_ALI_ACCESS_KEY>"
|
||||||
|
export Ali_Secret="<YOUR_ALI_SECRET_KEY>"
|
||||||
|
|
||||||
|
# 申请 yink.ai 通配符证书
|
||||||
|
acme.sh --issue --dns dns_ali \
|
||||||
|
-d "yink.ai" -d "*.yink.ai" \
|
||||||
|
--keylength ec-256
|
||||||
|
|
||||||
|
# 申请 writech.ai 通配符证书
|
||||||
|
acme.sh --issue --dns dns_ali \
|
||||||
|
-d "writech.ai" -d "*.writech.ai" \
|
||||||
|
--keylength ec-256
|
||||||
|
|
||||||
|
# 申请 writech.hk 通配符证书
|
||||||
|
acme.sh --issue --dns dns_ali \
|
||||||
|
-d "writech.hk" -d "*.writech.hk" \
|
||||||
|
--keylength ec-256
|
||||||
|
```
|
||||||
|
|
||||||
|
**申请 writech.cn 通配符证书**(使用腾讯云 DNSPod API):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 配置腾讯云 DNSPod API 凭据(用于 .cn 域名)
|
||||||
|
export DP_Id="<YOUR_DNSPOD_ID>"
|
||||||
|
export DP_Key="<YOUR_DNSPOD_KEY>"
|
||||||
|
|
||||||
|
# 申请 writech.cn 通配符证书
|
||||||
|
acme.sh --issue --dns dns_dp \
|
||||||
|
-d "writech.cn" -d "*.writech.cn" \
|
||||||
|
--keylength ec-256
|
||||||
|
```
|
||||||
|
|
||||||
|
> **ec-256**:使用 ECC P-256 密钥,比传统 RSA 2048 握手更快、密钥更短,现代浏览器和服务器均已支持。
|
||||||
|
|
||||||
|
### 4.4 证书分发与部署
|
||||||
|
|
||||||
|
证书申请成功后,需要安装到各业务服务器。当前服务器清单:
|
||||||
|
|
||||||
|
| 服务器 | 角色 | 使用的证书 |
|
||||||
|
|-------|------|----------|
|
||||||
|
| **腾讯云应用服务器(广州)** | writech.cn 大陆数据服务 | writech.cn 通配符 |
|
||||||
|
| **阿里云应用服务器(新加坡)** | yink.ai / writech.ai 品牌站点及海外服务 | yink.ai + writech.ai 通配符 |
|
||||||
|
| **私有云 Linux 服务器** | 数据源站、用户账户信息源 | 按需部署各域名证书 |
|
||||||
|
| **writech.hk 服务器** | 证书管理中心 | yink.ai + writech.ai + writech.cn + writech.hk 通配符 |
|
||||||
|
|
||||||
|
**acme.sh 安装证书到本地(writech.hk 自身)**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装 yink.ai 证书到 Nginx 目录
|
||||||
|
acme.sh --install-cert -d "yink.ai" -d "*.yink.ai" \
|
||||||
|
--key-file /etc/ssl/private/yink_ai.key \
|
||||||
|
--fullchain-file /etc/ssl/certs/yink_ai.pem \
|
||||||
|
--reloadcmd "sudo systemctl reload nginx"
|
||||||
|
|
||||||
|
# 安装 writech.ai 证书
|
||||||
|
acme.sh --install-cert -d "writech.ai" -d "*.writech.ai" \
|
||||||
|
--key-file /etc/ssl/private/writech_ai.key \
|
||||||
|
--fullchain-file /etc/ssl/certs/writech_ai.pem \
|
||||||
|
--reloadcmd "sudo systemctl reload nginx"
|
||||||
|
|
||||||
|
# 安装 writech.hk 证书
|
||||||
|
acme.sh --install-cert -d "writech.hk" -d "*.writech.hk" \
|
||||||
|
--key-file /etc/ssl/private/writech_hk.key \
|
||||||
|
--fullchain-file /etc/ssl/certs/writech_hk.pem \
|
||||||
|
--reloadcmd "sudo systemctl reload nginx"
|
||||||
|
```
|
||||||
|
|
||||||
|
**自动分发脚本(deploy_certs.sh)**:
|
||||||
|
|
||||||
|
acme.sh 续期成功后通过 `--reloadcmd` 触发此脚本,将证书推送到远程服务器:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
# deploy_certs.sh — 证书续期后自动分发到各业务服务器
|
||||||
|
# 部署在 writech.hk 服务器上,由 acme.sh --reloadcmd 触发
|
||||||
|
|
||||||
|
LOG_FILE="/var/log/cert_deploy.log"
|
||||||
|
DATE=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
# === 远程服务器列表 ===
|
||||||
|
ALIYUN_HOST="root@<阿里云内网IP>"
|
||||||
|
TENCENT_HOST="root@<腾讯云内网IP>"
|
||||||
|
PRIVATE_HOST="root@<私有云IP>"
|
||||||
|
|
||||||
|
# === 证书源路径 ===
|
||||||
|
CERT_DIR="$HOME/.acme.sh"
|
||||||
|
|
||||||
|
# === 分发函数 ===
|
||||||
|
deploy_cert() {
|
||||||
|
local host=$1
|
||||||
|
local domain=$2
|
||||||
|
local remote_cert_dir="/etc/ssl/certs"
|
||||||
|
local remote_key_dir="/etc/ssl/private"
|
||||||
|
|
||||||
|
echo "[$DATE] 分发 $domain 证书到 $host" >> $LOG_FILE
|
||||||
|
|
||||||
|
scp -q "${CERT_DIR}/${domain}_ecc/fullchain.cer" \
|
||||||
|
"${host}:${remote_cert_dir}/${domain//\./_}.pem"
|
||||||
|
scp -q "${CERT_DIR}/${domain}_ecc/${domain}.key" \
|
||||||
|
"${host}:${remote_key_dir}/${domain//\./_}.key"
|
||||||
|
|
||||||
|
ssh -q "$host" "sudo systemctl reload nginx" && \
|
||||||
|
echo "[$DATE] $host ($domain) 部署成功" >> $LOG_FILE || \
|
||||||
|
echo "[$DATE] $host ($domain) 部署失败!" >> $LOG_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
# === 分发 writech.cn 证书到大陆服务器 ===
|
||||||
|
deploy_cert "$ALIYUN_HOST" "writech.cn"
|
||||||
|
deploy_cert "$TENCENT_HOST" "writech.cn"
|
||||||
|
|
||||||
|
# === 分发所有域名证书到私有云服务器 ===
|
||||||
|
for domain in yink.ai writech.ai writech.cn writech.hk; do
|
||||||
|
deploy_cert "$PRIVATE_HOST" "$domain"
|
||||||
|
done
|
||||||
|
|
||||||
|
# === 重载本地 Nginx(writech.hk 自身)===
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
echo "[$DATE] 本地 writech.hk Nginx 已重载" >> $LOG_FILE
|
||||||
|
|
||||||
|
echo "[$DATE] === 证书分发完成 ===" >> $LOG_FILE
|
||||||
|
```
|
||||||
|
|
||||||
|
**配置 acme.sh 续期后自动触发分发**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 为每个域名设置续期后的部署钩子
|
||||||
|
acme.sh --install-cert -d "writech.cn" -d "*.writech.cn" \
|
||||||
|
--reloadcmd "/home/deploy/deploy_certs.sh"
|
||||||
|
```
|
||||||
|
|
||||||
|
> **SSH 免密登录**:writech.hk 需预先配置到各远程服务器的 SSH Key 免密登录(`ssh-copy-id`),确保 SCP 和 SSH 命令无需交互。
|
||||||
|
|
||||||
|
### 4.5 Nginx HTTPS 配置模板
|
||||||
|
|
||||||
|
各服务器的 Nginx 推荐配置(以 writech.cn API 服务器为例):
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
server {
|
server {
|
||||||
@@ -292,16 +441,35 @@ server {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.5 证书监控与告警
|
> writech.hk 的 Nginx 配置类似,将 `ssl_certificate` 路径替换为对应域名的证书文件即可。
|
||||||
|
|
||||||
证书过期是生产事故高频原因之一,建议配置监控:
|
### 4.6 自动续期验证
|
||||||
|
|
||||||
|
acme.sh 安装时已自动注册 cron 任务,每天凌晨检查证书到期情况,距到期 30 天内自动续期:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看 acme.sh 自动续期 cron
|
||||||
|
crontab -l | grep acme.sh
|
||||||
|
# 输出类似:0 2 * * * "/home/deploy/.acme.sh"/acme.sh --cron --home "/home/deploy/.acme.sh"
|
||||||
|
|
||||||
|
# 手动测试续期流程(不会真正续期,仅验证流程)
|
||||||
|
acme.sh --renew -d "yink.ai" -d "*.yink.ai" --force --dry-run
|
||||||
|
|
||||||
|
# 查看所有已管理证书的状态
|
||||||
|
acme.sh --list
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.7 证书监控与告警
|
||||||
|
|
||||||
|
证书过期是生产事故高频原因之一,建议配置多层监控:
|
||||||
|
|
||||||
| 方式 | 说明 |
|
| 方式 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| Cloudflare 仪表盘 | yink.ai / writech.ai 证书由 CF 自动管理,可在 SSL/TLS 页面查看状态 |
|
| acme.sh cron 日志 | 续期脚本日志保存在 `~/.acme.sh/acme.sh.log`,可定期检查是否有续期失败记录 |
|
||||||
| 云厂商短信/邮件提醒 | 阿里云 / 腾讯云证书到期前 30 天自动通知 |
|
| deploy_certs.sh 日志 | 分发脚本日志保存在 `/var/log/cert_deploy.log`,记录每次推送结果 |
|
||||||
| Certbot renew cron | Let's Encrypt 证书自动续期,配合 `--deploy-hook` 重载 Nginx |
|
| ZeroSSL 管理面板 | 登录 zerossl.com 查看所有已签发证书的到期时间和状态 |
|
||||||
| 外部监控(推荐) | 使用 [UptimeRobot](https://uptimerobot.com)(免费)监控各域名 HTTPS 可用性,到期前自动邮件告警 |
|
| 外部监控(推荐) | 使用 [UptimeRobot](https://uptimerobot.com)(免费)监控各域名 HTTPS 可用性,证书异常时自动邮件告警 |
|
||||||
|
| 脚本告警(推荐) | 在 deploy_certs.sh 中增加续期失败时发送邮件或企业微信/飞书通知的逻辑 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -310,32 +478,37 @@ server {
|
|||||||
```
|
```
|
||||||
┌─────────────────────────────────┐
|
┌─────────────────────────────────┐
|
||||||
│ 用户(大陆 / 海外) │
|
│ 用户(大陆 / 海外) │
|
||||||
└─────────────────┬───────────────┘
|
└────────────────┬────────────────┘
|
||||||
│ HTTPS
|
│ HTTPS
|
||||||
▼
|
┌─────────────┴─────────────┐
|
||||||
┌─────────────────────────────────┐
|
▼ ▼
|
||||||
│ yink.ai(主)/ writech.ai(301跳转) │
|
┌───────────────────────┐ ┌───────────────────────┐
|
||||||
│ Cloudflare CDN · 香港源站 │
|
│ writech.cn │ │ yink.ai / writech.ai │
|
||||||
│ 静态首页 / 品牌落地页 / 文档 │
|
│ (大陆·ICP 已备案) │ │ (品牌站·海外服务) │
|
||||||
└──────────┬──────────────┬────────┘
|
│ 腾讯云 · 广州 │ │ 阿里云 · 新加坡 │
|
||||||
│ CORS API │ CORS API
|
│ 106.55.191.177 │ │ 47.84.109.13 │
|
||||||
▼ ▼
|
│ │ │ │
|
||||||
┌───────────────────┐ ┌──────────────────────┐
|
│ · 用户认证 │ │ · 品牌首页 / 落地页 │
|
||||||
│ api.writech.cn │ │ api-sg.writech.ai │
|
│ · 笔迹数据存储 │ │ · 海外用户服务 │
|
||||||
│ (大陆·ICP备案) │ │ (新加坡·按需上线) │
|
│ · AI 手写识别 │ │ · 算力 API 调用 │
|
||||||
│ 阿里云 / 腾讯云 │ │ 海外云服务器 │
|
│ · MQTT 实时通道 │ │ │
|
||||||
│ │ │ │
|
│ · OTA 固件升级 │ │ │
|
||||||
│ · 用户认证 │ │ · 海外用户数据 │
|
└───────────┬───────────┘ └───────────┬───────────┘
|
||||||
│ · 笔迹数据存储 │ │ · 独立合规存储 │
|
│ 数据读写 / 同步 │
|
||||||
│ · AI 手写识别 │ │ · 公共数据同步 │
|
└─────────────┬─────────────┘
|
||||||
│ · MQTT 实时通道 │ │ │
|
▼
|
||||||
│ · OTA 固件升级 │ └──────────────────────┘
|
┌─────────────────────────────┐
|
||||||
└───────────────────┘
|
│ 私有云数据源站 │
|
||||||
|
│ 118.141.37.23 │
|
||||||
|
│ · 核心数据存储 │
|
||||||
|
│ · 用户账户信息源 │
|
||||||
|
│ · 大容量存储 │
|
||||||
|
└─────────────────────────────┘
|
||||||
|
|
||||||
┌─────────────────────────────────┐
|
┌─────────────────────────────────┐
|
||||||
│ 企业邮件(@yink.ai 统一域名) │
|
│ 企业邮件(@yink.ai 统一域名) │
|
||||||
│ MX → 腾讯企业邮箱 / CF Routing │
|
│ MX → 腾讯企业邮箱 │
|
||||||
│ SPF + DKIM + DMARC 全配置 │
|
│ SPF + DKIM + DMARC 全配置 │
|
||||||
└─────────────────────────────────┘
|
└─────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -345,13 +518,13 @@ server {
|
|||||||
|
|
||||||
| 阶段 | 任务 | 预计周期 |
|
| 阶段 | 任务 | 预计周期 |
|
||||||
|------|------|----------|
|
|------|------|----------|
|
||||||
| **第一阶段** | writech.ai + yink.ai 域名托管至 Cloudflare,DNS 全面配置 | 第 1 周 |
|
| **第一阶段** | yink.ai / writech.ai DNS 在阿里云配置,writech.cn DNS 在腾讯云 DNSPod 配置 | 第 1 周 |
|
||||||
| **第一阶段** | 香港源站服务器搭建,静态首页上线 | 第 1-2 周 |
|
| **第一阶段** | 阿里云新加坡服务器搭建,静态首页上线 | 第 1-2 周 |
|
||||||
| **第一阶段** | writech.cn ICP 备案(若未完成),大陆 API 服务器上线 | 同步进行 |
|
| **第一阶段** | writech.cn ICP 备案已完成,腾讯云广州 API 服务器上线 | 同步进行 |
|
||||||
| **第一阶段** | 企业邮箱开通(腾讯企业邮箱),SPF / DKIM / DMARC 配置,分配员工邮箱 | 第 1 周 |
|
| **第一阶段** | 企业邮箱开通(腾讯企业邮箱),SPF / DKIM / DMARC 配置,分配员工邮箱 | 第 1 周 |
|
||||||
| **第二阶段** | 大陆 APP / SDK / 固件 API BaseURL 统一切换至 `api.writech.cn` | 第 3-6 周 |
|
| **第二阶段** | 大陆 APP / SDK / 固件 API BaseURL 统一切换至 `api.writech.cn` | 第 3-6 周 |
|
||||||
| **第二阶段** | 大陆 API 网关配置 CORS,允许 yink.ai / writech.ai 前端跨域调用 | 同步 |
|
| **第二阶段** | 大陆 API 网关配置 CORS,允许 yink.ai / writech.ai 前端跨域调用 | 同步 |
|
||||||
| **第二阶段** | Cloudflare Worker 实现 `/geo` 地区检测接口 | 第 4 周 |
|
| **第二阶段** | 阿里云 CDN 边缘脚本实现地区检测与智能路由 | 第 4 周 |
|
||||||
| **第三阶段** | 海外 API 节点上线(新加坡),前端智能路由切换 | 按业务需求 |
|
| **第三阶段** | 海外 API 节点上线(新加坡),前端智能路由切换 | 按业务需求 |
|
||||||
| **第三阶段** | 数据合规审查,确认海外数据不跨境传输 | 配套进行 |
|
| **第三阶段** | 数据合规审查,确认海外数据不跨境传输 | 配套进行 |
|
||||||
|
|
||||||
@@ -359,9 +532,9 @@ server {
|
|||||||
|
|
||||||
## 七、关键注意事项
|
## 七、关键注意事项
|
||||||
|
|
||||||
1. **ICP 备案是底线**:writech.cn 必须完成 ICP 备案才能在大陆正常提供服务,备案期间(约 20 个工作日)可先用香港服务器临时承载
|
1. **ICP 备案已完成**:writech.cn 已在腾讯云完成 ICP 备案,大陆数据服务正常运行
|
||||||
2. **yink.ai 首页内容合规**:首页面向全球,避免涉及敏感词汇,确保大陆用户可正常访问
|
2. **yink.ai 首页内容合规**:首页面向全球,避免涉及敏感词汇,确保大陆用户可正常访问
|
||||||
3. **数据主权**:大陆用户产生的数据必须存储于 writech.cn 大陆服务器,不得将用户数据同步至香港或海外节点,符合《数据安全法》和《个人信息保护法》
|
3. **数据主权**:大陆用户产生的数据必须存储于 writech.cn 大陆服务器,不得将用户数据同步至香港或海外节点,符合《数据安全法》和《个人信息保护法》
|
||||||
4. **邮件发件域名一致性**:所有系统通知邮件(注册验证码、订单确认等)的发件地址统一使用 `noreply@yink.ai`,避免用 writech.cn 发信造成品牌形象分裂
|
4. **邮件发件域名一致性**:所有系统通知邮件(注册验证码、订单确认等)的发件地址统一使用 `noreply@yink.ai`,避免用 writech.cn 发信造成品牌形象分裂
|
||||||
5. **HTTPS 全站强制**:yink.ai、writech.ai 和 writech.cn 所有端点必须强制 HTTPS,Cloudflare 可免费提供 TLS 证书
|
5. **HTTPS 全站强制**:yink.ai、writech.ai 和 writech.cn 所有端点必须强制 HTTPS,通过 ZeroSSL 统一签发免费 TLS 证书
|
||||||
6. **writech.ai → yink.ai 301 跳转**:writech.ai 所有路径统一 301 永久跳转至 yink.ai 对应路径,集中 SEO 权重;确保历史链接、搜索引擎索引不失效
|
6. **writech.ai → yink.ai 301 跳转**:writech.ai 所有路径统一 301 永久跳转至 yink.ai 对应路径,集中 SEO 权重;确保历史链接、搜索引擎索引不失效
|
||||||
|
|||||||
@@ -0,0 +1,694 @@
|
|||||||
|
# 技术支持与论坛 — 规划设计及实施方案
|
||||||
|
|
||||||
|
## 一、概述
|
||||||
|
|
||||||
|
### 1.1 目标
|
||||||
|
|
||||||
|
基于 [ICT 服务平台](ICT服务平台概要.md) 统一认证底座(OpenLDAP + Keycloak)和互联网应用服务器基础设施,构建**面向客户、经销商与合作伙伴的互动社区论坛平台**,覆盖技术支持、产品反馈、用户建议、营销互动的完整场景。论坛与 [文档生产及输出管理](文档生产及输出管理.md) 系统深度协同,共同构成企业对外知识服务与客户运营体系。
|
||||||
|
|
||||||
|
### 1.2 核心设计原则
|
||||||
|
|
||||||
|
- **全栈开源**:论坛引擎(Discourse)、LLM 推理(Ollama + Qwen2.5)、RAG 编排(LangChain)、向量检索(pgvector)、文本嵌入(bge-large-zh)全部采用开源方案,零 API 费用
|
||||||
|
- **认证复用**:登录用户接入 Keycloak SSO 免密码秘钥登录;游客免登录可浏览公开栏目
|
||||||
|
- **AI 驱动**:基于开源大模型本地部署,帖子自动分类、智能回复草稿生成、内容合规检测,人工审核后发布,数据全程不出企业服务器
|
||||||
|
- **主题订阅**:用户自主选择关注的主题,信息流仅展示已关注内容,类似微信群的「入群 / 退群」机制
|
||||||
|
- **积分激励**:通过积分奖励体系拉动社区活跃度与用户留存
|
||||||
|
- **管控有序**:分级审核机制,管理员可对不雅或不相关主题实施警告、冻结、关停
|
||||||
|
|
||||||
|
### 1.3 用户角色
|
||||||
|
|
||||||
|
论坛在 ICT 平台已有角色(游客 / 访客 / 读者 / 管理员)基础上定义论坛专属角色:
|
||||||
|
|
||||||
|
| 角色 | 说明 | 典型场景 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 游客 (Guest) | 免登录浏览公开栏目,不可发帖 | 搜索引擎入口、链接分享打开阅读 |
|
||||||
|
| 普通用户 (Member) | 注册并登录后参与论坛互动 | 发帖、跟帖、点赞、关注主题、积累积分 |
|
||||||
|
| 经销商 (Dealer) | 经过企业认证的经销商账号 | 创建专属主题、发布产品服务信息、管理自有主题 |
|
||||||
|
| 版主 (Moderator) | 被管理员任命管理特定栏目或主题 | 置顶、移帖、警告、关闭话题 |
|
||||||
|
| 客服 (Support) | 企业客服团队成员 | 审核 AI 回复草稿、人工解答、处理投诉 |
|
||||||
|
| 管理员 (Admin) | 论坛系统管理员 | 栏目管理、主题审批、用户封禁、积分规则配置 |
|
||||||
|
|
||||||
|
### 1.4 论坛层级结构
|
||||||
|
|
||||||
|
论坛内容采用四级层级组织,对应企业网站上的导航结构:
|
||||||
|
|
||||||
|
```
|
||||||
|
栏目 (Category) ─── 网站顶部导航,如"技术支持""吐槽""建议"
|
||||||
|
└─ 主题 (Theme) ─── 类似微信群的持续讨论空间,如"智能笔连接问题"
|
||||||
|
└─ 话题帖 (Topic) ─── 某个具体问题或讨论,如"BLE 连接超时怎么办"
|
||||||
|
└─ 跟帖 (Reply) ─── 对话题帖的回复,支持多级引用
|
||||||
|
```
|
||||||
|
|
||||||
|
- **栏目**是企业预设的固定分类,对应网站的一级导航栏目
|
||||||
|
- **主题**是栏目下的持续讨论空间,用户可关注或取消关注,类似加入或退出微信群
|
||||||
|
- **话题帖**是主题内的具体讨论,每个话题帖有独立 URL 可链接分享
|
||||||
|
- **跟帖**是话题帖内的交互回复,支持引用、@提及、Markdown 格式
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、系统架构
|
||||||
|
|
||||||
|
### 2.1 整体架构图
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 技术支持与论坛 - 系统架构
|
||||||
|
|
||||||
|
actor "游客" as Guest
|
||||||
|
actor "用户/经销商" as User
|
||||||
|
actor "客服/管理员" as Admin
|
||||||
|
|
||||||
|
node "互联网应用服务器\n(腾讯云/阿里云)" as AppServer {
|
||||||
|
component "Discourse\n论坛引擎" as Forum
|
||||||
|
component "ForumAI\nAI 回复服务" as AI
|
||||||
|
component "Keycloak\nSSO 认证" as KC
|
||||||
|
component "MsgHub\n消息中心" as MsgHub
|
||||||
|
component "Umami\n统计分析" as Analytics
|
||||||
|
component "Nginx + SSL" as Nginx
|
||||||
|
database "Redis\n缓存/会话" as Redis
|
||||||
|
}
|
||||||
|
|
||||||
|
node "私有云 [数据后端]" as PCloud {
|
||||||
|
database "PostgreSQL\nAI草稿/积分/审核" as DB
|
||||||
|
database "OpenLDAP\n用户目录" as LDAP
|
||||||
|
}
|
||||||
|
|
||||||
|
node "LLM 推理节点\n(Ollama + Qwen2.5)" as LLM
|
||||||
|
|
||||||
|
Guest -down-> Nginx : HTTPS 浏览
|
||||||
|
User -down-> Nginx : HTTPS 互动
|
||||||
|
Admin -down-> Nginx : 管理后台
|
||||||
|
|
||||||
|
Nginx -down-> Forum : 论坛请求
|
||||||
|
Nginx -down-> KC : 认证
|
||||||
|
Forum -right-> AI : Webhook\n新帖事件
|
||||||
|
AI -right-> LLM : 生成回复草稿
|
||||||
|
AI -down-> DB : 草稿/审核队列
|
||||||
|
AI -left-> Forum : API 发布回复
|
||||||
|
Forum -down-> MsgHub : 论坛通知
|
||||||
|
Forum -down-> Analytics : 访问埋点
|
||||||
|
Forum -down-> Redis : 会话/缓存
|
||||||
|
KC -down-> LDAP : 用户认证
|
||||||
|
MsgHub -down-> DB : 消息存储
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 核心组件清单
|
||||||
|
|
||||||
|
| 组件 | 开源方案 | 用途 | 许可证 |
|
||||||
|
|------|---------|------|--------|
|
||||||
|
| 论坛引擎 | **Discourse** | 帖子发布、主题管理、搜索、信任等级 | GPL v2 |
|
||||||
|
| AI 回复服务 | **ForumAI**(Node.js + LangChain) | 帖子分析、回复草稿生成、FAQ 匹配、RAG 检索 | MIT (LangChain) |
|
||||||
|
| LLM 本地推理 | **Ollama** + **Qwen2.5** | 中文理解、回复生成、情感分析,全部本地部署 | MIT / Apache 2.0 |
|
||||||
|
| 文本嵌入 | **bge-large-zh-v1.5**(BAAI) | 中文 Embedding,FAQ 语义匹配 | MIT |
|
||||||
|
| 向量存储 | **pgvector**(PostgreSQL 扩展) | FAQ 向量索引与余弦相似度检索 | PostgreSQL |
|
||||||
|
| 认证中心 | **Keycloak**(已有) | OIDC SSO 统一登录 | Apache 2.0 |
|
||||||
|
| 消息推送 | **MsgHub**(已有) | 论坛事件实时通知 | — |
|
||||||
|
| 统计分析 | **Umami**(已有) | 论坛页面访问与互动数据 | MIT |
|
||||||
|
| 缓存 | **Redis**(已有) | 会话管理、积分缓存、限流 | BSD |
|
||||||
|
| 数据存储 | **PostgreSQL**(已有) | ForumAI 草稿、积分记录、审核日志 | PostgreSQL |
|
||||||
|
| 反向代理 | **Nginx**(已有) | SSL 终止、路由分发 | BSD |
|
||||||
|
|
||||||
|
> **全栈开源**:上述所有组件均为开源方案,LLM 推理通过 Ollama 本地部署 Qwen2.5 模型,无需依赖任何付费 API,数据全程不出企业服务器。Discourse Docker 镜像内含独立的 PostgreSQL 和 Redis,ForumAI 使用平台共享的 PostgreSQL + pgvector 存储 AI 草稿、积分和向量数据。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、论坛栏目与主题体系
|
||||||
|
|
||||||
|
### 3.1 预设栏目
|
||||||
|
|
||||||
|
企业网站上的论坛以栏目形式呈现,每个栏目是一个独立的一级导航入口:
|
||||||
|
|
||||||
|
| 栏目 | URL 标识 | 访问级别 | 说明 |
|
||||||
|
|------|---------|---------|------|
|
||||||
|
| **技术支持** | `technical-support` | public | 产品使用问题、故障排查、技术咨询,AI 优先回复 |
|
||||||
|
| **产品反馈** | `product-feedback` | public | 用户吐槽、使用体验、Bug 报告 |
|
||||||
|
| **建议与需求** | `suggestions` | public | 功能建议、需求提案,支持投票表决 |
|
||||||
|
| **公告** | `announcements` | public | 企业官方公告、版本发布、活动通知(仅管理员可发帖) |
|
||||||
|
| **经销商专区** | `dealer-zone` | login | 经销商专属讨论,需认证后可见 |
|
||||||
|
| **自由讨论** | `general` | login | 注册用户自由交流 |
|
||||||
|
|
||||||
|
### 3.2 主题定义与管理
|
||||||
|
|
||||||
|
每个栏目下包含多个**主题(Theme)**,主题是围绕特定产品、功能或客户群体的持续讨论空间:
|
||||||
|
|
||||||
|
| 属性 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 名称 | 主题的显示名称 | "Qink 智能笔使用交流" |
|
||||||
|
| 标识 | URL 友好的英文标识 | `qink-smart-pen` |
|
||||||
|
| 所属栏目 | 挂载在哪个栏目下 | 技术支持 |
|
||||||
|
| 创建者 | 企业预设 / 用户申请 / 经销商自建 | admin / dealer-001 |
|
||||||
|
| 描述 | 主题简介,显示在主题列表 | "关于 Qink 智能笔的连接、使用、固件问题" |
|
||||||
|
| 图标 | 主题头像或 Logo | 产品图片 |
|
||||||
|
| 状态 | 正常 / 警告中 / 已停止 / 已归档 | 正常 |
|
||||||
|
| 关注人数 | 当前关注该主题的用户数 | 1,234 |
|
||||||
|
|
||||||
|
**预设主题示例**:
|
||||||
|
|
||||||
|
| 栏目 | 主题 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 技术支持 | 智能笔连接问题 | BLE 配对、固件升级、连接不稳定 |
|
||||||
|
| 技术支持 | 大屏显示与同步 | 笔迹同步延迟、画面适配、多设备场景 |
|
||||||
|
| 技术支持 | 手写识别与 OCR | 识别准确率、语言支持、特殊字符 |
|
||||||
|
| 产品反馈 | Qink 使用体验 | Qink 系列产品的综合体验反馈 |
|
||||||
|
| 产品反馈 | iTone 音质讨论 | iTone 系列音频产品体验 |
|
||||||
|
| 建议与需求 | 功能投票箱 | 用户对新功能的提案与投票 |
|
||||||
|
|
||||||
|
### 3.3 用户与经销商自建主题
|
||||||
|
|
||||||
|
普通用户和经销商可申请创建自己的主题,系统提供完整支撑:
|
||||||
|
|
||||||
|
#### 创建流程
|
||||||
|
|
||||||
|
```
|
||||||
|
用户/经销商提交"创建主题"申请
|
||||||
|
│
|
||||||
|
├─ 填写:主题名称、所属栏目、描述、创建理由
|
||||||
|
│
|
||||||
|
├─ 系统自动检查:
|
||||||
|
│ ├─ 名称是否与已有主题重复
|
||||||
|
│ ├─ 内容是否包含违禁词
|
||||||
|
│ └─ 用户信任等级是否满足要求
|
||||||
|
│
|
||||||
|
├─ 经销商账号 → 自动通过(免审核)
|
||||||
|
│
|
||||||
|
└─ 普通用户 → 进入管理员审核队列
|
||||||
|
├─ 审核通过 → 主题创建,申请者自动成为该主题版主
|
||||||
|
└─ 审核拒绝 → 通知申请者并说明原因
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 自建主题权限
|
||||||
|
|
||||||
|
| 角色 | 创建主题 | 免审核 | 管理自有主题 | 删除自有主题 |
|
||||||
|
|------|---------|--------|------------|------------|
|
||||||
|
| 普通用户(等级 3+) | 可申请 | 否 | 可(版主权限) | 需管理员确认 |
|
||||||
|
| 经销商 | 可直接创建 | 是 | 可(版主权限) | 可 |
|
||||||
|
| 管理员 | 可直接创建 | 是 | 全部主题 | 可 |
|
||||||
|
|
||||||
|
### 3.4 主题关注与信息流
|
||||||
|
|
||||||
|
用户通过**关注(Follow)机制**管理自己可见的内容,类似微信群的加入与退出:
|
||||||
|
|
||||||
|
| 操作 | 效果 |
|
||||||
|
|------|------|
|
||||||
|
| 关注主题 | 该主题下的新话题帖出现在用户信息流中;新帖通知推送到消息中心 |
|
||||||
|
| 取消关注 | 该主题内容从信息流消失;停止该主题的消息推送 |
|
||||||
|
| 未关注 | 用户不会看到该主题下的任何内容(栏目页仍可看到主题列表) |
|
||||||
|
|
||||||
|
**信息流规则**:
|
||||||
|
|
||||||
|
- 论坛首页(个人信息流)仅展示**已关注主题**下的话题帖,按最新回复时间倒序排列
|
||||||
|
- 栏目页展示该栏目下**所有主题列表**(含未关注的),用户可浏览并决定是否关注
|
||||||
|
- 新注册用户自动关注企业预设的「推荐主题」(如技术支持 / 公告),后续可自行调整
|
||||||
|
- 每个主题卡片显示:主题名称、描述、关注人数、最新活跃时间、「关注 / 已关注」按钮
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、帖子交互与链接分享
|
||||||
|
|
||||||
|
### 4.1 帖子发布与跟帖
|
||||||
|
|
||||||
|
#### 发布话题帖
|
||||||
|
|
||||||
|
登录用户在已关注的主题内可发布话题帖:
|
||||||
|
|
||||||
|
| 字段 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 标题 | 话题帖标题,简洁描述问题或主题 |
|
||||||
|
| 正文 | 支持 Markdown 格式,可嵌入图片、代码块、表格 |
|
||||||
|
| 标签 | 可选,便于检索分类(如 `BLE` `固件` `Android`) |
|
||||||
|
| 附件 | 支持上传图片、日志文件(大小 / 类型受限) |
|
||||||
|
|
||||||
|
#### 跟帖(回复)
|
||||||
|
|
||||||
|
- 对话题帖的回复支持 Markdown 格式
|
||||||
|
- 支持**引用回复**(引用某条跟帖后回复)
|
||||||
|
- 支持 **@提及** 其他用户,触发专属通知
|
||||||
|
- 支持**点赞**,高赞回复自动置顶或标记为「有帮助」
|
||||||
|
- 帖子作者可将某条回复标记为**最佳回答**(技术支持栏目尤为重要)
|
||||||
|
|
||||||
|
### 4.2 链接分享体系
|
||||||
|
|
||||||
|
每个论坛页面均有独立的、可分享的 URL:
|
||||||
|
|
||||||
|
| 页面 | URL 格式 | 示例 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 论坛首页 | `https://forum.writech.cn/` | — |
|
||||||
|
| 栏目页 | `https://forum.writech.cn/c/{栏目标识}` | `forum.writech.cn/c/technical-support` |
|
||||||
|
| 主题页 | `https://forum.writech.cn/c/{栏目}/{主题}` | `forum.writech.cn/c/technical-support/qink-smart-pen` |
|
||||||
|
| 话题帖 | `https://forum.writech.cn/t/{标题slug}/{帖子ID}` | `forum.writech.cn/t/ble-timeout/456` |
|
||||||
|
| 特定跟帖 | `https://forum.writech.cn/t/{slug}/{ID}/{跟帖序号}` | `forum.writech.cn/t/ble-timeout/456/3` |
|
||||||
|
|
||||||
|
**分享能力**:
|
||||||
|
|
||||||
|
- 每个话题帖页面提供**分享按钮**,支持复制链接、生成二维码
|
||||||
|
- 分享链接携带渠道追踪参数(复用 PromoAPI 的 `ch` / `cmp` 参数体系)
|
||||||
|
- 链接在微信、浏览器等平台打开时展示完整的帖子内容
|
||||||
|
- 游客通过分享链接可直接阅读公开栏目下的帖子,无需登录
|
||||||
|
|
||||||
|
### 4.3 SEO 与社交分享优化
|
||||||
|
|
||||||
|
- Discourse 原生支持 SSR(服务端渲染),搜索引擎可抓取论坛内容
|
||||||
|
- 每个话题帖生成 Open Graph 元标签,分享到微信 / 微博时展示标题 + 摘要 + 缩略图
|
||||||
|
- 技术支持类帖子沉淀为**搜索引擎可索引的知识库**,持续引流
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、AI 辅助回复系统(ForumAI)
|
||||||
|
|
||||||
|
### 5.1 设计理念
|
||||||
|
|
||||||
|
ForumAI 是论坛的 AI 后端服务,核心目标是**降低客服团队工作量**,同时保证回复质量:
|
||||||
|
|
||||||
|
- **AI 先行**:每条新帖自动生成回复草稿,客服只需审核确认或微调
|
||||||
|
- **人工兜底**:AI 无法处理的复杂问题自动转交人工,确保每条帖子都有回应
|
||||||
|
- **知识积累**:FAQ 库随帖子积累不断丰富,AI 回复准确率持续提升
|
||||||
|
- **透明标记**:AI 回复标记「AI 助手」标签,用户知晓回复来源
|
||||||
|
|
||||||
|
### 5.2 工作流程
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title ForumAI 工作流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:用户发布话题帖或跟帖;
|
||||||
|
:Discourse Webhook 推送到 ForumAI;
|
||||||
|
|
||||||
|
:ForumAI 分析帖子内容;
|
||||||
|
note right
|
||||||
|
意图识别: 提问 / 反馈 / 建议 / 投诉
|
||||||
|
情感分析: 正面 / 中性 / 负面
|
||||||
|
关键词提取: 产品 / 功能 / 问题
|
||||||
|
end note
|
||||||
|
|
||||||
|
if (匹配 FAQ 知识库 ?) then (是)
|
||||||
|
:生成标准回复草稿;
|
||||||
|
note right: 附上 FAQ 文档链接
|
||||||
|
else (否)
|
||||||
|
:调用 LLM 生成回复草稿;
|
||||||
|
note right
|
||||||
|
Ollama + Qwen2.5 (本地部署)
|
||||||
|
LangChain RAG: 产品知识 + 帖子上下文
|
||||||
|
end note
|
||||||
|
endif
|
||||||
|
|
||||||
|
:草稿存入审核队列;
|
||||||
|
|
||||||
|
if (AI 置信度高且为常见问题 ?) then (是)
|
||||||
|
:自动发布回复;
|
||||||
|
note right: 标注 "AI 助手" 标签
|
||||||
|
else (否)
|
||||||
|
:推送到客服审核队列;
|
||||||
|
:客服查看/编辑草稿;
|
||||||
|
:客服确认发布;
|
||||||
|
endif
|
||||||
|
|
||||||
|
:回复发布到论坛;
|
||||||
|
:MsgHub 通知帖子作者;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 AI 能力矩阵
|
||||||
|
|
||||||
|
| 能力 | 说明 | 实现方式 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 意图识别 | 判断帖子是提问、反馈、建议还是投诉 | LLM 分类 + 规则引擎 |
|
||||||
|
| 情感分析 | 检测用户情绪(正面 / 中性 / 负面 / 愤怒) | LLM 情感评分 |
|
||||||
|
| FAQ 匹配 | 将帖子与已有 FAQ 知识库进行语义匹配 | bge-large-zh Embedding + pgvector 余弦相似度检索 |
|
||||||
|
| 回复生成 | 基于产品知识库和帖子上下文生成回复草稿 | LangChain RAG(Ollama + Qwen2.5 + pgvector) |
|
||||||
|
| 内容审核 | 检测帖子是否含不良内容、广告、违禁词 | Qwen2.5 审核 + 关键词过滤 |
|
||||||
|
| 智能分类 | 自动为帖子打标签、分配到合适的主题 | LLM 分类 |
|
||||||
|
| 优先级评估 | 根据情感和紧急程度评估帖子优先级 | 规则引擎 + LLM |
|
||||||
|
|
||||||
|
### 5.4 人工辅佐审核机制
|
||||||
|
|
||||||
|
客服团队通过**审核后台**管理 AI 生成的回复草稿:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────┐
|
||||||
|
│ ForumAI 审核后台 客服 │
|
||||||
|
├──────────────────────────────────────────────────┤
|
||||||
|
│ 待审核 (12) │ 已发布 (89) │ 已驳回 (3) │
|
||||||
|
├──────────────────────────────────────────────────┤
|
||||||
|
│ 🔴 [紧急] BLE 连接频繁断开 3分钟前 │
|
||||||
|
│ AI 草稿:建议重新配对,详见固件升级指南... │
|
||||||
|
│ 置信度:87% │ 意图:提问 │ 情感:负面 │
|
||||||
|
│ [✅ 发布] [✏️ 编辑后发布] [❌ 驳回] [👤 转人工] │
|
||||||
|
├──────────────────────────────────────────────────┤
|
||||||
|
│ 🟡 [一般] Qink 能否支持 Windows 手写输入 1小时前 │
|
||||||
|
│ AI 草稿:目前 Qink 主要支持 Android/iOS... │
|
||||||
|
│ 置信度:72% │ 意图:提问 │ 情感:中性 │
|
||||||
|
│ [✅ 发布] [✏️ 编辑后发布] [❌ 驳回] [👤 转人工] │
|
||||||
|
└──────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**审核流程规则**:
|
||||||
|
|
||||||
|
| 场景 | 处理方式 |
|
||||||
|
|------|---------|
|
||||||
|
| AI 置信度 > 90% 且为 FAQ 匹配 | 自动发布,标记「AI 助手」 |
|
||||||
|
| AI 置信度 70-90% | 进入客服审核队列,客服确认或修改后发布 |
|
||||||
|
| AI 置信度 < 70% | 标记「需人工回复」,客服从头撰写 |
|
||||||
|
| 情感为「愤怒」或「投诉」 | 无论置信度均进入人工处理,标记高优先级 |
|
||||||
|
|
||||||
|
### 5.5 技术实现
|
||||||
|
|
||||||
|
```
|
||||||
|
ForumAI (Node.js 服务,端口 3005)
|
||||||
|
├─ Express.js — HTTP 接收 Discourse Webhook (MIT)
|
||||||
|
├─ @discourseconnect — Discourse REST API 客户端
|
||||||
|
├─ LangChain.js — RAG 编排:串联 LLM + 向量检索 + Prompt (MIT)
|
||||||
|
├─ Ollama Client — 调用本地 Ollama 推理 Qwen2.5(HTTP localhost:11434)
|
||||||
|
├─ pg + pgvector — 草稿/审核写入 PostgreSQL,FAQ Embedding 向量检索
|
||||||
|
├─ ioredis — 限流、FAQ 缓存 (MIT)
|
||||||
|
└─ MsgHub Client — 审核通知推送
|
||||||
|
```
|
||||||
|
|
||||||
|
**FAQ 知识库管理**:
|
||||||
|
|
||||||
|
- FAQ 条目以 Markdown 存储于 Git 仓库,通过 DocForge 同步更新
|
||||||
|
- 每条 FAQ 通过 **bge-large-zh-v1.5**(BAAI 开源,MIT)生成 1024 维 Embedding 向量,存入 PostgreSQL(**pgvector** 扩展)
|
||||||
|
- 新帖到达时,ForumAI 通过 **LangChain RAG** 流程计算帖子 Embedding 并与 FAQ 库做余弦相似度检索
|
||||||
|
- 匹配度 > 0.85 视为 FAQ 命中,直接引用对应回复模板
|
||||||
|
- LLM 推理全部通过 **Ollama**(MIT)本地运行 **Qwen2.5**(Apache 2.0)模型,无需外部 API 依赖
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、积分奖励体系
|
||||||
|
|
||||||
|
### 6.1 积分获取规则
|
||||||
|
|
||||||
|
通过积分奖励拉动论坛活跃度,积分规则涵盖日常互动和内容贡献:
|
||||||
|
|
||||||
|
| 行为 | 积分 | 频次限制 | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| 每日首次登录 | +5 | 每日 1 次 | 连续签到额外奖励 |
|
||||||
|
| 发布话题帖 | +10 | 每日 5 帖 | 鼓励提问和分享 |
|
||||||
|
| 发表跟帖 | +3 | 每日 20 条 | 鼓励参与讨论 |
|
||||||
|
| 被点赞(每个赞) | +2 | 无限制 | 鼓励高质量回复 |
|
||||||
|
| 回复被标记为「最佳回答」 | +50 | 无限制 | 重奖有价值的回答 |
|
||||||
|
| 关注新主题 | +1 | 每日 3 次 | 鼓励探索更多主题 |
|
||||||
|
| 邀请新用户注册 | +30 | 每月 10 次 | 拉新奖励 |
|
||||||
|
| 连续签到 7 天 | +20 | 每周 1 次 | 额外奖励 |
|
||||||
|
| 连续签到 30 天 | +100 | 每月 1 次 | 月度奖励 |
|
||||||
|
| 举报违规内容(查实后) | +10 | 无限制 | 鼓励社区自治 |
|
||||||
|
|
||||||
|
### 6.2 用户等级体系
|
||||||
|
|
||||||
|
积分累计决定用户等级,不同等级解锁不同特权:
|
||||||
|
|
||||||
|
| 等级 | 名称 | 累计积分 | 特权 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| Lv.0 | 新手 | 0 | 浏览、跟帖(需审核) |
|
||||||
|
| Lv.1 | 活跃用户 | 50+ | 跟帖免审核、点赞 |
|
||||||
|
| Lv.2 | 贡献者 | 200+ | 发帖免审核、上传附件 |
|
||||||
|
| Lv.3 | 达人 | 500+ | 申请创建主题、编辑自己的帖子标签 |
|
||||||
|
| Lv.4 | 专家 | 2000+ | 编辑他人帖子标签、参与社区管理投票 |
|
||||||
|
| Lv.5 | 社区大使 | 5000+ | 自建主题免审核、推荐至首页热门 |
|
||||||
|
|
||||||
|
### 6.3 积分兑换
|
||||||
|
|
||||||
|
积分可用于兑换企业提供的奖励:
|
||||||
|
|
||||||
|
| 兑换项目 | 所需积分 | 说明 |
|
||||||
|
|---------|---------|------|
|
||||||
|
| 品牌周边(贴纸、明信片) | 100 | 邮寄至用户地址 |
|
||||||
|
| 产品优惠券(满减 / 折扣) | 300 | 在官网或经销商处使用 |
|
||||||
|
| 新品试用资格 | 500 | 优先体验未发布产品 |
|
||||||
|
| 专属客服通道 | 1000 | 一对一技术支持 |
|
||||||
|
| 年度社区贡献者荣誉 | — | 年底评选,非积分兑换 |
|
||||||
|
|
||||||
|
### 6.4 营销活动积分
|
||||||
|
|
||||||
|
管理员可配置**限时积分活动**以拉动特定时段的社区活跃度:
|
||||||
|
|
||||||
|
| 活动类型 | 示例 | 积分规则 |
|
||||||
|
|---------|------|---------|
|
||||||
|
| 签到翻倍周 | 每年特定周 | 所有签到积分 x2 |
|
||||||
|
| 话题悬赏 | "分享你的智能笔使用场景" | 参与发帖 +30,最佳帖 +200 |
|
||||||
|
| 邀新冲刺 | 月度邀新活动 | 邀请积分 x3,邀新排行额外奖励 |
|
||||||
|
| 节日专题 | 教师节、开学季 | 特定话题帖积分加成 |
|
||||||
|
|
||||||
|
积分核心逻辑基于 Discourse 开源插件 **discourse-gamification**(MIT)实现用户等级和徽章展示,ForumAI 负责自定义积分规则计算和营销活动积分加成。活动规则通过管理后台配置,ForumAI 自动识别活动期间的帖子并按活动规则计算积分。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、内容审核与管控
|
||||||
|
|
||||||
|
### 7.1 三级审核机制
|
||||||
|
|
||||||
|
论坛内容审核采用 AI 自动审核 + 版主审核 + 管理员终审的三级机制:
|
||||||
|
|
||||||
|
| 审核级别 | 执行者 | 处理内容 | 响应时间 |
|
||||||
|
|---------|--------|---------|---------|
|
||||||
|
| **一级:AI 自动审核** | ForumAI | 新帖/跟帖自动扫描:违禁词、广告、不良内容、灌水 | 即时(< 3 秒) |
|
||||||
|
| **二级:版主审核** | 版主 | AI 标记为可疑的内容、用户举报的内容 | < 30 分钟 |
|
||||||
|
| **三级:管理员终审** | 管理员 | 主题创建审批、用户封禁、重大争议裁决 | < 24 小时 |
|
||||||
|
|
||||||
|
### 7.2 管理员操作工具
|
||||||
|
|
||||||
|
管理员和版主可对帖子和主题执行以下操作:
|
||||||
|
|
||||||
|
| 操作 | 适用对象 | 说明 |
|
||||||
|
|------|---------|------|
|
||||||
|
| **置顶** | 话题帖 | 在主题内或栏目内置顶显示 |
|
||||||
|
| **锁定** | 话题帖 | 禁止新跟帖,保留可阅读 |
|
||||||
|
| **移动** | 话题帖 | 将帖子移至更合适的主题或栏目 |
|
||||||
|
| **合并** | 话题帖 | 将重复的帖子合并为一个 |
|
||||||
|
| **隐藏** | 帖子/跟帖 | 从公开视图隐藏,仅管理员可见 |
|
||||||
|
| **删除** | 帖子/跟帖 | 永久删除内容(需三级管理员确认) |
|
||||||
|
| **警告** | 用户 | 向用户发送违规警告通知,记录在案 |
|
||||||
|
| **禁言** | 用户 | 暂时禁止用户发帖和跟帖(可设期限) |
|
||||||
|
| **封禁** | 用户 | 永久禁止用户访问论坛 |
|
||||||
|
|
||||||
|
### 7.3 AI 自动审核
|
||||||
|
|
||||||
|
ForumAI 对每条新发布的帖子和跟帖执行自动审核:
|
||||||
|
|
||||||
|
| 检测项 | 检测方式 | 处理动作 |
|
||||||
|
|--------|---------|---------|
|
||||||
|
| 违禁词 | 关键词词典匹配 | 拦截,进入版主审核队列 |
|
||||||
|
| 广告推销 | LLM 分类 + URL 检测 | 拦截,标记为疑似广告 |
|
||||||
|
| 人身攻击 / 不雅内容 | LLM 毒性检测 | 拦截,自动隐藏 + 通知版主 |
|
||||||
|
| 灌水 / 重复发帖 | 频率检测 + 内容相似度 | 限流,超过阈值自动拦截 |
|
||||||
|
| 敏感信息 | 正则匹配(手机号、身份证等) | 自动打码,提醒用户修改 |
|
||||||
|
|
||||||
|
### 7.4 主题状态管理
|
||||||
|
|
||||||
|
主题具有完整的生命周期,管理员可根据主题表现进行状态管控:
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 主题状态管理
|
||||||
|
|
||||||
|
state "申请中" as Pending
|
||||||
|
state "正常" as Active
|
||||||
|
state "警告中" as Warning
|
||||||
|
state "已停止" as Stopped
|
||||||
|
state "已归档" as Archived
|
||||||
|
state "已拒绝" as Rejected
|
||||||
|
|
||||||
|
[*] --> Pending : 用户/经销商提交申请
|
||||||
|
[*] --> Active : 管理员直接创建
|
||||||
|
|
||||||
|
Pending --> Active : 管理员审核通过
|
||||||
|
Pending --> Rejected : 管理员拒绝
|
||||||
|
|
||||||
|
Active --> Warning : 管理员发出警告\n(内容不当/偏离主题)
|
||||||
|
Warning --> Active : 整改通过
|
||||||
|
Warning --> Stopped : 未整改或再次违规
|
||||||
|
|
||||||
|
Active --> Stopped : 严重违规直接停止
|
||||||
|
Stopped --> Active : 管理员解除停止
|
||||||
|
|
||||||
|
Active --> Archived : 长期不活跃\n或管理员手动归档
|
||||||
|
Archived --> Active : 管理员重新激活
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
**各状态说明**:
|
||||||
|
|
||||||
|
| 状态 | 对用户的表现 | 可执行操作 |
|
||||||
|
|------|------------|----------|
|
||||||
|
| 申请中 | 仅申请者可见,显示"审核中" | 等待管理员审批 |
|
||||||
|
| 正常 | 正常显示和互动 | 发帖、跟帖、关注 |
|
||||||
|
| 警告中 | 主题顶部显示黄色警告条,提示整改内容 | 可继续互动,但新帖需审核 |
|
||||||
|
| 已停止 | 主题页显示"该主题已被管理员停止",禁止新帖 | 仅可阅读历史内容 |
|
||||||
|
| 已归档 | 主题页显示"已归档",禁止新帖 | 仅可阅读历史内容 |
|
||||||
|
| 已拒绝 | 仅申请者收到拒绝通知 | 可修改后重新申请 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、权限与访问控制
|
||||||
|
|
||||||
|
### 8.1 论坛访问级别
|
||||||
|
|
||||||
|
论坛栏目的访问控制复用文档系统的权限模型:
|
||||||
|
|
||||||
|
| 级别 | 标识 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| **公开** | `public` | 游客可浏览帖子内容,登录后方可发帖和跟帖 |
|
||||||
|
| **需登录** | `login` | 仅登录用户可浏览和互动(如经销商专区) |
|
||||||
|
| **受限** | `restricted` | 仅特定用户组可访问(如内部测试反馈栏目) |
|
||||||
|
|
||||||
|
### 8.2 论坛权限矩阵
|
||||||
|
|
||||||
|
| 操作 | 游客 | 普通用户 | 经销商 | 版主 | 客服 | 管理员 |
|
||||||
|
|------|------|---------|--------|------|------|--------|
|
||||||
|
| 浏览公开栏目 | 可 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 浏览 login 栏目 | 否 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 发布话题帖 | 否 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 发表跟帖 | 否 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 点赞 | 否 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 关注主题 | 否 | 可 | 可 | 可 | 可 | 可 |
|
||||||
|
| 创建主题 | 否 | Lv.3+ 申请 | 直接创建 | 否 | 否 | 直接创建 |
|
||||||
|
| 标记最佳回答 | 否 | 仅自己帖子 | 仅自己帖子 | 可 | 可 | 可 |
|
||||||
|
| 审核帖子 | 否 | 否 | 否 | 所辖主题 | 所有 | 所有 |
|
||||||
|
| 管理主题状态 | 否 | 否 | 自有主题 | 所辖主题 | 否 | 所有 |
|
||||||
|
| 封禁用户 | 否 | 否 | 否 | 否 | 否 | 可 |
|
||||||
|
| AI 审核后台 | 否 | 否 | 否 | 否 | 可 | 可 |
|
||||||
|
|
||||||
|
### 8.3 与认证底座的关系
|
||||||
|
|
||||||
|
| 层次 | 组件 | 职责 |
|
||||||
|
|------|------|------|
|
||||||
|
| 身份源 | OpenLDAP(私有云) | 用户账户、组织架构、角色 |
|
||||||
|
| 认证中心 | Keycloak(互联网服务器) | SSO 登录,签发 OIDC Token |
|
||||||
|
| 论坛认证 | Discourse SSO 对接 | 通过 Keycloak OIDC 实现单点登录 |
|
||||||
|
| 角色映射 | ForumAI 配置 | Keycloak 角色组映射到论坛角色(Member / Dealer / Support / Admin) |
|
||||||
|
| 匿名访问 | Discourse 公开分类 | 游客无需登录即可浏览 public 级别栏目 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、消息通知与 MsgHub 集成
|
||||||
|
|
||||||
|
### 9.1 论坛事件接入 MsgHub
|
||||||
|
|
||||||
|
论坛产生的事件通过 Discourse Webhook 接入 MsgHub 消息中心,与文档系统的消息统一展示:
|
||||||
|
|
||||||
|
```
|
||||||
|
Discourse 论坛事件
|
||||||
|
│
|
||||||
|
├─ Webhook → ForumAI → MsgHub
|
||||||
|
│
|
||||||
|
└─ MsgHub 统一推送到用户消息中心
|
||||||
|
├─ WebSocket 实时推送(在线用户)
|
||||||
|
└─ 未读消息存储(离线用户)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 论坛消息类型
|
||||||
|
|
||||||
|
| 消息类型 | 触发条件 | 消息内容 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| 新回复 | 关注的话题帖收到新跟帖 | "{用户}回复了你关注的《{帖子标题}》" |
|
||||||
|
| @提及 | 帖子或跟帖中 @了你 | "{用户}在《{帖子标题}》中提到了你" |
|
||||||
|
| 最佳回答 | 你的回复被标记为最佳回答 | "你在《{帖子标题}》中的回复被选为最佳回答 (+50积分)" |
|
||||||
|
| AI 回复已发布 | 客服确认发布了 AI 回复 | "你的帖子《{标题}》已收到官方回复" |
|
||||||
|
| 主题动态 | 关注的主题有新话题帖 | "【{主题名}】有新话题:{帖子标题}" |
|
||||||
|
| 主题审批 | 你申请的主题被审批 | "你申请的主题「{名称}」已通过审核" |
|
||||||
|
| 警告通知 | 管理员对你发出警告 | "你的帖子《{标题}》收到管理员警告" |
|
||||||
|
| 积分变动 | 积分增加或兑换 | "恭喜获得 50 积分(最佳回答奖励)" |
|
||||||
|
| 等级提升 | 用户等级提升 | "恭喜升级为 Lv.3 达人!解锁「创建主题」特权" |
|
||||||
|
|
||||||
|
### 9.3 通知策略
|
||||||
|
|
||||||
|
| 策略 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 即时推送 | @提及、最佳回答、警告通知、等级提升 |
|
||||||
|
| 聚合推送 | 新回复、主题动态(同一主题 5 分钟内聚合为一条) |
|
||||||
|
| 静默 | 用户可设置单个主题为「免打扰」,仅 @提及 时通知 |
|
||||||
|
| 摘要邮件 | 每日 / 每周发送论坛摘要邮件到用户邮箱(可选开启) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、部署方案
|
||||||
|
|
||||||
|
### 10.1 服务部署清单
|
||||||
|
|
||||||
|
论坛相关服务在已有 ICT 平台基础上新增以下组件:
|
||||||
|
|
||||||
|
| 服务 | 部署方式 | 运行位置 | 端口 | 说明 |
|
||||||
|
|------|---------|---------|------|------|
|
||||||
|
| **Discourse 论坛引擎** | Docker (官方镜像) | 互联网应用服务器 | 4000 | 含内置 PostgreSQL + Redis + Sidekiq |
|
||||||
|
| **Ollama LLM 推理** | Docker (GPU 可选) | 互联网应用服务器 | 11434 | 本地运行 Qwen2.5 开源大模型 |
|
||||||
|
| **ForumAI 服务** | Docker (Node.js) | 互联网应用服务器 | 3005 | LangChain RAG + 积分 + 审核 |
|
||||||
|
| PostgreSQL(已有) | 原生安装 | 私有云 | 5432 | ForumAI 草稿/积分/审核日志 |
|
||||||
|
| Redis(已有) | Docker | 互联网应用服务器 | 6379 | ForumAI 限流/缓存 |
|
||||||
|
| MsgHub(已有) | Docker | 互联网应用服务器 | 3003 | 论坛消息通知 |
|
||||||
|
| Keycloak(已有) | Docker | 互联网应用服务器 | 8443 | SSO 认证 |
|
||||||
|
| Nginx(已有) | 原生 | 互联网应用服务器 | 443 | 反向代理 |
|
||||||
|
|
||||||
|
### 10.2 Nginx 路由规则
|
||||||
|
|
||||||
|
在现有 Nginx 配置中新增论坛相关路由:
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# Discourse 论坛(独立子域名)
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name forum.writech.cn;
|
||||||
|
|
||||||
|
ssl_certificate /etc/ssl/certs/writech_cn.pem;
|
||||||
|
ssl_certificate_key /etc/ssl/private/writech_cn.key;
|
||||||
|
|
||||||
|
# 论坛所有请求代理到 Discourse
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:4000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket 支持(Discourse MessageBus)
|
||||||
|
location /message-bus/ {
|
||||||
|
proxy_pass http://127.0.0.1:4000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ForumAI 服务(内部调用 + Discourse Webhook)
|
||||||
|
# 在主站 server 块中添加:
|
||||||
|
location /api/forum-ai/ {
|
||||||
|
proxy_pass http://127.0.0.1:3005;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.3 DNS 配置
|
||||||
|
|
||||||
|
在腾讯云 DNSPod 中新增 `forum.writech.cn` 子域名记录:
|
||||||
|
|
||||||
|
| 记录 | 类型 | 指向 | DNS 平台 | 用途 |
|
||||||
|
|------|------|------|---------|------|
|
||||||
|
| forum.writech.cn | A | 腾讯云广州服务器 | 腾讯云 DNSPod | 论坛子域名 |
|
||||||
|
|
||||||
|
> 通配符 SSL 证书(`*.writech.cn`)已覆盖 `forum.writech.cn`,无需额外证书。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、实施路线图
|
||||||
|
|
||||||
|
| 阶段 | 任务 | 预计周期 |
|
||||||
|
|------|------|--------|
|
||||||
|
| **第一阶段:基础** | Discourse Docker 部署、Keycloak SSO 对接 | 第 1-2 周 |
|
||||||
|
| **第一阶段** | 预设栏目和主题创建、Nginx 路由配置 | 第 2 周 |
|
||||||
|
| **第一阶段** | 基础 UI 定制(品牌配色、Logo、导航栏集成) | 第 2-3 周 |
|
||||||
|
| **第二阶段:互动** | 主题关注与信息流功能开发 | 第 4 周 |
|
||||||
|
| **第二阶段** | 用户/经销商自建主题审批流程开发 | 第 4-5 周 |
|
||||||
|
| **第二阶段** | MsgHub 集成(论坛事件 Webhook → 消息中心) | 第 5 周 |
|
||||||
|
| **第三阶段:智能** | Ollama + Qwen2.5 本地部署、bge-large-zh 嵌入模型部署 | 第 6 周 |
|
||||||
|
| **第三阶段** | ForumAI 服务开发(Webhook + LangChain RAG 编排 + pgvector) | 第 6-7 周 |
|
||||||
|
| **第三阶段** | FAQ 知识库构建与向量检索集成 | 第 7-8 周 |
|
||||||
|
| **第三阶段** | AI 审核后台开发(客服审核队列 + 草稿管理) | 第 8-9 周 |
|
||||||
|
| **第四阶段:运营** | 积分奖励体系开发(积分规则 + 等级 + 兑换) | 第 10-11 周 |
|
||||||
|
| **第四阶段** | 内容审核与管控工具(AI 审核 + 管理员操作) | 第 11 周 |
|
||||||
|
| **第四阶段** | 营销活动积分模块 + 运营看板 | 第 12 周 |
|
||||||
|
| **第五阶段:优化** | SEO 优化、Open Graph 社交分享、链接分享体系完善 | 第 13 周 |
|
||||||
|
| **第五阶段** | 全链路测试、性能调优、上线 | 第 13-14 周 |
|
||||||
@@ -0,0 +1,959 @@
|
|||||||
|
# 文档生产及输出管理 — 规划设计及实施方案
|
||||||
|
|
||||||
|
## 一、概述
|
||||||
|
|
||||||
|
### 1.1 目标
|
||||||
|
|
||||||
|
基于 [ICT 服务平台](ICT服务平台概要.md) 的统一认证底座(OpenLDAP + Keycloak)和 Git 基础设施(Gitea),构建**从 Markdown 编写到浏览器阅读、反馈、统计分析**的全链路文档管理平台,覆盖文档生产、发布、阅读、协作、运营的完整生命周期。
|
||||||
|
|
||||||
|
### 1.2 核心设计原则
|
||||||
|
|
||||||
|
- **Git 为唯一真实源**:所有文档以 Markdown 格式存储于 Git 仓库,浏览器端为只读渲染视图
|
||||||
|
- **开源优先**:核心组件全部采用成熟开源方案,降低成本与锁定风险
|
||||||
|
- **认证复用**:登录用户接入 ICT 平台 Keycloak SSO 免密码秘钥登录;游客与访客免登录,通过浏览器指纹追踪
|
||||||
|
- **自动化驱动**:Git 推送即触发渲染、发布、同步,零人工干预
|
||||||
|
|
||||||
|
### 1.3 用户角色
|
||||||
|
|
||||||
|
| 角色 | 说明 | 典型场景 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 作者 (Author) | 拥有 Git 仓库写权限的员工 | VS Code / Qoder 编写 Markdown 并推送 |
|
||||||
|
| 审阅者 (Reviewer) | 受邀阅读并点评文档的内部/外部人员 | 浏览器阅读、点评、反馈 |
|
||||||
|
| 读者 (Reader) | 通过 Keycloak 登录后访问文档的注册用户 | 登录后阅读 `login` / `restricted` 级别文档 |
|
||||||
|
| 游客 (Guest) | 免登录访问公开文档的匿名用户 | 通过 URL 自由阅读 `public` 级别文档,可匿名评论 |
|
||||||
|
| 访客 (Visitor) | 免登录仅限一次阅读的匿名用户 | 首次打开 `public_once` 级别文档可阅读,再次访问需登录 |
|
||||||
|
| 管理员 (Admin) | 管理发布策略、权限、生命周期的 IT 人员 | 配置发布规则与权限策略 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、系统架构
|
||||||
|
|
||||||
|
### 2.1 整体架构图
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 文档生产及输出管理 — 系统架构
|
||||||
|
|
||||||
|
actor "作者" as Author
|
||||||
|
actor "游客/访客/读者" as Reader
|
||||||
|
|
||||||
|
node "VS Code + Qoder" as VSCode
|
||||||
|
|
||||||
|
node "互联网应用服务器 (腾讯云/阿里云)" as AppServer {
|
||||||
|
component "Nginx + SSL" as Nginx
|
||||||
|
component "Keycloak SSO" as KC
|
||||||
|
|
||||||
|
package "文档生产" {
|
||||||
|
component "Gitea" as Gitea
|
||||||
|
component "DocForge" as Forge
|
||||||
|
}
|
||||||
|
|
||||||
|
package "文档阅读" {
|
||||||
|
component "DocPortal" as Portal
|
||||||
|
component "MeiliSearch" as Search
|
||||||
|
}
|
||||||
|
|
||||||
|
package "协作与运营" {
|
||||||
|
component "Remark42" as Comment
|
||||||
|
component "Umami" as Analytics
|
||||||
|
component "MsgHub" as MsgHub
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node "私有云 [数据后端]" as PCloud {
|
||||||
|
database "PostgreSQL" as DB
|
||||||
|
database "OpenLDAP" as LDAP
|
||||||
|
storage "Git 仓库存储" as Store
|
||||||
|
}
|
||||||
|
|
||||||
|
node "目标域名网站" as Sites {
|
||||||
|
component "yink.ai" as SiteA
|
||||||
|
component "docs.writech.cn" as SiteB
|
||||||
|
}
|
||||||
|
|
||||||
|
' == 作者流 ==
|
||||||
|
Author -down-> VSCode : Markdown 编写
|
||||||
|
VSCode -down-> Gitea : git push (SSH)
|
||||||
|
Gitea -down-> Store : 仓库数据
|
||||||
|
|
||||||
|
' == 渲染发布 ==
|
||||||
|
Gitea -right-> Forge : Webhook
|
||||||
|
Forge -right-> Portal : HTML + 摘要
|
||||||
|
Forge -down-> DB : 元数据入库
|
||||||
|
Forge ..> Sites : 自动部署
|
||||||
|
|
||||||
|
' == 读者流 ==
|
||||||
|
Reader -down-> Nginx : HTTPS
|
||||||
|
Nginx --> KC : 认证
|
||||||
|
Nginx --> Portal : 文档路由
|
||||||
|
|
||||||
|
' == 阅读交互 ==
|
||||||
|
Portal --> Comment : 评论
|
||||||
|
Portal --> Analytics : 访问记录
|
||||||
|
Portal --> Search : 搜索
|
||||||
|
|
||||||
|
' == 内部数据流 ==
|
||||||
|
Comment -right-> MsgHub : 评论通知
|
||||||
|
MsgHub -down-> DB : 消息存储
|
||||||
|
KC -down-> LDAP : 用户认证
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 核心组件清单
|
||||||
|
|
||||||
|
| 组件 | 开源方案 | 用途 | 许可证 |
|
||||||
|
|------|---------|------|--------|
|
||||||
|
| Git 仓库 | **Gitea** | 文档源码存储与版本管理 | MIT |
|
||||||
|
| Markdown 渲染 | **Pandoc** + **markdown-it** | Markdown → HTML 转换,元数据提取 | GPL / MIT |
|
||||||
|
| 阅读平台 | **自研 DocPortal**(基于 Next.js) | 文档浏览、权限控制、URL 管理 | — |
|
||||||
|
| 评论系统 | **Remark42** | 自托管评论,支持匿名/认证评论 | MIT |
|
||||||
|
| 统计分析 | **Umami** | 自托管网站分析,页面访问与阅读时长 | MIT |
|
||||||
|
| 全文检索 | **MeiliSearch** | 文档标题、摘要、正文全文搜索 | MIT |
|
||||||
|
| PDF 导出 | **Pandoc** + **WeasyPrint** | Markdown → PDF 高质量排版 | GPL |
|
||||||
|
| 消息推送 | **自研 MsgHub**(基于 Socket.io) | 实时消息通知与任务看板集成 | — |
|
||||||
|
| 认证中心 | **Keycloak**(已有) | OIDC SSO 统一登录 | Apache 2.0 |
|
||||||
|
| 反向代理 | **Nginx**(已有) | SSL 终止、路由分发 | BSD |
|
||||||
|
| 静态站点生成 | **MkDocs** / **Hugo** | Git → 静态网站自动构建 | BSD / Apache |
|
||||||
|
| 浏览器指纹 | **FingerprintJS** (开源版) | 访客匿名标识,`public_once` 一次性阅读控制 | MIT |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、文档生产流程
|
||||||
|
|
||||||
|
### 3.1 编写工具:VS Code + Qoder
|
||||||
|
|
||||||
|
- 作者使用 **VS Code** 编辑器 + **Qoder** AI 辅助工具进行 Markdown 文档编写
|
||||||
|
- 支持实时预览、AI 辅助补全、PlantUML 图表嵌入
|
||||||
|
- 所有文档遵循统一的 Markdown 规范(标题层级、Front Matter 元数据等)
|
||||||
|
|
||||||
|
### 3.2 Front Matter 元数据规范
|
||||||
|
|
||||||
|
每篇文档头部须包含 YAML Front Matter,声明文档元信息:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "产品技术方案"
|
||||||
|
summary: "描述智能笔 BLE 通信协议的整体架构与关键技术细节"
|
||||||
|
author: "zhangsan@writech.cn"
|
||||||
|
tags: ["技术方案", "智能笔", "BLE"]
|
||||||
|
publish:
|
||||||
|
access: login # 可选:public / public_once / login / restricted
|
||||||
|
allowed_users: [] # access=restricted 时生效,填写用户邮箱
|
||||||
|
permissions: # 各权限开关
|
||||||
|
read: true
|
||||||
|
comment: true
|
||||||
|
save_as: false
|
||||||
|
export_pdf: false
|
||||||
|
lifecycle:
|
||||||
|
expires_at: "2026-06-30" # 可选:到期日期
|
||||||
|
max_views: null # 可选:最大阅读次数
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 Git 推送触发流程
|
||||||
|
|
||||||
|
```
|
||||||
|
作者在 VS Code / Qoder 中编写 Markdown
|
||||||
|
│
|
||||||
|
├─ git add → git commit → git push (SSH 秘钥认证)
|
||||||
|
│
|
||||||
|
└─ Gitea 接收推送
|
||||||
|
│
|
||||||
|
├─ Webhook → DocForge 渲染引擎
|
||||||
|
│ ├─ 解析 Front Matter 元数据
|
||||||
|
│ ├─ Markdown → HTML 渲染(Pandoc + markdown-it)
|
||||||
|
│ ├─ 提取摘要(首段 / summary 字段)
|
||||||
|
│ ├─ 生成文档 URL(基于仓库路径映射)
|
||||||
|
│ ├─ 写入文档注册表(PostgreSQL)
|
||||||
|
│ ├─ 推送到 MeiliSearch 索引
|
||||||
|
│ └─ 若匹配域名映射规则 → 同步到目标网站
|
||||||
|
│
|
||||||
|
└─ 文档在 DocPortal 即时可访问
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、文档渲染与发布引擎(DocForge)
|
||||||
|
|
||||||
|
### 4.1 渲染流程
|
||||||
|
|
||||||
|
DocForge 是 Git Webhook 驱动的文档处理服务,负责将 Markdown 转换为可发布的 HTML 页面:
|
||||||
|
|
||||||
|
1. **接收 Webhook**:Gitea 推送事件触发,包含变更文件列表
|
||||||
|
2. **增量渲染**:仅处理本次变更的 Markdown 文件,非全量重建
|
||||||
|
3. **元数据解析**:提取 Front Matter 中的标题、摘要、权限、生命周期配置
|
||||||
|
4. **HTML 渲染**:通过 Pandoc 将 Markdown 转为带目录的 HTML,嵌入统一样式模板
|
||||||
|
5. **摘要生成**:优先使用 `summary` 字段,未填则自动取正文前 200 字
|
||||||
|
6. **URL 生成规则**:`https://docs.writech.cn/{仓库名}/{文档路径}`
|
||||||
|
7. **注册入库**:文档元数据(URL、标题、摘要、权限、生命周期)写入 PostgreSQL
|
||||||
|
8. **搜索索引**:文档标题 + 摘要 + 正文推送至 MeiliSearch
|
||||||
|
|
||||||
|
### 4.2 渲染引擎技术栈
|
||||||
|
|
||||||
|
```
|
||||||
|
DocForge (Node.js 服务)
|
||||||
|
├─ Express.js — HTTP 接收 Webhook
|
||||||
|
├─ Pandoc (CLI 调用) — Markdown → HTML 核心渲染
|
||||||
|
├─ markdown-it — 辅助渲染(代码高亮、PlantUML 等)
|
||||||
|
├─ gray-matter — Front Matter 解析
|
||||||
|
├─ pg (node-postgres) — 元数据写入 PostgreSQL
|
||||||
|
└─ meilisearch-js — 搜索索引更新
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、文档阅读平台(DocPortal)
|
||||||
|
|
||||||
|
### 5.1 功能概览
|
||||||
|
|
||||||
|
DocPortal 是面向读者的 Web 应用,提供文档浏览、搜索、评论、导出等功能:
|
||||||
|
|
||||||
|
| 功能 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 文档列表 | 按仓库/标签/时间浏览文档,显示标题 + 摘要 + URL |
|
||||||
|
| 全文搜索 | 基于 MeiliSearch 的标题、摘要、正文即时搜索 |
|
||||||
|
| 文档阅读 | 渲染后的 HTML 页面,带目录导航 |
|
||||||
|
| 评论反馈 | 嵌入 Remark42 评论组件,支持分段评论 |
|
||||||
|
| PDF 导出 | 有权限用户可导出 PDF(Pandoc + WeasyPrint) |
|
||||||
|
| 另存为 | 有权限用户可下载 Markdown 原文或 HTML |
|
||||||
|
| 源文件定位 | 有编辑权限的用户可见「编辑源文件」图标,一键复制 Git 仓库中对应 Markdown 文件的完整路径 |
|
||||||
|
|
||||||
|
### 5.2 URL 与摘要体系
|
||||||
|
|
||||||
|
每篇文档发布后具备:
|
||||||
|
|
||||||
|
| 元素 | 格式 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 文档 URL | `https://docs.writech.cn/{repo}/{path}` | `https://docs.writech.cn/docs/技术方案/BLE通信协议` |
|
||||||
|
| 短链接 | `https://docs.writech.cn/d/{短码}` | `https://docs.writech.cn/d/a3Kx9` |
|
||||||
|
| 摘要 | Front Matter `summary` 或自动提取前 200 字 | 显示在文档列表、搜索结果、分享卡片中 |
|
||||||
|
|
||||||
|
短链接便于在邮件、即时通讯中分享,访问短链接自动重定向到完整 URL。
|
||||||
|
|
||||||
|
### 5.3 源文件快速定位(编辑图标)
|
||||||
|
|
||||||
|
对于拥有 Git 仓库写权限的用户,文档页面右上角显示 **「✏️ 编辑源文件」** 图标:
|
||||||
|
|
||||||
|
- **点击**:复制 Git 仓库中对应 Markdown 文件的完整路径到剪贴板,如 `docs/技术方案/BLE通信协议.md`
|
||||||
|
- **Tooltip**:显示仓库名 + 文件路径 + 最近修改者 + 修改时间
|
||||||
|
- 作者可直接在 VS Code / Qoder 中通过路径定位文件并修改
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、权限管理体系
|
||||||
|
|
||||||
|
### 6.1 文档访问级别
|
||||||
|
|
||||||
|
文档发布时,作者在 Front Matter 的 `publish.access` 字段选择访问级别:
|
||||||
|
|
||||||
|
| 级别 | 标识 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| **公开** | `public` | 游客可通过 URL 自由访问,无需登录,不限次数 |
|
||||||
|
| **公开一次** | `public_once` | 访客免登录可阅读一次,再次访问同一文档需登录;通过浏览器指纹 + Cookie 判定 |
|
||||||
|
| **需登录** | `login` | 需通过 Keycloak 登录后方可访问(读者 / 审阅者) |
|
||||||
|
| **限定人员** | `restricted` | 仅 `allowed_users` 列表中的用户可访问 |
|
||||||
|
|
||||||
|
### 6.2 细粒度权限矩阵
|
||||||
|
|
||||||
|
在 `publish.permissions` 中按功能逐项配置:
|
||||||
|
|
||||||
|
| 权限 | 说明 | 默认值 |
|
||||||
|
|------|------|--------|
|
||||||
|
| `read` | 阅读文档正文 | true |
|
||||||
|
| `comment` | 发表评论和反馈 | true(login/restricted);public 游客可匿名评论(需验证码);public_once 访客不可评论 |
|
||||||
|
| `save_as` | 下载 Markdown 原文或 HTML | false(游客 / 访客始终不可用) |
|
||||||
|
| `export_pdf` | 导出为 PDF 文件 | false(游客 / 访客始终不可用) |
|
||||||
|
|
||||||
|
### 6.3 权限校验流程
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 文档访问权限校验流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:用户访问文档 URL;
|
||||||
|
|
||||||
|
if (文档 access = public ?) then (是)
|
||||||
|
:允许阅读;
|
||||||
|
note right: 游客 - 免登录, 不限次数
|
||||||
|
else (否)
|
||||||
|
if (文档 access = public_once ?) then (是)
|
||||||
|
if (用户已登录 ?) then (是)
|
||||||
|
:允许阅读;
|
||||||
|
note right: 登录用户不受一次限制
|
||||||
|
else (否)
|
||||||
|
:生成浏览器指纹;
|
||||||
|
if (已有该文档访问记录 ?) then (是)
|
||||||
|
:提示 "请登录后继续访问";
|
||||||
|
:重定向到 Keycloak 登录;
|
||||||
|
stop
|
||||||
|
else (否)
|
||||||
|
:允许阅读;
|
||||||
|
:写入指纹记录 + Cookie;
|
||||||
|
note right: 访客 - 免登录, 仅此一次
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
else (否)
|
||||||
|
if (用户已登录 Keycloak ?) then (否)
|
||||||
|
:重定向到 Keycloak 登录;
|
||||||
|
stop
|
||||||
|
else (是)
|
||||||
|
if (文档 access = login ?) then (是)
|
||||||
|
:允许阅读;
|
||||||
|
else (restricted)
|
||||||
|
if (用户在 allowed_users 列表中 ?) then (是)
|
||||||
|
:允许阅读;
|
||||||
|
else (否)
|
||||||
|
:返回 403 无权访问;
|
||||||
|
stop
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
:加载文档页面;
|
||||||
|
:根据角色与 permissions 决定功能可用性;
|
||||||
|
note right
|
||||||
|
游客: 可匿名评论(需验证码), 不可导出
|
||||||
|
访客: 不可评论, 不可导出
|
||||||
|
登录用户: 按 permissions 配置
|
||||||
|
编辑图标: 仅 Git 写权限用户
|
||||||
|
end note
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.4 权限与认证底座的关系
|
||||||
|
|
||||||
|
| 层次 | 组件 | 职责 |
|
||||||
|
|------|------|------|
|
||||||
|
| 身份源 | OpenLDAP(私有云) | 用户账户、组织架构、角色 |
|
||||||
|
| 认证中心 | Keycloak(互联网服务器) | SSO 登录,签发 OIDC Token |
|
||||||
|
| 匿名访问控制 | DocPortal + FingerprintJS | 游客自由访问 `public` 文档;访客通过浏览器指纹 + Cookie 判定是否首次访问 `public_once` 文档 |
|
||||||
|
| 应用层权限 | DocPortal | 解析登录用户 Token 或匿名身份,匹配 Front Matter 权限配置 |
|
||||||
|
| Git 写权限 | Gitea | 判断用户是否有仓库写权限,控制「编辑图标」显示 |
|
||||||
|
|
||||||
|
### 6.5 访客一次性阅读的技术实现
|
||||||
|
|
||||||
|
`public_once` 级别文档的访客身份追踪方案:
|
||||||
|
|
||||||
|
| 技术手段 | 说明 |
|
||||||
|
|---------|------|
|
||||||
|
| FingerprintJS | 客户端浏览器指纹库,生成稳定的匿名标识符(无需 Cookie 即可识别回访) |
|
||||||
|
| HttpOnly Cookie | 辅助手段,首次阅读时种下 Cookie,防止清除指纹后绕过限制 |
|
||||||
|
| 服务端记录 | PostgreSQL 存储 `(fingerprint_hash, doc_id, visited_at)`,校验是否已阅读 |
|
||||||
|
|
||||||
|
校验流程:用户访问 `public_once` 文档时,DocPortal 前端通过 FingerprintJS 生成浏览器指纹,携带指纹向后端查询是否已有该文档的访问记录;无记录则放行并写入,有记录则提示登录。
|
||||||
|
|
||||||
|
> **注意**:浏览器指纹并非 100% 可靠(更换浏览器或隐身模式可重置),`public_once` 的定位是**轻量防护**,适用于营销试读、内容预览等场景。高价值内容建议使用 `login` 或 `restricted` 级别。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、阅读统计分析
|
||||||
|
|
||||||
|
### 7.1 采集指标
|
||||||
|
|
||||||
|
基于 **Umami**(自托管 Web 分析)采集以下数据:
|
||||||
|
|
||||||
|
| 指标 | 采集方式 | 说明 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 页面访问量(PV) | Umami JS 埋点 | 每次打开文档 URL 计一次 |
|
||||||
|
| 独立访客数(UV) | Umami 匿名指纹 | 去重统计独立访问用户(含游客 / 访客匿名指纹) |
|
||||||
|
| 阅读时长 | Umami 页面停留时间 + 自定义心跳事件 | 每 30 秒上报一次心跳,计算有效阅读时长 |
|
||||||
|
| 阅读进度 | 自定义事件(滚动百分比) | 记录用户阅读到文档的哪个位置 |
|
||||||
|
| 来源渠道 | Umami Referrer | 记录用户从哪个链接进入 |
|
||||||
|
|
||||||
|
### 7.2 阅读时长精确统计方案
|
||||||
|
|
||||||
|
标准的页面停留时间统计不够准确(用户可能切出标签页),采用**心跳 + 可见性检测**方案:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 嵌入文档页面的阅读时长统计脚本(伪代码)
|
||||||
|
let readingSeconds = 0;
|
||||||
|
let heartbeatTimer = null;
|
||||||
|
|
||||||
|
document.addEventListener('visibilitychange', () => {
|
||||||
|
if (document.hidden) {
|
||||||
|
clearInterval(heartbeatTimer); // 页面不可见,暂停计时
|
||||||
|
} else {
|
||||||
|
heartbeatTimer = setInterval(() => {
|
||||||
|
readingSeconds += 30;
|
||||||
|
umami.track('reading-heartbeat', { // 每30秒上报
|
||||||
|
doc_id: DOC_ID,
|
||||||
|
seconds: readingSeconds
|
||||||
|
});
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 统计看板
|
||||||
|
|
||||||
|
管理员和作者可在 DocPortal 中查看文档统计看板:
|
||||||
|
|
||||||
|
- **文档维度**:每篇文档的 PV / UV / 平均阅读时长 / 完读率
|
||||||
|
- **时间维度**:按日 / 周 / 月查看趋势
|
||||||
|
- **用户维度**:(需登录文档)哪些用户阅读了、阅读时长排名
|
||||||
|
- **导出**:统计数据可导出 CSV
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、文档生命周期管理
|
||||||
|
|
||||||
|
### 8.1 生命周期配置
|
||||||
|
|
||||||
|
在 Front Matter 的 `publish.lifecycle` 中配置:
|
||||||
|
|
||||||
|
| 参数 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `expires_at` | 日期字符串 | 到期后文档自动下架,页面显示「文档已过期」 |
|
||||||
|
| `max_views` | 整数 | 累计阅读次数达到上限后自动下架 |
|
||||||
|
| 无配置 | — | 永久有效,不自动下架 |
|
||||||
|
|
||||||
|
> **区分 `max_views` 与 `public_once`**:`max_views` 是文档级总阅读次数上限(达到后所有用户均不可访问),`public_once` 是访客级单次阅读限制(每位访客仅限免登录阅读一次,登录用户不受影响)。两者可同时配置、互不冲突。
|
||||||
|
|
||||||
|
### 8.2 生命周期状态流转
|
||||||
|
|
||||||
|
```
|
||||||
|
已发布 (Active)
|
||||||
|
│
|
||||||
|
├─ 达到 expires_at → 已过期 (Expired)
|
||||||
|
├─ 达到 max_views → 已达上限 (Limit Reached)
|
||||||
|
├─ 作者手动下架 → 已下架 (Archived)
|
||||||
|
└─ Git 中删除文件 → 已删除 (Deleted)
|
||||||
|
|
||||||
|
已过期 / 已达上限 / 已下架
|
||||||
|
└─ 作者更新 Front Matter 重新配置 → 已发布 (Active)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.3 下架处理
|
||||||
|
|
||||||
|
- 下架后 URL 仍保留,但页面显示提示信息(如「此文档已过期,请联系作者」)
|
||||||
|
- 管理员可配置是否允许已登录用户查看过期文档的历史快照
|
||||||
|
- 文档的统计数据和评论不随下架删除,可供作者回溯
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、评论反馈系统
|
||||||
|
|
||||||
|
### 9.1 技术方案:Remark42
|
||||||
|
|
||||||
|
采用 **Remark42** 自托管评论系统:
|
||||||
|
|
||||||
|
- **部署位置**:互联网应用服务器(Docker 容器)
|
||||||
|
- **认证对接**:通过 Keycloak OIDC 实现评论者身份认证
|
||||||
|
- **匿名评论**:`public` 级别文档支持游客匿名评论(需验证码防刷);`public_once` 级别文档访客不开放评论
|
||||||
|
- **数据存储**:Remark42 自带 BoltDB 存储,备份至私有云
|
||||||
|
|
||||||
|
### 9.2 评论功能
|
||||||
|
|
||||||
|
| 功能 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| 文档级评论 | 在文档末尾发表整体评论 |
|
||||||
|
| 段落级评论 | 选中文档段落后发表针对性评论 |
|
||||||
|
| 回复与嵌套 | 支持多级回复讨论 |
|
||||||
|
| @提及 | 评论中 @某用户,触发专属通知 |
|
||||||
|
| Markdown 格式 | 评论内容支持 Markdown 语法 |
|
||||||
|
| 管理操作 | 作者可置顶、删除评论;管理员可全局管理 |
|
||||||
|
|
||||||
|
### 9.3 评论触发消息通知
|
||||||
|
|
||||||
|
当文档收到新评论或反馈时:
|
||||||
|
|
||||||
|
1. Remark42 通过 Webhook 通知 MsgHub 消息中心
|
||||||
|
2. MsgHub 根据评论内容识别通知目标:
|
||||||
|
- 文档作者(始终通知)
|
||||||
|
- 被 @提及的用户
|
||||||
|
- 该文档评论帖的参与者(可配置是否通知)
|
||||||
|
3. 消息实时推送到目标用户的消息中心
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、消息中心与任务看板集成
|
||||||
|
|
||||||
|
### 10.1 设计理念
|
||||||
|
|
||||||
|
消息中心采用**类微信群列表**的交互模式:
|
||||||
|
|
||||||
|
- 每篇有新消息的文档如同一个「对话」
|
||||||
|
- 新消息驱动该文档条目**置顶排列**(最新消息在最前)
|
||||||
|
- 点击文档条目直接在浏览器中打开对应文档及其评论区
|
||||||
|
- 未读消息显示红点 + 未读数
|
||||||
|
- 消息中心同时作为作者的**任务看板**,待处理的评论/反馈一目了然
|
||||||
|
|
||||||
|
### 10.2 消息类型
|
||||||
|
|
||||||
|
| 消息类型 | 触发条件 | 消息内容 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| 📝 新评论 | 文档收到新评论 | "{用户}在《{文档标题}》中发表了评论" |
|
||||||
|
| 💬 回复 | 某人回复了你的评论 | "{用户}回复了你在《{文档标题}》中的评论" |
|
||||||
|
| @提及 | 评论中 @了你 | "{用户}在《{文档标题}》的评论中提到了你" |
|
||||||
|
| 📊 阅读里程碑 | 文档阅读量突破阈值 | "《{文档标题}》阅读量已突破 100 次" |
|
||||||
|
| ⚠️ 生命周期告警 | 文档即将过期或达到阅读上限 | "《{文档标题}》将于 3 天后过期" |
|
||||||
|
|
||||||
|
### 10.3 消息中心界面结构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ 📬 消息中心 🔍 搜索 │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ 🔴 BLE通信协议技术方案 10:32 │
|
||||||
|
│ 张三:建议补充低功耗模式的说明 │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ 🔴 产品需求文档 v2.1 09:15 │
|
||||||
|
│ 李四 回复了你的评论 │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ 智能笔固件升级指南 昨天 │
|
||||||
|
│ 阅读量已突破 100 次 │
|
||||||
|
├─────────────────────────────────────────┤
|
||||||
|
│ Q3 项目计划 周一 │
|
||||||
|
│ 王五:时间节点需要再确认 │
|
||||||
|
└─────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
- 红点标识未读消息
|
||||||
|
- 列表按最新消息时间倒序排列
|
||||||
|
- 点击任一条目 → 浏览器打开该文档页面,自动滚动到对应评论
|
||||||
|
- 支持标记已读、批量已读、按类型筛选
|
||||||
|
|
||||||
|
### 10.4 技术实现
|
||||||
|
|
||||||
|
```
|
||||||
|
MsgHub 消息中心 (Node.js)
|
||||||
|
├─ Socket.io — WebSocket 实时推送
|
||||||
|
├─ PostgreSQL — 消息持久化存储
|
||||||
|
├─ Redis — 未读计数缓存、在线状态
|
||||||
|
├─ Remark42 Webhook — 评论事件接入
|
||||||
|
├─ DocForge Webhook — 生命周期事件接入
|
||||||
|
└─ Umami API — 阅读量里程碑检测
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、域名网站自动发布
|
||||||
|
|
||||||
|
### 11.1 映射机制
|
||||||
|
|
||||||
|
Git 仓库中的 Markdown 可配置自动发布到指定域名网站,映射关系存储于 PostgreSQL:
|
||||||
|
|
||||||
|
| Git 仓库 / 路径 | 目标域名 | 构建工具 | 说明 |
|
||||||
|
|-----------------|---------|---------|------|
|
||||||
|
| `web-doc/` | yink.ai | Hugo | 品牌官网内容 |
|
||||||
|
| `docs/对外文档/` | docs.writech.cn | MkDocs | 对外技术文档站 |
|
||||||
|
| `edu-doc/` | edu.writech.cn | MkDocs | 教育平台文档 |
|
||||||
|
|
||||||
|
### 11.2 自动发布流程
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title Git → 域名网站自动发布流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:作者 git push 更新 Markdown;
|
||||||
|
:Gitea Webhook 触发 DocForge;
|
||||||
|
|
||||||
|
:DocForge 检查变更文件路径;
|
||||||
|
if (匹配域名映射规则 ?) then (是)
|
||||||
|
:调用对应构建工具\n(Hugo / MkDocs);
|
||||||
|
:生成静态 HTML 站点;
|
||||||
|
:通过 rsync + SSH\n部署到目标服务器;
|
||||||
|
:目标域名网站内容更新;
|
||||||
|
else (否)
|
||||||
|
:仅更新 DocPortal\n内部阅读平台;
|
||||||
|
endif
|
||||||
|
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11.3 映射配置文件
|
||||||
|
|
||||||
|
映射关系通过 Git 仓库中的配置文件 `.docforge.yml` 管理:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .docforge.yml — 仓库根目录
|
||||||
|
site_mappings:
|
||||||
|
- source: "对外文档/"
|
||||||
|
target:
|
||||||
|
domain: "docs.writech.cn"
|
||||||
|
builder: "mkdocs"
|
||||||
|
deploy:
|
||||||
|
method: "rsync"
|
||||||
|
host: "106.55.191.177"
|
||||||
|
path: "/var/www/docs.writech.cn/"
|
||||||
|
- source: "/"
|
||||||
|
target:
|
||||||
|
domain: "docs.writech.cn"
|
||||||
|
builder: "mkdocs"
|
||||||
|
base_path: "/internal/"
|
||||||
|
deploy:
|
||||||
|
method: "rsync"
|
||||||
|
host: "106.55.191.177"
|
||||||
|
path: "/var/www/docs.writech.cn/internal/"
|
||||||
|
```
|
||||||
|
|
||||||
|
映射关系一旦设定,后续 Markdown 更新即自动推送到对应域名,无需手动操作。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十二、互联网推广与海报链接体系
|
||||||
|
|
||||||
|
### 12.1 设计目标
|
||||||
|
|
||||||
|
将文档系统产出的内容转化为**互联网营销落地页**(海报链接),通过主流流量平台分发,获取 2B / 2C 新客户。核心链路:
|
||||||
|
|
||||||
|
```
|
||||||
|
文档系统 (Markdown)
|
||||||
|
│
|
||||||
|
├─ DocForge 渲染为静态 HTML 落地页
|
||||||
|
│
|
||||||
|
├─ 内嵌 JS 与服务器 API 交互(埋点 / 表单 / 动态内容)
|
||||||
|
│
|
||||||
|
├─ CDN 全网加速分发
|
||||||
|
│
|
||||||
|
├─ 生成海报链接(短链接 + 渠道追踪参数)
|
||||||
|
│
|
||||||
|
└─ 投放到微信 / 淘宝 / 美团 / 抖音 / 短信
|
||||||
|
│
|
||||||
|
└─ 客户点击/扫码 → 浏览器打开落地页 → 转化
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.2 海报链接架构
|
||||||
|
|
||||||
|
#### 落地页结构
|
||||||
|
|
||||||
|
海报链接指向的是一张**静态 HTML 落地页**,由 DocForge 从 Markdown 源文档自动生成,包含:
|
||||||
|
|
||||||
|
| 层次 | 内容 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 静态 HTML | 产品介绍、图文排版、CTA 按钮 | CDN 分发,毫秒级加载 |
|
||||||
|
| 内嵌 JS | 埋点脚本 + 交互逻辑 | 页面加载后调用服务器 API |
|
||||||
|
| 服务器 API | 渠道统计、表单提交、动态内容 | 运行在互联网应用服务器 |
|
||||||
|
|
||||||
|
#### 落地页内嵌 JS 交互能力
|
||||||
|
|
||||||
|
静态落地页加载后,内嵌的 JS 脚本自动调用服务器接口完成以下交互:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 落地页内嵌 JS 核心逻辑(伪代码)
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
|
// 1. 渠道来源埋点 — 记录用户从哪个平台进入
|
||||||
|
const params = new URLSearchParams(location.search);
|
||||||
|
fetch('/api/promo/track', {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
page_id: PAGE_ID,
|
||||||
|
channel: params.get('ch'), // wx / tb / mt / dy / sms
|
||||||
|
campaign: params.get('cmp'), // 活动标识
|
||||||
|
referer: document.referrer
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. 动态内容加载 — 价格、库存、活动信息
|
||||||
|
fetch('/api/promo/dynamic/' + PAGE_ID)
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById('price').textContent = data.price;
|
||||||
|
document.getElementById('stock').textContent = data.stock;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. 表单提交 — 客户留资 / 咨询 / 预约
|
||||||
|
document.getElementById('lead-form').addEventListener('submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
fetch('/api/promo/lead', {
|
||||||
|
method: 'POST',
|
||||||
|
body: new FormData(e.target)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.3 CDN 全网加速分发
|
||||||
|
|
||||||
|
落地页为纯静态 HTML + CSS + JS + 图片,通过 CDN 分发到全网边缘节点,确保各渠道用户点击后毫秒级加载:
|
||||||
|
|
||||||
|
| 项目 | 方案 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| CDN 服务 | 阿里云 CDN | 覆盖国内及海外节点,配合已有域名架构 |
|
||||||
|
| 源站 | 互联网应用服务器 | DocForge 生成的静态文件存储于源站 |
|
||||||
|
| 缓存策略 | HTML 5分钟 / 图片字体 30 天 | HTML 短缓存确保内容更新及时生效 |
|
||||||
|
| HTTPS | ZeroSSL 通配符证书 | 复用 ICT 平台证书体系 |
|
||||||
|
| 缓存刷新 | DocForge 发布后自动调用 CDN Purge API | Markdown 更新后落地页即时刷新 |
|
||||||
|
|
||||||
|
发布流程:
|
||||||
|
|
||||||
|
```
|
||||||
|
DocForge 渲染落地页 HTML
|
||||||
|
│
|
||||||
|
├─ 写入源站目录 /var/www/promo/
|
||||||
|
│
|
||||||
|
├─ 调用阿里云 CDN Purge API 刷新缓存
|
||||||
|
│
|
||||||
|
└─ 全网边缘节点同步更新(秒级)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.4 五大渠道投放方案
|
||||||
|
|
||||||
|
每个渠道生成专属海报链接,带渠道追踪参数,确保来源可精确归因:
|
||||||
|
|
||||||
|
| 渠道 | 渠道码 | 链接形式 | 投放载体 | 打开方式 |
|
||||||
|
|------|---------|---------|---------|----------|
|
||||||
|
| **微信** | `ch=wx` | 短链接 + 二维码 | 朋友圈图文、公众号文章、群聊卡片 | 微信内置浏览器打开 |
|
||||||
|
| **淘宝** | `ch=tb` | 淘口令 + 短链接 | 商品详情页、店铺首页、客服消息 | 手淘内置浏览器打开 |
|
||||||
|
| **美团** | `ch=mt` | 短链接 | 店铺介绍、团购详情、评价回复 | 美团 App 内置浏览器打开 |
|
||||||
|
| **抖音** | `ch=dy` | 短链接 | 视频评论区、主页链接、直播间小黄车 | 抖音内置浏览器打开 |
|
||||||
|
| **短信** | `ch=sms` | 短链接 | 营销短信文案 | 系统默认浏览器打开 |
|
||||||
|
|
||||||
|
链接格式示例:
|
||||||
|
|
||||||
|
```
|
||||||
|
完整 URL:https://go.writech.cn/p/smart-pen-intro?ch=wx&cmp=2026q1
|
||||||
|
短链接: https://go.writech.cn/s/Xk9mP
|
||||||
|
淘口令: ¥smart-pen-introXk9mP¥
|
||||||
|
二维码: 将短链接编码为 QR Code,嵌入海报图片
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.5 渠道适配与浏览器兼容
|
||||||
|
|
||||||
|
各平台客户端点击链接后均通过其**内置浏览器**打开落地页,需针对性适配:
|
||||||
|
|
||||||
|
| 内置浏览器 | 特征 | 适配策略 |
|
||||||
|
|-------------|------|----------|
|
||||||
|
| 微信 WebView | 不支持部分 Web API,有 JS-SDK | 检测 UA 含 "MicroMessenger",加载微信 JS-SDK,启用分享卡片自定义 |
|
||||||
|
| 淘宝 WebView | 限制外跳,访问受限 | 落地页自包含,避免外跳;表单交互在页内完成 |
|
||||||
|
| 美团 WebView | 与标准浏览器接近 | 标准响应式适配即可 |
|
||||||
|
| 抖音 WebView | 限制外跳,支持基础 Web API | 落地页自包含;复杂交互引导“用浏览器打开” |
|
||||||
|
| 系统浏览器 (短信) | 完整 Web 能力 | 无需特殊适配 |
|
||||||
|
|
||||||
|
落地页 JS 自动检测运行环境并适配:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 环境检测与适配(伪代码)
|
||||||
|
const ua = navigator.userAgent;
|
||||||
|
if (/MicroMessenger/i.test(ua)) {
|
||||||
|
loadWxJSSDK(); // 加载微信 JS-SDK,配置分享卡片
|
||||||
|
} else if (/AliApp.*TB/i.test(ua)) {
|
||||||
|
disableExternalLinks(); // 淘宝内禁止外跳
|
||||||
|
} else if (/aweme/i.test(ua)) {
|
||||||
|
showOpenInBrowser(); // 抖音内显示“用浏览器打开”引导
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.6 推广流量追踪与转化分析
|
||||||
|
|
||||||
|
#### 追踪参数体系
|
||||||
|
|
||||||
|
每个海报链接携带统一追踪参数,全部流入 Umami 统计平台:
|
||||||
|
|
||||||
|
| 参数 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `ch` | 渠道来源 | wx / tb / mt / dy / sms |
|
||||||
|
| `cmp` | 活动标识 | 2026q1 / summer-sale |
|
||||||
|
| `ct` | 内容类型 | product / article / event |
|
||||||
|
| `kw` | 关键词(付费投放时) | smart-pen / ink-screen |
|
||||||
|
|
||||||
|
#### 转化漏斗
|
||||||
|
|
||||||
|
从点击到转化的全链路数据均录入 PostgreSQL,供营销团队分析:
|
||||||
|
|
||||||
|
```
|
||||||
|
点击链接 (Impression)
|
||||||
|
│
|
||||||
|
├─ 打开落地页 (PageView) ← Umami 埋点
|
||||||
|
│
|
||||||
|
├─ 页面停留 > 10s (Engaged) ← 心跳上报
|
||||||
|
│
|
||||||
|
├─ 提交表单 / 点击 CTA (Lead) ← 表单提交 API
|
||||||
|
│
|
||||||
|
└─ 完成购买 / 注册 (Conversion) ← 业务系统回调
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 推广效果看板
|
||||||
|
|
||||||
|
在 DocPortal 管理后台提供推广效果看板:
|
||||||
|
|
||||||
|
| 维度 | 指标 |
|
||||||
|
|------|------|
|
||||||
|
| 渠道维度 | 各渠道 PV / UV / 平均停留 / 留资数 / 转化率 |
|
||||||
|
| 内容维度 | 各落地页访问量 / 转化率 / 热度图 |
|
||||||
|
| 活动维度 | 各活动投入产出比 (ROI) |
|
||||||
|
| 时间维度 | 按日 / 周 / 月的流量与转化趋势 |
|
||||||
|
|
||||||
|
### 12.7 推广落地页生成与管理流程
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title 推广落地页生成与分发流程
|
||||||
|
|
||||||
|
start
|
||||||
|
:营销人员在 Markdown 中编写推广内容;
|
||||||
|
note right: 使用 promo 模板,配置表单/CTA
|
||||||
|
|
||||||
|
:设置 Front Matter 推广配置;
|
||||||
|
note right
|
||||||
|
publish.type: promo
|
||||||
|
publish.channels: [wx, tb, dy]
|
||||||
|
publish.cdn: true
|
||||||
|
end note
|
||||||
|
|
||||||
|
:git push 推送到 Gitea;
|
||||||
|
:DocForge 渲染生成静态落地页;
|
||||||
|
note right
|
||||||
|
内嵌埋点 JS + 表单交互 JS
|
||||||
|
生成各渠道专属短链接
|
||||||
|
微信渠道额外生成 QR Code
|
||||||
|
end note
|
||||||
|
|
||||||
|
:部署到源站 + CDN 刷新;
|
||||||
|
|
||||||
|
:营销人员获取各渠道链接;
|
||||||
|
note right
|
||||||
|
微信: 短链接 + QR Code
|
||||||
|
淘宝: 淘口令 + 短链接
|
||||||
|
美团: 短链接
|
||||||
|
抖音: 短链接
|
||||||
|
短信: 短链接
|
||||||
|
end note
|
||||||
|
|
||||||
|
:投放到各平台;
|
||||||
|
|
||||||
|
:客户点击/扫码;
|
||||||
|
:平台内置浏览器打开落地页;
|
||||||
|
note right
|
||||||
|
CDN 加速加载静态 HTML
|
||||||
|
JS 调用服务器 API 记录渠道+加载动态内容
|
||||||
|
end note
|
||||||
|
|
||||||
|
:客户浏览/交互/留资;
|
||||||
|
:Umami + API 记录全链路数据;
|
||||||
|
stop
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.8 推广文档 Front Matter 扩展
|
||||||
|
|
||||||
|
推广类文档在标准 Front Matter 基础上增加推广专属配置:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: "智能笔新品发布"
|
||||||
|
summary: "自然写 Qink 智能笔,笔迹实时同步至大屏"
|
||||||
|
author: "marketing@writech.cn"
|
||||||
|
tags: ["推广", "智能笔", "Qink"]
|
||||||
|
publish:
|
||||||
|
type: promo # 推广类型文档
|
||||||
|
access: public # 推广页通常 public;高价值预览内容可用 public_once
|
||||||
|
cdn: true # 启用 CDN 分发
|
||||||
|
channels: [wx, tb, mt, dy, sms] # 投放渠道
|
||||||
|
landing_page:
|
||||||
|
template: product # 落地页模板:product / article / event
|
||||||
|
cta_text: "立即了解" # CTA 按钮文案
|
||||||
|
cta_url: "/contact" # CTA 跳转目标
|
||||||
|
form: true # 是否包含留资表单
|
||||||
|
lifecycle:
|
||||||
|
expires_at: "2026-06-30"
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十三、部署方案
|
||||||
|
|
||||||
|
### 13.1 服务部署清单
|
||||||
|
|
||||||
|
全部服务运行于**互联网应用服务器**(腾讯云 / 阿里云),数据后端在私有云:
|
||||||
|
|
||||||
|
| 服务 | 部署方式 | 运行位置 | 端口 |
|
||||||
|
|------|---------|---------|------|
|
||||||
|
| DocForge 渲染引擎 | Docker | 互联网应用服务器 | 3001 |
|
||||||
|
| DocPortal 阅读平台 | Docker (Next.js) | 互联网应用服务器 | 3000 |
|
||||||
|
| Remark42 评论系统 | Docker | 互联网应用服务器 | 8080 |
|
||||||
|
| Umami 统计分析 | Docker | 互联网应用服务器 | 3002 |
|
||||||
|
| MeiliSearch 搜索 | Docker | 互联网应用服务器 | 7700 |
|
||||||
|
| MsgHub 消息中心 | Docker (Node.js) | 互联网应用服务器 | 3003 |
|
||||||
|
| Redis | Docker | 互联网应用服务器 | 6379 |
|
||||||
|
| PostgreSQL | 原生安装 | 私有云 | 5432 |
|
||||||
|
| Gitea | Docker(已有) | 互联网应用服务器 | 22/443 |
|
||||||
|
| Keycloak | Docker(已有) | 互联网应用服务器 | 8443 |
|
||||||
|
| PromoAPI 推广接口 | Docker (Node.js) | 互联网应用服务器 | 3004 |
|
||||||
|
| 阿里云 CDN | SaaS | 全网边缘节点 | — |
|
||||||
|
|
||||||
|
### 13.2 Nginx 路由规则
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# DocPortal 阅读平台
|
||||||
|
location /docs/ {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remark42 评论 API
|
||||||
|
location /api/comment/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Umami 统计
|
||||||
|
location /api/analytics/ {
|
||||||
|
proxy_pass http://127.0.0.1:3002;
|
||||||
|
}
|
||||||
|
|
||||||
|
# MeiliSearch 搜索
|
||||||
|
location /api/search/ {
|
||||||
|
proxy_pass http://127.0.0.1:7700;
|
||||||
|
}
|
||||||
|
|
||||||
|
# MsgHub WebSocket
|
||||||
|
location /ws/msg/ {
|
||||||
|
proxy_pass http://127.0.0.1:3003;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
|
# DocForge Webhook(仅允许 Gitea 内部调用)
|
||||||
|
location /hook/docforge {
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
proxy_pass http://127.0.0.1:3001;
|
||||||
|
}
|
||||||
|
|
||||||
|
# PromoAPI 推广接口
|
||||||
|
location /api/promo/ {
|
||||||
|
proxy_pass http://127.0.0.1:3004;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 推广落地页静态文件(CDN 回源)
|
||||||
|
location /p/ {
|
||||||
|
alias /var/www/promo/;
|
||||||
|
expires 5m;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十四、实施路线图
|
||||||
|
|
||||||
|
| 阶段 | 任务 | 预计周期 |
|
||||||
|
|------|------|--------|
|
||||||
|
| **第一阶段:基础** | DocForge 渲染引擎开发,Gitea Webhook 对接 | 第 1-2 周 |
|
||||||
|
| **第一阶段** | DocPortal 阅读平台 MVP(文档列表 + 阅读 + URL + 摘要) | 第 2-3 周 |
|
||||||
|
| **第一阶段** | MeiliSearch 全文检索集成 | 第 3 周 |
|
||||||
|
| **第一阶段** | Front Matter 权限解析 + Keycloak OIDC 认证对接 | 第 3-4 周 |
|
||||||
|
| **第二阶段:协作** | Remark42 评论系统部署与 Keycloak 对接 | 第 5 周 |
|
||||||
|
| **第二阶段** | MsgHub 消息中心开发(WebSocket + 消息列表) | 第 5-6 周 |
|
||||||
|
| **第二阶段** | 消息中心与任务看板集成(类微信列表交互) | 第 6-7 周 |
|
||||||
|
| **第二阶段** | 评论通知 → 消息中心 → 打开文档全链路打通 | 第 7 周 |
|
||||||
|
| **第三阶段:运营** | Umami 统计分析部署,阅读时长精确统计方案 | 第 8 周 |
|
||||||
|
| **第三阶段** | 文档生命周期管理(过期、阅读上限、自动下架) | 第 8-9 周 |
|
||||||
|
| **第三阶段** | PDF 导出功能(Pandoc + WeasyPrint) | 第 9 周 |
|
||||||
|
| **第四阶段:发布** | 域名网站自动发布(.docforge.yml 映射 + Hugo/MkDocs 构建) | 第 10-11 周 |
|
||||||
|
| **第四阶段** | 统计看板(作者维度 + 文档维度 + 趋势图) | 第 11-12 周 |
|
||||||
|
| **第四阶段** | 全链路测试与上线 | 第 12 周 |
|
||||||
|
| **第五阶段:推广** | 推广落地页模板开发 + CDN 接入 | 第 13 周 |
|
||||||
|
| **第五阶段** | 五渠道海报链接生成 + 渠道埋点 + 浏览器适配 | 第 13-14 周 |
|
||||||
|
| **第五阶段** | 推广效果看板(渠道归因 + 转化漏斗) | 第 14 周 |
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
# IT服务资源
|
||||||
|
|
||||||
|
## 资源概览
|
||||||
|
|
||||||
|
本文档记录公司IT基础设施资源的配置与状态信息。
|
||||||
|
|
||||||
|
## 应用服务器
|
||||||
|
|
||||||
|
| 序号 | 资源名称 | 云平台 | 服务区地址 | 操作系统 | IP地址 | 绑定域名 | 状态 |
|
||||||
|
|:---:|---------|--------|---------|---------|--------|---------|:---:|
|
||||||
|
| 1 | 腾讯云应用服务器 | 腾讯云 | 广州 | — | 106.55.191.177 | writech.cn | 运行中 |
|
||||||
|
| 2 | 阿里云应用服务器 | 阿里云 | 新加坡 | — | 47.84.109.13 | writech.ai | 运行中 |
|
||||||
|
| 3 | 私有云应用服务器 | 私有云 | 企业 | Ubuntu Linux | 118.141.37.23(公网IP经路由器映射至内网) | — | 运行中 |
|
||||||
|
|
||||||
|
### 1. 腾讯云应用服务器
|
||||||
|
|
||||||
|
- **云平台**:腾讯云
|
||||||
|
- **服务区地址**:广州
|
||||||
|
- **IP地址**:106.55.191.177
|
||||||
|
- **绑定域名**:writech.cn
|
||||||
|
- **用途**:应用服务部署
|
||||||
|
- **状态**:运行中
|
||||||
|
|
||||||
|
### 2. 阿里云应用服务器
|
||||||
|
|
||||||
|
- **云平台**:阿里云
|
||||||
|
- **服务区地址**:新加坡
|
||||||
|
- **IP地址**:47.84.109.13
|
||||||
|
- **绑定域名**:writech.ai
|
||||||
|
- **用途**:应用服务部署
|
||||||
|
- **状态**:运行中
|
||||||
|
|
||||||
|
### 3. 私有云应用服务器
|
||||||
|
|
||||||
|
- **云平台**:私有云
|
||||||
|
- **操作系统**:Ubuntu Linux
|
||||||
|
- **IP地址**:118.141.37.23(公网IP经路由器映射至内网Linux服务器)
|
||||||
|
- **用途**:数据源站、用户账户信息源
|
||||||
|
- **状态**:运行中
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 整体使用策略
|
||||||
|
|
||||||
|
### 各平台定位
|
||||||
|
|
||||||
|
1. **私有云**:安全可靠,存储容量大,作为数据源站及用户账户信息源。公网IP经路由器映射至内网Linux服务器,互联网的网络出口能力有限。仅限管理员通过内网/VPN直接操作维护。
|
||||||
|
2. **腾讯云 / 阿里云**:网络出口带宽能力强,应用程序可调用其算力API能力来服务业务。所有互联网终端用户(含企业员工)均通过公有云应用服务器使用各类业务系统。
|
||||||
|
|
||||||
|
### 核心原则
|
||||||
|
|
||||||
|
- **数据安全优先**:核心数据及用户信息存放在私有云上,确保数据主权可控。
|
||||||
|
- **弹性服务能力**:腾讯云及阿里云作为面向互联网终端用户提供服务的前端节点,其带宽和计算能力可按需扩充。
|
||||||
|
- **算力API复用**:公有云应用可调用平台提供的AI、音视频、CDN等算力API,降低自建成本。
|
||||||
|
- **统一访问入口**:企业员工使用企业管理系统同样基于互联网应用服务器访问,基本杜绝直接使用私有云系统,私有云仅限管理员进行运维管理。
|
||||||
|
|
||||||
|
### 互联网终端用户分类
|
||||||
|
|
||||||
|
| 用户类型 | 缩写 | 说明 |
|
||||||
|
|---------|:---:|------|
|
||||||
|
| 合作伙伴 | 2B | 企业级合作伙伴,通过API或管理后台接入 |
|
||||||
|
| 最终消费者 | 2C | 直接使用产品的终端消费者 |
|
||||||
|
| 企业员工 | 2E | 内部员工,通过互联网应用服务器使用企业管理系统 |
|
||||||
|
|
||||||
|
### 业务部署拓扑图
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
title IT资源业务部署拓扑
|
||||||
|
|
||||||
|
cloud "互联网终端用户" as Users {
|
||||||
|
actor "2B 合作伙伴" as B
|
||||||
|
actor "2C 最终消费者" as C
|
||||||
|
actor "2E 企业员工" as E
|
||||||
|
}
|
||||||
|
|
||||||
|
node "腾讯云 [广州]\nwritech.cn\n106.55.191.177" as TCloud {
|
||||||
|
component "应用服务" as TApp
|
||||||
|
component "算力API调用" as TAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
node "阿里云 [新加坡]\nwritech.ai\n47.84.109.13" as ACloud {
|
||||||
|
component "应用服务" as AApp
|
||||||
|
component "算力API调用" as AAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
node "私有云\n118.141.37.23\n(公网IP经路由器映射至内网)" as PCloud {
|
||||||
|
database "核心数据源站" as DB
|
||||||
|
database "用户账户信息" as Account
|
||||||
|
storage "大容量存储" as Storage
|
||||||
|
}
|
||||||
|
|
||||||
|
B -down-> TCloud : 国内合作伙伴访问
|
||||||
|
B -down-> ACloud : 海外合作伙伴访问
|
||||||
|
C -down-> TCloud : 国内消费者访问
|
||||||
|
C -down-> ACloud : 海外消费者访问
|
||||||
|
E -down-> TCloud : 企业管理系统访问
|
||||||
|
|
||||||
|
TApp -down-> DB : 数据读写
|
||||||
|
TApp -down-> Account : 账户验证
|
||||||
|
AApp -down-> DB : 数据读写
|
||||||
|
AApp -down-> Account : 账户验证
|
||||||
|
|
||||||
|
note right of PCloud : 仅管理员通过内网/VPN直接访问
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user