合同在线编辑设计:富文本 + OnlyOffice 双模式统一、占位域填充与正文回存
合同在线编辑设计富文本 OnlyOffice 双模式统一、占位域填充与正文回存演示地址http://ruoyioffice.com | 源码1·GitHubruoyi-office | 源码2·GitCoderuoyi-office | 源码3·Giteeruoyi-office | 微信17156169080备注「RuoYi Office」“把合同下载下来改完再传回系统”——这套流程听着天经地义却藏着无数断层改完忘传、传错版本、多人各改各的、正文和系统数据对不上。文档编辑本该发生在系统里而不是在某个人的电脑桌面上。合同在线编辑要解决的核心工程问题是让打开-编辑-保存这条链路完全发生在浏览器里且轻量场景富文本和高保真场景OnlyOffice能用同一套接口统一切换、正文能可靠回存。本文以 RuoYi Office 的合同在线编辑实现为样本从前端组件到后端回存把这条链路完整拆开面向前端/全栈开发者与实施顾问。▲ 合同在线编辑全景① 前端请求编辑配置后端按 editorMode 返回 richtext / onlyoffice→ ② 动态加载文档服务器 api.js → ③ 初始化 DocEditor下发编辑权限与用户 → ④ 编辑保存触发回调 → ⑤ 后端按 bizType 回存 contentHtml 或 contractDocUrl引言在线编辑难在统一 可靠回存文档在浏览器里改听着简单做成工程能力要回答一连串问题难点一轻重场景如何统一。简单确认函用富文本足矣正式合同要 Word 级高保真——如果两种编辑器给业务两套完全不同的接口和交互维护和体验都是灾难。难点二编辑器脚本怎么加载。OnlyOffice 靠文档服务器的api.js驱动前端要动态注入、且同地址只能加载一次重复注入会冲突。难点三谁能编、谁只能看。同一份文档起草人能编、审批人只能看——编辑权限必须从后端下发不能前端自己说了算。难点四保存怎么可靠回存。富文本存 HTML 字段、OnlyOffice 存 Word 文件两条链路不同且文档服务器是异步回调保存回存的文件必须唯一命名否则缓存导致改了不刷新。朴素做法问题下载改完再上传断层、传错版两种编辑器两套接口维护/体验割裂前端控制可编辑权限不可信回存同名覆盖缓存不刷新RuoYi Office 的解法是把在线编辑做成模式统一切换 动态加载 权限下发 双链路回存的工程闭环。下面拆开看。一、功能拆解在线编辑链路的组成一条可靠的在线编辑链路由这几块构成环节职责关键点模式决策选富文本还是 OnlyOffice配置统一全局一致配置下发后端构建编辑器配置文档 key、权限、回调脚本加载前端加载 api.js同地址只加载一次编辑器初始化渲染 DocEditor下发用户/语言/权限保存回存回调回存正文HTML / Word 双链路价值在于让在线编辑对业务是一套体验对系统是可靠回存的数据彻底告别下载-上传的断层。二、模式统一一套配置决定编辑方式系统不让用户在界面上选编辑器而是由配置统一决定避免同一份数据出现两种编辑体验OverridepublicStringgetEditorMode(){// 显式配置优先未配置时按 enabled 推断StringconfiguredStrUtil.trimToNull(properties.getEditorMode());if(configured!null){returnEDITOR_MODE_RICHTEXT.equalsIgnoreCase(configured)?EDITOR_MODE_RICHTEXT:EDITOR_MODE_ONLYOFFICE;}// 启用且配了文档服务器地址 → onlyoffice否则 → richtextreturnisEnabled()?EDITOR_MODE_ONLYOFFICE:EDITOR_MODE_RICHTEXT;}模式触发条件载体适用richtext未启用 OnlyOfficecontentHtml字段轻量、免部署onlyoffice启用且配了 server-urlWord 文件 URL高保真、协作为什么要配置统一而不是用户选因为编辑方式一旦不统一同一类合同就会一半是 HTML、一半是 Word正文格式、导出、预览全乱套。把选择权收到配置层全公司合同模板与正文始终一种编辑方式数据形态才可控。三、前端链路动态加载与初始化前端用一个通用组件封装 OnlyOffice先向后端要配置再动态加载api.js最后实例化编辑器。核心是同地址脚本只加载一次与权限、事件回调完整下发constresultawaitgetOnlyOfficeConfig({fileUrl:props.fileUrl,fileName:props.fileName,editable:props.editable,bizType:props.bizType,bizId:props.bizId,});awaitloadApiScript(result.documentServerUrl);// 同地址只注入一次 api.jsconstDocsAPI(windowasany).DocsAPI;constconfig{...result.config,events:{onAppReady:(){loading.valuefalse;emit(ready);},onError:(e:any){error.valueOnlyOffice 错误${e?.data};},},};editorInstancenewDocsAPI.DocEditor(containerId,config);// 渲染编辑器后端构建配置时把编辑权限、当前登录用户一并下发——edit权限来自后端判定避免前端伪造下发用户名则免去 OnlyOffice 弹输入协作名称配置项作用permissions.edit是否可编辑后端下发editorConfig.modeedit / vieweditorConfig.user当前登录用户协作留痕customization.autosave/forcesave自动/强制保存callbackUrl保存回调地址富文本模式则更简单正文即contentHtml前端富文本编辑器直接读写该字段保存时随合同一起提交无需文档服务器。四、后端回存两条链路同一套回调OnlyOffice 是异步保存用户编辑后文档服务器在可保存/强制保存时回调后端后端下载编辑后的文件、唯一命名落盘再按业务类型回存到模板或合同// 仅在 status2(可保存) / 6(强制保存) 时回存if(statusnull||(status!2status!6))return;byte[]contentHttpUtil.downloadBytes(editedUrl);// 文件名带时间戳保证唯一避免同名覆盖导致 key 不变、读旧缓存StringuniqueNameFileUtil.mainName(fileName)_System.currentTimeMillis().ext;StringnewUrlStrUtil.subBefore(fileApi.createFile(content,uniqueName,contract,mime),?,false);if(BIZ_TYPE_TEMPLATE.equals(bizType)){templateService.updateTemplateDocFileUrl(bizId,newUrl);// 回存模板}elseif(BIZ_TYPE_CONTRACT.equals(bizType)){contractInfoService.updateContractDocUrl(bizId,newUrl);// 回存合同正文}编辑模式保存触发回存目标唯一性保障富文本表单提交contentHtml随合同一次写入OnlyOffice文档服务器异步回调contractDocUrl/docFileUrl文件名带时间戳为什么回存文件要带时间戳唯一命名因为 OnlyOffice 用文档 key识别文档版本key 随文件 URL 变化若回存时同名覆盖、URL 不变文档服务器会命中旧缓存表现为明明改了保存了重新打开还是旧内容。时间戳唯一命名让每次保存都产生新 URL、新 key从根上杜绝这个经典坑更多 key 与部署细节见《OnlyOffice 集成实战》。五、页面深拆从起草到附件预览合同起草列表进入起草页即打开在线编辑器编辑体验统一。▲ 合同起草从起草列表进入在线拟稿页按配置以富文本或 OnlyOffice 打开正文附件表单预览编辑与只读预览复用同一套文件基础设施权限决定 edit/view。▲ 附件与正文编辑态与只读预览态复用同一文件链路权限从后端下发文件中心编辑回存的每一版文件都进入文件中心可追溯可下载。▲ 文件中心OnlyOffice 每次回存生成带时间戳的新文件历史版本可追溯六、选型视角在线编辑的价值在无断层 可回存在线编辑方案很多工程上的分水岭在于统一与可靠维度下载改传富文本 OnlyOffice 双模协作断层严重全程在线体验一致各改各的配置统一一种权限控制无后端下发 edit/view保存可靠靠人上传双链路自动回存场景适配一刀切轻重各取所需一句话在线编辑的价值不在能在网页里打字而在让编辑无断层、让保存可回存、让轻重场景用一套体验。模式统一守住一致、权限下发守住可信、双链路回存守住可靠——这三点是下载改传永远补不上的。七、方案亮点亮点说明价值模式统一切换editorMode 配置决定数据形态可控api.js 安全加载同地址只注入一次避免脚本冲突权限后端下发edit/view 不可伪造编辑权限可信双链路回存HTML / Word 分流轻重场景通吃唯一命名回存时间戳新 URL杜绝缓存不刷新八、常见问题 FAQQ1不部署 OnlyOffice 能用在线编辑吗能。未启用 OnlyOffice 时系统自动回落到富文本模式richtext正文存contentHtml零额外部署即可在线编辑适合轻量场景。Q2富文本和 OnlyOffice 能混用吗不建议。系统按全局配置统一一种编辑方式避免同类合同一半 HTML 一半 Word 导致格式/导出混乱如需切换应统一配置而非让用户逐份选择。Q3多人同时编辑一份合同会冲突吗OnlyOffice 模式支持多人协同编辑下发登录用户身份由文档服务器处理协同富文本模式为单人编辑适合无需协同的轻量场景。Q4编辑保存后为什么有时看着没变多为文档 key/文件 URL 未随内容变化导致读旧缓存。本方案回存时用时间戳唯一命名生成新 URL、新 key正是为了避免此问题若自研集成需特别注意 key 生成规则。Q5审批人能改合同正文吗由后端下发的editable决定。通常起草人可编辑、审批人只读配合模板contentEditable锁定可进一步禁止对标准条款的二次编辑。Q6回存的历史版本能找回吗可以。OnlyOffice 每次回存生成带时间戳的新文件并纳入文件服务历史文件可追溯模板侧还会写版本表留痕便于对比与回滚。结语文档编辑不该发生在某个人的电脑桌面上。RuoYi Office 把合同在线编辑做成模式统一切换 动态加载 权限下发 双链路回存的工程闭环用配置统一编辑方式、用后端下发编辑权限、用时间戳唯一命名保证可靠回存让富文本的轻量与 OnlyOffice 的高保真收敛到同一套业务体验里。对开发者来说在线编辑的意义不是引入一个编辑器控件而是让打开-编辑-保存这条链路彻底闭合在系统内——正文与数据从此不再两张皮。演示地址http://ruoyioffice.com | 源码·Giteeruoyi-office | 微信17156169080备注「RuoYi Office」