刘光辉
14 小时以前 34981c30a78e8bbd7791131059a9210f9928b62c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
onlyoffice:
  # 浏览器加载编辑器 api.js 的地址。注意这是**浏览器视角**的地址,不是容器视角——
  # 容器名 cx-onlyoffice 浏览器解析不了,本机开发走 override 发布的 20000 端口。
  # 交付环境改为 Nginx 反代的 https://<域名>/onlyoffice(方案 §8.4)。
  ds-public-url: ${ONLYOFFICE_DS_PUBLIC_URL:http://localhost:20000}
 
  # 给 DS 回源拉原始文档用(DS 视角)。路径 /api/file/Image/** 在 GatewayWhite
  # 硬编码白名单内,DS 无登录态也能取,靠 URL 上的 securityKey 票据鉴权。
  # 宿主 java -jar 栈需覆盖为 http://host.docker.internal:30000(DS 在容器、网关在宿主)。
  file-fetch-base-url: ${ONLYOFFICE_FILE_FETCH_BASE_URL:http://cx-gateway:30000}
 
  # 给 DS 回调后端用(DS 视角)。必须经网关——直连 30015 按 L042 会被 inner-auth 拒,
  # 而 DS 不是 JNPF 服务、注入不了 SA-SAME-TOKEN。回调路径已进网关白名单(平台补丁 #9)。
  callback-base-url: ${ONLYOFFICE_CALLBACK_BASE_URL:http://cx-gateway:30000}
 
  # 后端反向拉取 DS 产物的地址(后端视角)。保存回调里 DS 给的下载 url 用的是它自己
  # 视角的主机名,后端不一定能直连;配了本项就只保留其 path+query 换到这个主机上。
  # 留空则原样使用 DS 给的 url。宿主 java -jar 栈需覆盖为 http://localhost:20000。
  ds-internal-url: ${ONLYOFFICE_DS_INTERNAL_URL:http://cx-onlyoffice}
 
  # 与 DS 容器的 JWT_SECRET 同源(都读 .env 的 ONLYOFFICE_JWT_SECRET)。
  # 后端用它签发编辑器 config,并校验 DS 回调的 Authorization: Bearer。
  # 🔴 回调端点匿名可达(白名单放行),这个 secret 是它唯一的安全边界。
  # 无默认值:缺失即启动失败,避免用空串静默跑起来后回调全被拒、且日志不明显。
  jwt-secret: ${ONLYOFFICE_JWT_SECRET}
 
  # 编辑锁的心跳超时(分钟)。锁正常由 status 2/4 回调释放;浏览器崩溃等异常
  # 场景下靠这个兜底,否则文档会永久锁死。见方案 §6.2。
  lock-timeout-minutes: ${ONLYOFFICE_LOCK_TIMEOUT_MINUTES:30}
 
  # 编辑器里是否给下载/打印入口(「文件 → 下载为」「文件 → 打印」与顶栏右侧那两个图标)。
  # 默认全关。
  # ⚠️ 这两项只收界面入口,**不是安全边界**:/api/file/Image/** 在网关白名单内、只靠
  #   securityKey 票据鉴权,知道 URL 的人照样能把原文件拉走。真正的下载管控要落在文件服务层。
  # 需要按人区分时,用 edit-permission 那套 bizModule→moduleId 登记表判
  #   moduleId::btn_download / btn_batchPrint(PermissionConst 里已有这两个码),机制现成。
  allow-download: ${ONLYOFFICE_ALLOW_DOWNLOAD:false}
  allow-print: ${ONLYOFFICE_ALLOW_PRINT:false}
 
  # ELN 模板标注插件。公网基础地址从部署环境注入,release 由不可变发布目录决定。
  plugins:
    definitions:
      eln-template-annotator:
        guid: asc.{2D6D6CB6-F6FC-45B7-8EC7-0CC1940F1A6F}
        version: 0.1.0
        public-base-url: ${ONLYOFFICE_PLUGIN_PUBLIC_BASE_URL:http://localhost:4173/onlyoffice-plugins}
        release: ${ONLYOFFICE_PLUGIN_RELEASE:0.1.0-dev}
        api-base-url: ${ONLYOFFICE_PLUGIN_API_BASE_URL:http://localhost:30000}
      eln-template-filler:
        guid: asc.{7F4E8F35-5D66-47F8-A5B4-6AB3FAACF565}
        version: 0.1.0
        public-base-url: ${ONLYOFFICE_PLUGIN_PUBLIC_BASE_URL:http://localhost:4173/onlyoffice-plugins}
        release: ${ONLYOFFICE_PLUGIN_RELEASE:0.1.0-dev}
        api-base-url: ${ONLYOFFICE_PLUGIN_API_BASE_URL:http://localhost:30000}
    scenes:
      - biz-scene: eln.template.annotate
        biz-module: eln.template
        plugin-codes:
          - eln-template-annotator
        autostart-plugin-code: eln-template-annotator
        disabled-plugin-guids:
          - asc.{AA2EA9B6-9EC2-415F-9762-634EE8D9A95E}
      - biz-scene: eln.template.fill
        biz-module: eln.template
        plugin-codes:
          - eln-template-filler
        autostart-plugin-code: eln-template-filler
        disabled-plugin-guids:
          - asc.{AA2EA9B6-9EC2-415F-9762-634EE8D9A95E}
 
  # ── 谁能编辑(里程碑 4,方案 §6.1)───────────────────────────────────────────
  # 粒度是**菜单/按钮级**,和平台在线表单的单条更新端点一个口径(那边也只做
  # StpUtil.checkPermission,数据范围只用于列表 WHERE)。权限码登录时已进 Sa-Token
  # 会话,判定纯本地、无远程调用。
  #
  # 做不到「记录级」(这一条检验单该不该给这个人改)是有意为之:那要读业务表的班组/
  # 负责人/流程状态,属于业务规则,biz-common 的准入规则禁止它含单一业务模块的专属逻辑。
  # 需要记录级时,由业务模块自己判完再打开编辑器。
  edit-permission:
    # 未登记的 bizModule(或请求压根没带 bizModule)时的取向。
    #   false(默认)= 放行编辑 + 一条 warn。兼容默认值:前端最简调用
    #     onlineUtils.openOfficeDocument({ file }) 并不传 bizModule,一上来就严格会
    #     让所有既有调用方突然全变只读。
    #   true = 一律只读。**该登记的都登记完之后应当打开它**——否则「漏登记」的表现是
    #     悄悄放行编辑,而不是能被人发现的报错。
    strict: ${ONLYOFFICE_EDIT_PERMISSION_STRICT:false}
 
    # bizModule → 在线表单 moduleId 的登记表。业务侧自助加行,不用改 biz-common 代码。
    # 用 List 不用 Map:Spring Boot Binder 对 Map 是合并语义、对 List 是整体替换,
    # 写成 Map 的话删掉一条登记根本不生效(audit 的 layer0 注册表踩过这个坑)。
    #
    # ⚠️ require-btn-edit 是陷阱位:在线表单只有勾了「启用按钮权限」,用户权限表里才会有
    #   <moduleId>::btn_edit。没启用却留 true,结果是**所有人都被降级只读**。
    #   该表单没启用按钮权限时填 false,此时只校验菜单级权限。
    #
    # modules:
    #   - biz-module: lims_jianyan_baogao
    #     module-id: '507748874527276549'   # base_module.f_id
    #     require-btn-edit: true
    modules: []
# ══ 2026-08-11:由 jnpf-audit.yaml 迁移而来 ══
# audit 搬入 biz-common、jnpf-audit-server 退役后,原 config/shared/jnpf-audit.yaml 已删除。
# 该文件里唯一的活配置就是下面这行日志级别,**必须跟着服务名一起迁移**:
# logback-spring.xml 取的是 `log.level.<spring.application.name>`
#   (jnpf-biz-common-server/src/main/resources/logback-spring.xml:14
#    <springProperty ... source="log.level.jnpf-biz-common"/>),
# 服务名从 jnpf-audit 变成 jnpf-biz-common,原来那行 `log.level.jnpf-audit` 就再也不会被读到——
# 表现不是报错,而是**审计消费/落库链路的 log.info 被共享 logger.yaml 的 root: ERROR 静默压掉**。
#
# 原 jnpf-audit.yaml 中另一段(AUDIT_EVENT 的 Spring Cloud Stream binding 为何必须移除)
# 已随降级链第一级 MQ 一并作废,其历史论证转记于
# docs/handoff-2026-08-11-audit-into-biz-common.md,不在配置文件里留存。
log:
  level:
    # 共享 logger.yaml 把 log.level.root 压到 ERROR;本文件在 application.yml 的
    # spring.config.import 列表里排在 logger.yaml 之后,优先级更高,这里覆盖回 INFO
    # 让审计消费/落库链路的 log.info 可见,不动共享文件。
    jnpf-biz-common: INFO