【流程】公文管理
公文管理,由 yudao-module-oa 后端模块的 officialdoc 包实现,前端实现在 @/views/oa/officialdoc/template、@/views/oa/officialdoc/send、@/views/oa/officialdoc/receive 目录。
公文管理按「套红模板 → 公文发文 → 公文收文」组织。发文走 BPM 审批,通过后按主送、抄送部门生成收文;主送收文需签收并走办理审批,抄送仅知会、不发起流程。
本文涉及表如下图所示:
# 1. 套红模板
套红模板,由 OaOfficialDocTemplateController 提供接口(/oa/officialdoc-template)。
# 1.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
套红模板表 oa_official_doc_template,保存公文红头的发文机关、字号前缀、字体和印章图片:
CREATE TABLE `oa_official_doc_template` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`name` varchar(128) NOT NULL COMMENT '模板名称',
`authority_name` varchar(255) NOT NULL COMMENT '红头名称',
`font_size` int NOT NULL COMMENT '红头名称字号',
`no_prefix` varchar(64) DEFAULT NULL COMMENT '发文字号前缀',
`seal_pic_url` varchar(2048) DEFAULT NULL COMMENT '印章图片地址',
`separator_type` int NOT NULL COMMENT '分隔线类型',
`status` int NOT NULL COMMENT '状态',
`sort` int NOT NULL COMMENT '显示顺序',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='套红模板';
① 模板保存发文机关名称(authority_name)、字号前缀、字体大小和分隔线样式。发文选择启用模板后,正文与正式公文文件保存在发文单中,不会随模板后续修改联动已存发文。
② seal_pic_url 是平台图片上传得到的 URL,不关联印章台账 oa_seal 的 id 字段,与用印管理无关。
③ 枚举 separator_type 分隔线类型,对应字典 oa_official_doc_separator_type:
| 值 | 说明 |
|---|---|
0 | 单线 |
1 | 双线 |
④ status 使用通用启用、停用状态(CommonStatusEnum):0 开启、1 关闭。发文提交时由 validateOfficialDocTemplate 校验,停用模板不能用于新增发文,抛出 OFFICIAL_DOC_TEMPLATE_DISABLED 异常。
# 1.2 管理后台
对应 [OA 办公协同 -> 公文管理 -> 套红模板] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/officialdoc/template 目录。
# 列表

# 新增与修改
点击【新增】打开 OaOfficialDocTemplateForm.vue,填写模板名称、发文机关、字号前缀、字体大小和印章图片,设置状态及排序后保存。

# 停用与删除
停用模板后不再用于新增发文选择。删除模板不删除已关联的发文记录。
# 2. 公文发文
公文发文,由 OaOfficialDocSendController 提供接口(/oa/officialdoc-send)。
# 2.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
公文发文表 oa_official_doc_send,保存发文的标题、字号、密级、主送抄送部门和审批状态:
CREATE TABLE `oa_official_doc_send` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`no` varchar(64) DEFAULT NULL COMMENT '单据编号',
`template_id` bigint NOT NULL COMMENT '套红模板编号',
`title` varchar(255) NOT NULL COMMENT '标题',
`no_prefix` varchar(64) DEFAULT NULL COMMENT '发文字号前缀',
`year` int DEFAULT NULL COMMENT '发文年度',
`sequence` int DEFAULT NULL COMMENT '发文序号',
`document_no` varchar(64) DEFAULT NULL COMMENT '公文文号',
`secrecy_level` int NOT NULL COMMENT '密级',
`urgency_level` int NOT NULL COMMENT '紧急程度',
`disclosure_type` int NOT NULL COMMENT '公开类别',
`issue_time` datetime NOT NULL COMMENT '发文时间',
`send_dept_id` bigint NOT NULL COMMENT '发文部门编号',
`main_dept_ids` json NOT NULL COMMENT '主送部门编号列表',
`copy_dept_ids` json DEFAULT NULL COMMENT '抄送部门编号列表',
`signer_user_id` bigint DEFAULT NULL COMMENT '签发人用户编号',
`content` text COMMENT '正文',
`file_urls` json DEFAULT NULL COMMENT '附件地址列表',
`formal_file_url` varchar(2048) DEFAULT NULL COMMENT '正式公文地址',
`remark` varchar(500) DEFAULT NULL COMMENT '附注',
`status` int DEFAULT NULL COMMENT '审批状态',
`process_instance_id` varchar(64) DEFAULT NULL COMMENT 'BPM 流程实例编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='公文发文';
① template_id 关联 oa_official_doc_template 表的 id 字段;send_dept_id 关联 system_dept 表的 id 字段。signer_user_id 关联 system_users 表的 id 字段,DO / 响应 VO 有该字段,但 OaOfficialDocSendSaveReqVO 未暴露,创建与更新接口不能写入签发人。
② 业务单号 no 由 OaNoRedisDAO 以 FW 为前缀生成(如 FW20260913000001),与正式公文字号 document_no 分别保存。document_no 是冗余组合字段,由 buildOfficialDocSendDocumentNo 按「前缀 + 〔年度〕 + 序号 + 号」拼成,例如 测试〔2026〕1号;三段均可为空,缺省时对应片段直接省略。
③ main_dept_ids、copy_dept_ids 以 JSON 数组保存部门编号;file_urls 是其他附件,formal_file_url 是正式公文地址,不能混为同一个字段。JSON 结构如下:
main_dept_ids / copy_dept_ids(部门编号列表)与 file_urls(附件)
主送、抄送部门是 List<Long>,库中存为 JSON 数组;主送不能为空,抄送可空:
{
"main_dept_ids": [10, 11],
"copy_dept_ids": [12]
}
file_urls 是附件地址列表:
["https://example.com/attachment.pdf"]
④ 枚举字段对应字典:
| 字段 | 字典 | 取值 |
|---|---|---|
secrecy_level | oa_official_doc_secret_level | 0 公开 / 1 内部 / 2 秘密 / 3 机密 / 4 绝密 |
urgency_level | oa_official_doc_urgency_level | 0 普通 / 1 急件 / 2 特急 |
disclosure_type | oa_official_doc_public_category | 0 主动公开 / 1 依申请公开 / 2 不予公开 |
⑤ status 是 BPM 审批状态,process_instance_id 关联流程实例。详见 §2.2 状态流转。发文审批通过后,按主送、抄送部门生成收文,oa_official_doc_receive.send_id 关联原发文。
# 2.2 状态流转
发文审批状态由 OaOfficialDocSendServiceImpl 与 BPM 共同控制,status 复用 BpmProcessInstanceStatusEnum,对应字典 bpm_process_instance_status(字典数据通常不含 -1,-1 仅表示业务侧尚未发起流程的草稿):
| 状态值 | 枚举 | 说明 | 可执行操作 |
|---|---|---|---|
-1 | NOT_START | 未开始(草稿) | 编辑、删除、提交 |
1 | RUNNING | 审批中 | 撤销 |
2 | APPROVE | 审批通过 | —(已生成收文) |
3 | REJECT | 审批不通过 | — |
4 | CANCEL | 已取消 | — |
流程定义 Key 为 oa_official_doc_send(BpmModelConstants.OFFICIAL_DOC_SEND)。
状态流转说明
新增发文 ──→ 草稿(-1) ──提交──→ 审批中(1) ──┬──通过──→ 审批通过(2) → 按主送/抄送生成收文
↑ ├──不通过──→ 审批不通过(3)
└──── 仅草稿可改 ───────────────┴──撤销──→ 已取消(4)
- 创建 / 修改(
createOfficialDocSend/updateOfficialDocSend):状态固定为未开始(-1)。只有草稿可以修改和删除,由本人操作校验。 - 提交(
submitOfficialDocSend):草稿(-1)→审批中(1),发起oa_official_doc_send流程,businessKey = id。提交前再次校验模板启用与部门合法。 - 撤销(
cancelOfficialDocSend):仅审批中(1)可调用,原因文案为「申请人撤销公文发文」,终态由 BPM 事件回写为已取消(4)。 - 审批回调(
updateOfficialDocSendStatus,监听器OaOfficialDocSendStatusListener):若当前已非审批中(1)则直接返回,避免重复生成收文;审批通过(2)时调用createOfficialDocReceiveListByOfficialDocSend,按main_dept_ids生成主送收文、按copy_dept_ids生成抄送收文(同部门同类型不重复)。
# 2.3 管理后台
对应 [OA 办公协同 -> 公文管理 -> 公文发文] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/officialdoc/send 目录。
# 列表

# 新增与修改
点击【新增】打开 OaOfficialDocSendForm.vue,选择模板,填写标题、发文字号、密级、紧急程度、公开类别、日期、发文部门、主送和抄送部门及正文,上传正式公文和附件后保存。

# 提交与撤销
在列表点击【提交】,调用 POST /oa/officialdoc-send/submit 发起 oa_official_doc_send 流程;审批中可撤销,调用 PUT /oa/officialdoc-send/cancel。未提交草稿可以修改、删除。
# 查看详情
点击单据进入 @/views/oa/officialdoc/send/detail/index.vue,查看发文内容、正式公文、附件和审批状态。审批进度复用 BPM 流程详情。

# 3. 公文收文
公文收文,由 OaOfficialDocReceiveController 提供接口(/oa/officialdoc-receive)。
# 3.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
公文收文表 oa_official_doc_receive,保存来文登记、签收和办理情况,可关联内部发文:
CREATE TABLE `oa_official_doc_receive` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`no` varchar(64) DEFAULT NULL COMMENT '单据编号',
`send_id` bigint DEFAULT NULL COMMENT '来源发文编号,手工收文为空',
`receive_type` int NOT NULL COMMENT '收文类型',
`title` varchar(255) DEFAULT NULL COMMENT '标题',
`document_no` varchar(64) DEFAULT NULL COMMENT '来文字号',
`secrecy_level` int DEFAULT NULL COMMENT '密级',
`urgency_level` int DEFAULT NULL COMMENT '紧急程度',
`receive_time` datetime DEFAULT NULL COMMENT '收文时间',
`receive_dept_id` bigint NOT NULL COMMENT '收文部门编号',
`handler_user_id` bigint DEFAULT NULL COMMENT '主办人用户编号',
`instruction` text COMMENT '领导批示',
`result` text COMMENT '办理结果',
`deadline_time` datetime DEFAULT NULL COMMENT '办理期限',
`summary` text COMMENT '内容摘要',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`file_urls` json DEFAULT NULL COMMENT '附件地址列表',
`formal_file_url` varchar(2048) DEFAULT NULL COMMENT '正式公文地址',
`handle_status` int DEFAULT NULL COMMENT '办理状态',
`status` int DEFAULT NULL COMMENT '审批状态',
`process_instance_id` varchar(64) DEFAULT NULL COMMENT 'BPM 流程实例编号',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='公文收文';
① 收文可以由发文审批通过后自动生成,也可以手工登记。自动生成的收文通过 send_id 关联 oa_official_doc_send 表的 id 字段,手工收文该字段为空。业务单号 no 以 SW 为前缀生成。
② receive_dept_id 关联 system_dept 表的 id 字段,handler_user_id 关联 system_users 表的 id 字段。分页按当前用户所属部门过滤 receive_dept_id。
③ 枚举 receive_type 收文类型(OaOfficialDocReceiveTypeEnum),对应字典 oa_official_doc_receive_type:
| 值 | 枚举 | 说明 |
|---|---|---|
0 | MAIN | 主送(需办理,可提交 BPM) |
1 | COPY | 抄送(仅知会,禁止提交审批) |
④ handle_status 是办理状态,与 BPM 审批状态 status 分别维护。详见 §3.2 状态流转。
⑤ 由发文自动生成的收文,file_urls、formal_file_url 在编辑时只读,不可通过 update 替换或清空。
# 3.2 状态流转
收文同时维护两套状态:
办理状态 handle_status(OaOfficialDocHandleStatusEnum),对应字典 oa_official_doc_handle_status:
| 状态值 | 枚举 | 说明 | 可执行操作 |
|---|---|---|---|
0 | WAIT_CLAIM | 待签收 | 本部门签收 |
1 | CLAIMED | 已签收 | 填写办理资料、主送可提交 |
2 | PROCESSING | 办理中 | 撤销审批 |
3 | COMPLETED | 已办结 | — |
审批状态 status 同样复用 BpmProcessInstanceStatusEnum / 字典 bpm_process_instance_status(-1/1/2/3/4,字典通常无 -1)。流程定义 Key 为 oa_official_doc_receive。仅主送(receive_type = 0)走 BPM;抄送不审批。
状态流转说明
【自动投递】发文通过 → 待签收(0) ──签收──→ 已签收(1) ──主送提交──→ 办理中(2)+审批中(1)
├──通过──→ 已办结(3)+审批通过(2)
├──不通过──→ 已签收(1)+审批不通过(3)
└──撤销──→ 已签收(1)+已取消(4)
【抄送】待签收 → 签收 → 已签收(不发起流程)
【手工收文】直接归属创建人,receive_type 强制主送,不能签收接口
- 签收(
claimOfficialDocReceive):要求send_id非空、creator为空、handle_status = 待签收(0),且当前用户部门等于receive_dept_id。效果:handle_status → 已签收(1),creator写入当前用户;不修改handler_user_id、receive_time。 - 提交(
submitOfficialDocReceive):仅主送可提交;status → 审批中(1),handle_status → 办理中(2)。抄送提交抛出OFFICIAL_DOC_STATUS_INVALID。 - 审批回调(
updateOfficialDocReceiveStatus,监听器OaOfficialDocReceiveStatusListener):审批通过(2)→handle_status = 已办结(3);驳回、取消等其他终态 →handle_status回退为已签收(1)。
# 3.3 管理后台
对应 [OA 办公协同 -> 公文管理 -> 公文收文] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/officialdoc/receive 目录。
# 新增与签收
外来公文可通过【新增】打开 OaOfficialDocReceiveForm.vue 手工登记;由发文生成的待签收记录,通过【签收】调用 PUT /oa/officialdoc-receive/claim。

# 办理与提交
填写收文部门、主办人、领导批示、办理期限、办理结果和附件等资料。保存后在列表点击【提交】,调用 POST /oa/officialdoc-receive/submit 发起 oa_official_doc_receive 流程。收文来源与办理状态会影响可执行操作。

# 查看关联发文
进入 @/views/oa/officialdoc/receive/detail/index.vue 查看收文资料。自动生成的收文显示关联发文,可点击【查看关联发文】;手工收文展示自身填写的资料和文件。