package jnpf.bizcommon.onlyoffice.service.impl;
|
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
|
/** Shared UI policy: preview and comparison must inherit the same menu defaults. */
|
final class OnlyOfficeUiConfig {
|
private OnlyOfficeUiConfig() { }
|
|
static Map<String, Object> previewCustomization() {
|
return customization(false, false, true);
|
}
|
|
static Map<String, Object> previewPermissions() {
|
return permissions(false, true, false, false);
|
}
|
|
/** 签批页禁止用户下载和打印,编辑器仍可在会话关闭时通过回调回写最终文件。 */
|
static Map<String, Object> qianpiyePermissions(boolean editable, boolean hideComments) {
|
return permissions(editable, hideComments, false, false);
|
}
|
|
static Map<String, Object> permissions(boolean editable, boolean hideComments,
|
boolean allowDownload, boolean allowPrint) {
|
Map<String, Object> permissions = new LinkedHashMap<>();
|
permissions.put("edit", editable);
|
// Both permission and customization switches are needed to hide comments.
|
if (hideComments) {
|
permissions.put("comment", false);
|
permissions.put("review", false);
|
}
|
permissions.put("chat", false);
|
permissions.put("download", allowDownload);
|
permissions.put("print", allowPrint);
|
// This supported permission hides Protection without white-label layout settings.
|
permissions.put("protect", false);
|
return permissions;
|
}
|
|
static void applyReviewPermissions(Map<String, Object> permissions) {
|
permissions.put("edit", false);
|
permissions.put("review", true);
|
permissions.put("fillForms", false);
|
permissions.put("comment", true);
|
permissions.put("reviewGroups", java.util.Collections.emptyList());
|
permissions.put("editCommentAuthorOnly", true);
|
permissions.put("deleteCommentAuthorOnly", true);
|
permissions.put("modifyContentControl", false);
|
}
|
|
static void applyCommentPreviewPermissions(Map<String, Object> permissions) {
|
permissions.put("edit", false);
|
permissions.put("review", false);
|
// With editorConfig.mode=view this exposes existing comments, never a writable session.
|
permissions.put("comment", true);
|
permissions.put("fillForms", false);
|
permissions.put("modifyContentControl", false);
|
}
|
|
static void showReviewComments(Map<String, Object> customization, boolean writable) {
|
customization.put("comments", true);
|
customization.put("hideRightMenu", false);
|
Map<String, Object> review = new LinkedHashMap<>();
|
review.put("showReviewChanges", true);
|
review.put("reviewDisplay", "markup");
|
if (writable) review.put("trackChanges", true);
|
customization.put("review", review);
|
}
|
|
/**
|
* 编辑器界面裁剪。**必须在后端拼进 config**:customization 在 JWT 签名范围内,
|
* 前端往 config 里塞字段会让 DS 验签失败(前端只能追加 events,函数不参与序列化)。
|
*
|
* <p>两类考虑分开看:
|
* <ul>
|
* <li><b>安全</b>:{@code macros}/{@code plugins}。附件是用户上传的外来文档,
|
* 可能带宏;插件(含 AI 入口)会把文档内容发往第三方,都不该默认开着。</li>
|
* <li><b>界面噪音</b>:帮助、反馈、顶栏文件名(弹窗标题已经有了)、右侧面板。
|
* 这些纯属观感,改动无风险。</li>
|
* </ul>
|
*
|
* <p>⚠️ logo / about / layout 那一类属**白标定制**,社区版镜像大概率不生效,故此处不设——
|
* 需要的话得先实测再加,别写了以为生效。
|
*
|
* @param editable 是否可编辑;forcesave/autosave 只在编辑态有意义,顶栏展开与否也随它变
|
*/
|
static Map<String, Object> customization(boolean editable, boolean pluginsEnabled, boolean hideComments) {
|
Map<String, Object> customization = new LinkedHashMap<>();
|
|
// ── 安全 ──
|
// 外来 docx 可能带宏:不自动运行,且不给用户开的入口
|
customization.put("macros", false);
|
customization.put("macrosMode", "disable");
|
// 仅后端白名单场景开启指定插件;空场景仍关闭全部插件入口。
|
customization.put("plugins", pluginsEnabled);
|
|
// ── 界面收敛 ──
|
// 默认关闭拼写检查;用户在界面修改后,localStorage 仍会覆盖这个初始值。
|
Map<String, Object> features = new LinkedHashMap<>();
|
features.put("spellcheck", false);
|
customization.put("features", features);
|
if (hideComments) {
|
// 批注面板的另一半开关,与 permissions.comment=false 必须成对出现。
|
customization.put("comments", false);
|
Map<String, Object> review = new LinkedHashMap<>();
|
review.put("trackChanges", false);
|
review.put("showReviewChanges", false);
|
customization.put("review", review);
|
}
|
customization.put("help", false);
|
customization.put("feedback", false);
|
// 左下角那个「提出功能建议」归 suggestFeature 管,不是 feedback(实测得知)
|
customization.put("suggestFeature", false);
|
// 顶栏不再重复显示文件名——我们的弹窗标题已经有了
|
customization.put("toolbarHideFileName", true);
|
customization.put("hideRightMenu", true);
|
// 顶栏形态按模式分:编辑态展开成完整功能区(工具找得到),只读态收成单行紧凑版
|
// (没有可用的编辑按钮,展开只是白占垂直空间)。这与 DS 自己的默认取向一致,
|
// 但仍显式写出——默认值随版本变过,别指望省略。
|
//
|
// ⚠️ 本项会被浏览器 localStorage 覆盖:用户手动折叠过顶栏,之后打开就一直是折叠的,
|
// 后端传什么都不算数。验证时请换无痕窗口,别以为配置没生效。
|
customization.put("compactToolbar", !editable);
|
|
customization.put("autosave", false);
|
if (editable) {
|
// forcesave:点保存即触发 status 6 回调,不必等全员退出才落盘
|
customization.put("forcesave", true);
|
}
|
return customization;
|
}
|
|
/**
|
* 签批页保留后端签发并自动启动的标注插件,不保存中间版本。
|
* Docs 9.4 将 {@code customization.plugins} 同时用作插件运行时总开关;设为 false
|
* 会让 autostart 失效,不能用它单独隐藏插件管理器入口。
|
*/
|
static Map<String, Object> qianpiyeCustomization(boolean editable, boolean hideComments) {
|
Map<String, Object> customization = customization(editable, true, hideComments);
|
customization.put("autosave", false);
|
customization.put("forcesave", false);
|
return customization;
|
}
|
|
}
|