Documents 的“请求文件”在产品上看起来很轻:填名字、选请求人、给个截止日期,然后对方上传即可。但在企业版实现里,它其实串起了 documents.document、mail.activity、访问控制和模板邮件四层逻辑。
主要参考:
enterprise/documents/wizard/documents_request_wizard.pyenterprise/documents/models/mail_activity.pyenterprise/documents/models/documents_access.py
一、request wizard 先创建的不是 activity,而是文档壳
request_document() 一开始就会创建一个 documents.document,把名称、文件夹、标签、联系人、请求对象、业务记录关联都放进去。此时往往还没有真实附件,但系统已经有了一个“将来要上传到哪里的文档容器”。
这也是 Documents 区别于普通待办的地方:它不是提醒你“去做某事”,而是先占好了未来文件的归档位置。
二、upload_file 类型 activity 才是执行层待办
文档壳建好后,wizard 再调 activity_schedule() 生成 upload_file 类型活动。mail.activity 扩展会把这种 activity 和 documents 记录双向绑定起来,必要时甚至能从 activity 反向补建 document。
所以 request 流程里,document 和 activity 是两层:
- document 解决归档与访问
- activity 解决提醒、截止日期和执行动作
三、访问控制在“请求阶段”和“上传完成后”并不一样
这是整个链路里最容易被忽视的地方。
在请求阶段,如果 requestee 有内部用户,系统会给他带截止时间的编辑权;如果对方没有用户,只能退化为 access_via_link='edit',让他通过链接上传。
但等 _action_done() 跑完后,若之前为了外部上传而临时开放了 edit 链接权限,系统会把它降级成 view。也就是说,上传通道只是临时开的,不是永久写权限。
四、附件回填与 request 收口是一次性完成的
当上传 activity 被 done 且带有 attachment_ids 时,源码会把附件回填到原先那个“空的 documents.document”上,然后清掉:
requestee_partner_idrequest_activity_id
这一步收口后,请求态就结束了,文档进入正常存量状态。它不再是“待上传请求”,而是一份已经实际存在的 Documents 记录。
五、连续请求为什么能工作:next activity 会继续造 document
_prepare_next_activity_values() 里对连续 upload_file 类型 activity 做了特殊处理。如果你把一个上传请求串到下一个上传请求,系统会再创建新的 document 壳,而不是让多个阶段共用同一个空文档。
这说明官方模型设计里,请求是阶段性的,每个请求节点最好有自己的文档承载物。这样到期、权限和实际附件才不会缠在一起。
六、实战建议
如果你要二开供应商补资料、客户上传合同、员工交证明文件之类的场景,最稳的方式不是自己发一封上传邮件,而是复用 Documents request 流程。原因很现实:
- 归档位置天然确定
- 截止时间天然可追踪
- 上传后权限天然收口
- activity 和文档天然互相关联
Documents 请求文件功能的真正价值,不在“提醒别人上传”,而在把上传这件事变成一条可归档、可控权、可收尾的业务链。
DISCUSSION
评论区