功能(文档预览):集成 ONLYOFFICE 安全只读预览与工作台体验
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled

新增 ONLYOFFICE 配置签名、内部内容接口、容器编排与反向代理。

打通网页端和桌面端独立预览工作区,完善文档入口、布局及帮助体验。

补充桌面安全发布门禁、开发脚本、使用文档和前后端测试。
This commit is contained in:
Cheng Zhou
2026-07-14 14:19:17 +08:00
parent 44db5db838
commit c68dddfc01
50 changed files with 2429 additions and 677 deletions
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=scripts/common.sh
source "$SCRIPT_DIR/common.sh"
ROTATE_SECRET=0
if [[ "${1:-}" == "--rotate-secret" ]]; then
ROTATE_SECRET=1
shift
fi
if [[ $# -gt 0 ]]; then
ctms_fail "未知参数: $1(支持的参数仅有 --rotate-secret"
fi
generate_random_hex() {
local bytes="${1:-32}"
if command -v openssl >/dev/null 2>&1; then
openssl rand -hex "$bytes"
return
fi
od -An -N "$bytes" -tx1 /dev/urandom | tr -d ' \n'
}
prepare_onlyoffice_environment() {
local secret current_login_secret instance_id generated=0
secret="$(ctms_read_env_value ONLYOFFICE_JWT_SECRET || true)"
current_login_secret="$(ctms_read_env_value JWT_SECRET_KEY || true)"
instance_id="$(ctms_read_env_value ONLYOFFICE_INSTANCE_ID || true)"
if [[ "$ROTATE_SECRET" -eq 1 || ${#secret} -lt 32 || "$secret" == "$current_login_secret" ]]; then
secret="$(generate_random_hex 32)"
ctms_upsert_env_value ONLYOFFICE_JWT_SECRET "$secret"
generated=1
fi
if [[ -z "$instance_id" ]]; then
instance_id="ctms-dev-$(generate_random_hex 8)"
ctms_upsert_env_value ONLYOFFICE_INSTANCE_ID "$instance_id"
fi
ctms_upsert_env_value ONLYOFFICE_ENABLED true
ctms_upsert_env_value ONLYOFFICE_INTERNAL_URL http://onlyoffice
ctms_upsert_env_value ONLYOFFICE_STORAGE_BASE_URL http://backend:8000
ctms_upsert_env_value ONLYOFFICE_CONFIG_TTL_SECONDS 300
chmod 600 "$CTMS_ENV_FILE"
if [[ "$generated" -eq 1 ]]; then
ctms_ok "已生成新的 ONLYOFFICE 开发密钥并写入 .env(内容不会回显)"
else
ctms_ok "已复用 .env 中现有的 ONLYOFFICE 开发密钥"
fi
ctms_ok "ONLYOFFICE 开发实例标识已就绪: $instance_id"
}
wait_for_url() {
local label="$1" url="$2" attempts="${3:-90}" attempt=1
while [[ "$attempt" -le "$attempts" ]]; do
if curl -fsS "$url" >/dev/null 2>&1; then
ctms_ok "$label 已就绪"
return 0
fi
sleep 2
attempt=$(( attempt + 1 ))
done
ctms_fail "$label 未在预期时间内就绪: $url"
}
main() {
cd "$CTMS_ROOT_DIR"
ctms_require_docker_compose
ctms_require_command curl "macOS 通常已预装;Linux 可执行 apt-get install curl" \
|| ctms_fail "缺少 curl,无法执行启动健康检查"
ctms_step "准备 ONLYOFFICE 开发环境"
prepare_onlyoffice_environment
local -a compose=(
docker compose
-f "$CTMS_ROOT_DIR/docker-compose.dev.yaml"
-p ctms_dev
--profile office
)
ctms_step "校验开发 Compose 配置"
"${compose[@]}" config --quiet
ctms_ok "Compose 配置有效"
ctms_step "构建并启动 Office 预览服务"
"${compose[@]}" up -d --build --force-recreate backend onlyoffice nginx
ctms_step "验证运行状态"
wait_for_url "CTMS 后端" "http://127.0.0.1:8888/readyz" 60
wait_for_url "ONLYOFFICE Document Server" "http://127.0.0.1:8888/onlyoffice/healthcheck" 120
"${compose[@]}" exec -T backend python -c '
from app.core.config import settings
from app.main import app
paths = {route.path for route in app.routes}
required = {
"/api/v1/onlyoffice/attachments/{attachment_id}/config",
"/api/v1/onlyoffice/versions/{version_id}/config",
}
if not settings.ONLYOFFICE_ENABLED:
raise SystemExit("ONLYOFFICE_ENABLED 未生效")
if len(settings.ONLYOFFICE_JWT_SECRET or "") < 32:
raise SystemExit("ONLYOFFICE_JWT_SECRET 未生效")
if not settings.ONLYOFFICE_INSTANCE_ID:
raise SystemExit("ONLYOFFICE_INSTANCE_ID 未生效")
missing = required - paths
if missing:
raise SystemExit(f"后端缺少 ONLYOFFICE 路由: {sorted(missing)}")
print("ONLYOFFICE backend configuration and routes are ready")
'
ctms_ok "ONLYOFFICE 开发预览环境启动完成"
}
main