Laravel 审批页保存 PDF 批注:怎样避免覆盖别人的修改?

AI摘要
【总结】本文属知识分享,围绕PDF批注保存的版本冲突问题,说明Laravel后端应在保存接口中结合权限校验、基础版本比对与原子事务,避免覆盖他人修改;并给出接口设计、409冲突处理及双开页面验收方法。

两位审批人同时修改同一份 PDF 时的版本冲突示意

两个人先后打开同一份报价 PDF,各自加了批注。第一个人保存后,第二个人再保存,如果服务端只按文件 ID 覆盖原路径,第一个人的修改就可能丢失。浏览器里两次都提示成功,也不能证明最后留下了两份意见。

这个问题要在保存接口里处理。PDF 组件负责导出文档,Laravel 应用负责判断:上传的人是否有权限,以及他修改的还是不是当前版本。

打开时,文件和版本一起返回

审批页需要的不只是一条 PDF 下载地址。后端检查用户、审批任务与附件的关系之后,应把文件标识和本次打开的版本一起返回,例如:

{
  "attachmentId": "quote-127",
  "baseRevision": 4,
  "fileUrl": "由应用签发的当前版本访问地址"
}

这是应用接口的设计示例,不是 ComPDF 的返回格式。baseRevision=4 表示用户接下来要修改的起点;文件换成第 5 版时,不能只更新地址却沿用第 4 版的状态。

真实文件地址应从自己的存储和授权流程取得,不要将上面的中文占位值直接填进 viewer。带时效的地址也不替代任务权限检查:用户在审批页能看到附件,不代表他拥有该附件所有历史版本的写权限。

接入 PDF 操作,但别把“导出”当作“归档”

如果需要在审批页查看和批注,可以按 ComPDF Web 接入指南部署组件,先打开一份有权处理的文件,再验证批注与导出路径。Laravel 可以返回页面和文件信息,PDF 的浏览器交互由前端组件完成,不是在 PHP 控制器里调用浏览器实例。

用户点保存时,从当前文档实例取出 PDF 数据,上传到 Laravel 的附件保存接口。ComPDF 的文档保存说明给出了导出数据及上传服务器的接法;身份验证、版本冲突和存储回执由应用补齐。

页面状态至少分为“正在导出、正在上传、已保存、保存失败或版本冲突”。取得 Blob 后还没有服务器保存结果,此时不能把审批页改成已完成。

保存接口,先比版本,再切换当前文件

前端随文件提交 attachmentId 和打开时的 baseRevision。不要用客户端传来的作者名、审批状态或下一版本号直接更新数据库。

后端可以按以下顺序组织:

  1. 用 Laravel Policy 检查当前用户是否能修改该任务与附件;校验上传文件大小及内容,放入隔离的临时位置。
  2. 开启数据库事务,锁定对应附件记录,读取当前修订号。版本检查必须与更新当前修订在同一原子操作中,不能检查完就放开锁再改。
  3. 比较提交的基础版本。如果当前已经是 5,而用户交来的基础版本仍是 4,返回版本冲突,不覆盖第 5 版。
  4. 版本一致时,建立新修订记录,将文件存入唯一、不可被旧任务覆盖的路径;存储成功后再更新当前修订及操作者。
  5. 提交成功后返回新版本信息;存储失败或数据库提交失败时,应回滚当前引用,并清理或单独回收孤立文件。

文件存储与数据库事务不是同一件事,回滚数据库不会自动删除已经上传的文件。采用哪种“暂存、提交、清理”方案要看本地磁盘或对象存储的条件,不能用一段事务代码就声称文件和记录天然一致。

文件保存与审批状态需要由应用分别处理

图:应用保存流程示意,不是组件自动提供的版本管理。

冲突时,不能自动覆盖或拼成一份

接口可以用 HTTP 409 表示版本已变化,并返回当前修订号。页面提示“这份文件已有更新,请重新打开后核对”,保留用户当前的修改,提供另存本地副本或取消操作的选择。

不要把“重试”写成无条件覆盖。两份带批注的 PDF 并不适合靠拼接字节合并;是否合并注释,需要字段标识、坐标、文档版本和组件导入导出能力都能对应,还要解决同一意见被编辑或删除的问题。没有做过这些处理,就让用户重新核对,保留两个来源版本。

同样,保存副本和同意审批应分开。文件上传成功后,业务还可能需要检查意见、确认人和审批条件,不能直接进入下一节点。

上线前,双开页面走一遍

不用复杂压测就能先检查最容易丢修改的一条路径:

  • A、B 两个页面都打开第 4 版,分别加上可区分的批注。
  • A 保存,服务端生成第 5 版;重新打开第 5 版检查 A 的意见确实存在。
  • B 保存,提交的仍应是基础版本 4,接口应拒绝覆盖并提示冲突。
  • B 的页面保留未提交内容,不因失败就清空;A 的第 5 版保持不变。
  • 换成无修改权限的用户,直接调用保存接口,后端仍应拒绝。
  • 模拟上传或存储失败,检查当前版本没有指向缺失文件,也没有把审批状态提前标为完成。

这是一套可自行执行的接入与验收方法,不代表浏览器组件自动提供协同编辑或业务版本管理。先把“一人保存、另一人不丢修改”做对,再考虑自动保存、多人协作或注释合并。

选择 ComPDF 是为了解决 PDF 页面交互、批注和文件导出;把这些产物接成可靠审批,仍需要 Laravel 把权限、基础版本、存储和回执连起来。下次排查“批注怎么没了”时,先看导出的文件有没有意见,再看保存接口是否覆盖了别人的版本,两个问题就能分开定位。

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
42
粉丝
2
喜欢
7
收藏
9
排名:1391
访问:2800
私信
所有博文
社区赞助商