package jnpf.bizcommon.onlyoffice.entity; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * OnlyOffice 集成参数,绑定 {@code config/shared/jnpf-biz-common.yaml} 的 {@code onlyoffice.*}。 * *
三个 base url 之所以分开而不是共用一个「网关地址」,是因为它们的**视角不同**: * {@code dsPublicUrl} 是浏览器视角(容器名浏览器解析不了),另两个是 DS 容器视角。 * 宿主 java -jar 栈下后两者要覆盖成 host.docker.internal(DS 在容器、网关在宿主)。 */ @Data @Component @ConfigurationProperties(prefix = "onlyoffice") public class OnlyOfficeProperties { /** 浏览器加载编辑器 api.js 的地址,如 http://localhost:20000 */ private String dsPublicUrl; /** DS 回源拉原始文档的网关地址,如 http://cx-gateway:30000 */ private String fileFetchBaseUrl; /** DS 回调后端的网关地址,如 http://cx-gateway:30000 */ private String callbackBaseUrl; /** * 后端反向拉取 DS 产物的地址(后端视角),如 http://cx-onlyoffice。 * *
保存回调里 DS 给的下载 url 用的是**它自己视角**的主机名,后端不一定能直连; * 配了本项就只保留其 path+query 换到这个主机上。留空则原样使用 DS 给的 url。 */ private String dsInternalUrl; /** * 与 DS 容器 JWT_SECRET 同源。后端用它签发编辑器 config,并校验 DS 回调的 * Authorization 头。回调端点在网关白名单内(平台补丁 #9),此密钥是其唯一安全边界。 */ private String jwtSecret; /** 编辑锁心跳超时(分钟)。锁正常由 status 2/4 回调释放,此项是浏览器崩溃等异常场景的兜底 */ private Integer lockTimeoutMinutes = 30; /** * 是否允许在编辑器里下载文档(对应「文件 → 下载为」与顶栏右侧的下载图标)。 * *
默认关闭。⚠️ 它只收界面入口,不是安全边界——{@code /api/file/Image/**} 在网关白名单内、
* 只靠 securityKey 票据鉴权,知道 URL 的人照样能取到原文件。
*/
private boolean allowDownload = false;
/** 是否允许在编辑器里打印(对应「文件 → 打印」与顶栏右侧的打印图标)。默认关闭,同上注意事项 */
private boolean allowPrint = false;
/** 编辑权限判定,见 {@link EditPermission} */
private EditPermission editPermission = new EditPermission();
/** ONLYOFFICE 插件注册表与场景绑定 */
private Plugins plugins = new Plugins();
@Data
public static class Plugins {
/** 插件编码到部署定义的映射 */
private Map 粒度是**菜单/按钮级**,与平台在线表单的单条更新端点一致
* ({@code VisualdevModelDataController#update} 只做 {@code StpUtil.checkPermission})。
* 判定所需的权限码在登录时就已灌进 Sa-Token 会话,纯本地判断、零 Feign 调用。
*
* 为什么不做「记录级」(这一条检验单该不该给这个人改):那属于业务规则,
* 依赖业务表字段(班组、负责人、流程状态),而 biz-common 的准入规则禁止它含单一
* 业务模块的专属逻辑。需要记录级时应由业务模块自行判定后再打开编辑器。
*/
@Data
public static class EditPermission {
/**
* 未登记的 bizModule(或请求根本没带 bizModule)时的取向。
*
* {@code false}(默认)= 放行编辑,只打一条 warn 日志。这是**兼容默认值**:
* 里程碑 3 的最简调用 {@code openOfficeDocument({ file })} 并不传 bizModule,
* 一上来就严格会让所有既有调用方突然变只读。
*
* {@code true} = 一律只读。业务侧把该登记的都登记完之后应当打开它——
* 否则「配置漏登记」这种失误会表现为「悄悄放行编辑」,而不是被人察觉的报错。
*/
private boolean strict = false;
/**
* bizModule → 在线表单 moduleId 的登记表。
*
* 刻意用 List 而不是 Map:Spring Boot Binder 对 Map 是**合并**语义、对 List 是
* **整体替换**,用 Map 的话删掉一条登记根本不生效(audit 的 layer0 注册表踩过这个坑,
* 见 {@code AuditFormRegistry})。
*/
private List ⚠️ 这条是个陷阱位:在线表单只有勾了「启用按钮权限」时,用户的权限表里才会有
* {@code moduleId::btn_edit}。没启用却把本项留成 true,会导致**所有人都被降级只读**。
* 该模块没启用按钮权限时填 false,此时只校验菜单级权限。
*/
private boolean requireBtnEdit = true;
}
}