SpringBoot+Vue3 实现 OA 公文外来文与归档台账:外部收文、BPM办理、三类公文统一归档

文档地址:http://ruoyioffice.com | 源码1:ruoyi-office-vben | 源码2:ruoyi-office | 源码3:ruoyi-office

在前两篇公文系列文章中,我们分别拆解了公文发文和内部收文。发文解决的是“企业内部正式文件如何产生”,收文解决的是“内部发文如何分发到部门办理”。但真实企业办公里,还有一类更容易被忽视的公文:来自上级单位、监管部门、合作单位、外部机构的外来文件。它们不是系统内部发起,却必须被登记、批示、办理、留痕和归档。本文聚焦 RuoYi Office 的 外部收文 + 公文归档台账 设计,看看如何用 Spring Boot + Flowable + Vue3 把三类公文统一收口。

引言:外来文为什么不能只做“附件上传”?

很多企业第一次做 OA 公文模块时,会把外来文简化成一个“文件上传台账”:填一下来文单位、标题、上传附件,然后结束。这个方案看似轻巧,但一旦进入真实管理场景,就会暴露出几个问题:

业务问题简化方案的后果系统应承担的能力
来文需要领导批示附件上传后无法体现“谁批示、批示什么”支持领导批示节点与意见留痕
来文需要承办部门处理台账只能记录文件,不能追踪办理进展支持承办办理、办理结果、办理期限
来文需要流程闭环文件状态停留在“已上传”,无法区分办理中和已办结建立业务状态 + BPM 状态联动
来文最终要归档外部收文和内部发文、收文分散在多个列表建立统一归档台账
管理层要检索历史公文只能按文件名查,缺少文号、密级、责任部门等维度提供结构化检索和导出

所以,外部收文不应该只是“上传文件”,而应该是一张具备流程属性的业务单据:

外部单位来文 → 文秘登记 → 领导批示 → 承办部门办理 → 办结归档 → 统一台账检索

RuoYi Office 的设计重点正是在这里:外部收文独立于内部发文体系,但最终和发文、内部收文一起进入公文归档台账,形成完整的企业公文资产库。


一、业务场景:三类公文如何统一管理?

1.1 公文体系中的三类来源

在 RuoYi Office 中,公文归档台账聚合的不是单一表,而是三类来源:

类型来源典型场景归档条件
发文企业内部起草并审批签发公司制度、会议纪要、任命通知、对外函件processStatus = APPROVE
收文内部发文按部门自动生成,或部门手工登记主送部门签收、领导批示、承办办理handleStatus = 3
外部收文外部单位、监管机构、合作方来文上级通知、监管文件、合作函件、纸质文件登记processStatus = APPROVE

发文强调“生产正式文件”,收文强调“内部传达办理”,外部收文强调“外部文件进入企业后的处理闭环”。三者的业务动作不同,但最终都要落到同一个问题:哪些公文已经形成可追溯的正式记录?

1.2 外部收文的典型使用场景

外部收文在机关、国企、集团公司、园区企业中非常常见:

  • 上级单位下发通知,需要办公室登记后交由领导批示。
  • 监管部门发送检查整改文件,需要责任部门在期限内办理。
  • 合作单位发送合同函、联系函、会议纪要,需要内部留痕。
  • 纸质文件送达企业,需要扫描上传并纳入电子台账。
  • 历史公文需要按文号、标题、密级、责任部门进行检索和导出。

如果没有系统承接,这类文件通常散落在邮箱、微信群、纸质档案柜、个人电脑里。短期看还能靠人记,时间一长就会出现“找不到、说不清、追不回”的问题。

1.3 RuoYi Office 的解决思路

RuoYi Office 没有把外来文做成一个孤立表单,而是把它放进完整的公文体系里:
officedoc-outside-archive-flow.png

▲ 外部收文与归档流程:外部来文登记后进入 BPM 办理流程,流程通过后与发文、内部收文一起进入归档台账

核心思路可以概括为三句话:

  1. 外部收文是流程单据:登记不是终点,提交后进入 BPM 流程。
  2. 办理状态由流程驱动:待登记、办理中、已办结不是人工随便改,而是由流程状态回调统一维护。
  3. 归档台账是查询层聚合:不强行把三类公文塞进一张大表,而是在归档服务中统一投影、排序和分页。

二、系统设计:外部收文与归档台账的边界

2.1 模块分工

这次拆解涉及两个核心后端服务和三组前端页面:

层级文件/页面职责
后端服务OfficeDocOutsideServiceImpl.java外部收文保存、提交、删除、附件维护、流程状态回调
后端服务OfficeDocArchiveServiceImpl.java聚合发文、收文、外部收文,输出统一归档列表
PC 列表页views/oa/officedoc/outside/list外部收文查询、新建、导出、删除
PC 详情页views/oa/officedoc/outside/info外部收文登记、保存、提交、撤回、上传正式公文和附件
PC 台账页views/oa/officedoc/archive/list三类公文统一检索、查看详情、PDF 预览、导出

这套边界很清晰:外部收文负责“产生并办理一条来文”,归档台账负责“把已经完成的公文汇总出来”。

2.2 为什么归档不直接建一张汇总表?

公文归档可以有两种实现方案:

方案做法优点风险
物理归档表流程结束时复制一份数据到 archive 表查询快,结构统一数据冗余,回写一致性复杂
查询层聚合查询时分别查三类来源并合并无冗余,来源数据始终真实大数据量下需要优化分页

当前 RuoYi Office 采用的是第二种:查询层聚合。

原因很务实:公文归档台账本质上是一个管理查询视图,数据源仍然是发文、收文、外部收文各自的业务表。这样既避免了“业务表改了,归档表没同步”的一致性问题,也能保留每类公文的原始详情入口。

2.3 状态设计:BPM 状态与办理状态分层

外部收文有两个容易混淆的状态:

状态字段含义面向对象示例
processStatusBPM 流程实例状态流程引擎、审批中心未开始、运行中、通过、驳回、撤回
handleStatus外部收文业务办理状态业务人员、列表台账待登记、办理中、已办结

真实实现中,外部收文办理状态有三个核心值:

状态码常量含义触发场景
0HANDLE_STATUS_PENDING待登记新建未提交、驳回、取消、撤回、未开始
2HANDLE_STATUS_PROCESSING办理中提交 BPM 或流程运行中
3HANDLE_STATUS_COMPLETED已办结BPM 审批通过

这种分层设计的好处是:BPM 可以保持通用状态,业务页面可以展示更贴近用户语言的“办理状态”。


三、流程设计:从登记到归档的闭环

3.1 外部收文流程节点

外部收文的流程和内部收文类似,重点不是“签发”,而是“批示与办理”:

文秘登记 → 领导批示 → 承办部门办理 → 办结确认 → 流程结束
节点角色核心操作数据落点
文秘登记办公室/综合部填写来文单位、文号、标题、密级、收文日期,上传附件基础字段、附件
领导批示部门/公司领导填写批示意见,明确处理方向leaderOpinion
承办部门办理责任部门/主办人填写办理结果,补充处理情况handleResult
办结确认文秘/流程节点配置角色确认办理完成BPM 审批通过

外部收文没有内部发文的“套红模板”和“生成正式 PDF”动作,因为它的正式文件通常来自外部单位,系统只需要保存原文件或扫描件,并记录企业内部办理过程。

3.2 状态流转

外部收文的状态流转可以这样理解:

待登记(0)
  ├─ 提交 BPM → 办理中(2)
  ├─ 流程通过 → 已办结(3)
  └─ 驳回/取消/撤回/未开始 → 待登记(0)

注意这里有一个关键点:提交时直接把业务状态置为“办理中”。这意味着只要单据进入 BPM,就不再是普通草稿,而是一条正在办理的外来文。

3.3 节点级保存

前端详情页在审批模式下会识别当前节点名称:

  • 当前节点是“领导批示”时,允许编辑 leaderOpinion。
  • 当前节点是“承办部门办理”时,允许编辑 handleResult。
  • 审批通过前调用保存接口,避免批示或办理结果只停留在前端表单。

这延续了 RuoYi Office 公文收文模块的节点级业务定制思路:流程节点不只是“同意/拒绝”的按钮,还可以承载业务字段的编辑权限。


四、PC 端功能实现:外部收文列表、详情、归档台账

4.1 外部收文列表:面向登记与办理跟踪

外部收文列表页位于 views/oa/officedoc/outside/list,核心能力包括:
officedoc-outside-list.png

▲ 外部收文列表:支持按公文标题、来文单位、流程状态查询,展示办理状态和流程状态

列表页的字段设计很贴近文秘日常工作:

字段说明
单据编号系统生成的外部收文业务编号
公文标题外部来文的标题
来文单位文件来源单位,如上级单位、合作方、监管部门
来文字号外部文件自带文号
密级/紧急程度便于优先级管理
收文部门文件进入企业后的责任部门
办理状态待登记、办理中、已办结
流程状态BPM 流程状态

列表页的删除逻辑也遵循 BPM 单据规范:只有处于允许删除的流程状态时,删除按钮才可用;运行中的流程单据不可直接删除。

4.2 外部收文详情:登记、提交、上传正式文件

外部收文详情页位于 views/oa/officedoc/outside/info,它不是简单表单,而是一个流程表单页面:

区域功能说明
基础信息来文单位、来文字号、公文标题、密级、紧急程度、收文日期登记外来文的结构化元数据
办理信息收文部门、主办人、领导批示、办理结果、办理期限支撑领导批示和承办办理
正式公文上传 PDF、Word、扫描件保存外部来文原件
附件列表上传补充材料保存过程材料、相关附件
操作按钮保存、提交、撤回、删除与 BPM 状态联动

image.png

详情页初始化新单据时,会自动带入当前用户的公司、部门、创建人、默认密级、紧急程度和收文日期:

const now = new Date();
formData.value = {
  creator: userStore.userInfo?.id,
  companyId: userStore.userInfo?.companyId || 0,
  companyName: userStore.userInfo?.companyName || '',
  deptId: userStore.userInfo?.deptId || 0,
  deptName: userStore.userInfo?.deptName || '',
  processStatus: BpmProcessInstanceStatus.NOT_START,
  secretLevel: 0,
  urgencyLevel: 0,
  handleStatus: 0,
  sourceOrg: '',
  title: '',
  receiveDate: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`,
  docFileUrl: '',
  attachments: [],
};

这种默认值设计的价值在于减少文秘录入成本:系统知道当前用户属于哪个公司、哪个部门,没必要让用户每次重复填写。

4.3 归档台账:三类公文统一入口

归档台账页面位于 views/oa/officedoc/archive/list,它面向的是管理查询而不是单据办理:
officedoc-archive-list.png

▲ 公文归档台账:统一展示发文、收文、外部收文,支持按归档类型、标题、文号、密级、归档时间查询

归档台账的前端设计有三个细节:

设计点实现方式用户价值
归档类型区分发文蓝色、收文绿色、外部收文橙色标签一眼识别来源
详情跳转根据 archiveType 跳转到发文、收文、外部收文详情页保留原始业务上下文
PDF 预览有 docFileUrl 时展示“预览”按钮,用弹窗 iframe 打开不离开台账即可查看正式文件

前端跳转逻辑非常直接:

function handleViewDetail(row: OfficeDocArchiveApi.OfficeDocArchive) {
  const pathMap: Record<string, string> = {
    send: '/oa/officedoc/send-info',
    receive: '/oa/officedoc/receive-info',
    outside: '/oa/officedoc/outside-info',
  };
  const path = pathMap[row.archiveType || ''];
  if (path) {
    router.push({ path, query: { id: row.id, viewType: 'done' } });
  }
}

这说明归档台账不是复制出来的“静态档案”,而是一个统一入口。用户在台账中看到的是归档视图,点击进去仍然能回到原始业务单据。


五、后端核心代码:提交、回调、聚合

5.1 外部收文提交:保存单据并发起 BPM

外部收文提交的关键动作有四步:

  1. 如果没有单号,生成业务单据编号。
  2. 保存外部收文主表,并将 processStatus 设为运行中。
  3. 将 handleStatus 设为办理中。
  4. 提交 BPM 流程实例,回写 processInstanceId,保存附件。
@Override
public Long submitOfficeDocOutside(OfficeDocOutsideSaveReqVO saveReqVO) {
    if (StringUtils.isBlank(saveReqVO.getBillCode())) {
        saveReqVO.setBillCode(BillCodeUtils.generateBillCode(
                SystemEnum.OA, OaBillTypeEnum.OA_OFFICE_DOC_OUTSIDE));
    }
    OfficeDocOutsideDO docOutside = BeanUtils.toBean(saveReqVO, OfficeDocOutsideDO.class)
            .setProcessStatus(BpmTaskStatusEnum.RUNNING.getStatus())
            .setHandleStatus(HANDLE_STATUS_PROCESSING);
    officeDocOutsideMapper.insertOrUpdate(docOutside);

    Map<String, Object> variables = BpmProcessVariableUtils.buildBillVariables(saveReqVO);
    Long submitUserId = StringUtils.isNotBlank(saveReqVO.getCreator())
            ? Long.valueOf(saveReqVO.getCreator()) : SecurityFrameworkUtils.getLoginUserId();
    String processInstanceId = processInstanceApi.submitProcessInstance(submitUserId,
            new BpmProcessInstanceCreateReqDTO()
                    .setProcessDefinitionKey(OaBillTypeEnum.OA_OFFICE_DOC_OUTSIDE.getProcessDefinitionKey())
                    .setVariables(variables).setBusinessKey(String.valueOf(docOutside.getId()))
    ).getCheckedData();
    officeDocOutsideMapper.updateById(new OfficeDocOutsideDO().setId(docOutside.getId())
            .setProcessInstanceId(processInstanceId));

    if (saveReqVO.getAttachments() != null) {
        attachmentService.saveAttachmentList(OaBillTypeEnum.OA_OFFICE_DOC_OUTSIDE.getTypeCode(),
                docOutside.getId(), saveReqVO.getAttachments());
    }
    return docOutside.getId();
}

这段代码体现了 RuoYi Office 流程单据的通用模式:业务表先落库,BPM 以业务表 ID 作为 businessKey,流程实例启动后再回写到业务表。

5.2 流程状态回调:BPM 驱动办理状态

外部收文实现了 FlowBillService<OaBillTypeEnum>,因此流程状态变化时会回调业务服务。核心逻辑如下:

@Override
public void updateProcessStatus(String businessKey, Integer status) {
    Long id = Long.parseLong(businessKey);
    log.info("[updateProcessStatus] 外部收文,id: {}, status: {}", id, status);
    validateExists(id);

    OfficeDocOutsideDO updateObj = new OfficeDocOutsideDO();
    updateObj.setId(id);
    updateObj.setProcessStatus(status);
    if (BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(status)) {
        updateObj.setHandleStatus(HANDLE_STATUS_COMPLETED);
    } else if (BpmProcessInstanceStatusEnum.RUNNING.getStatus().equals(status)) {
        updateObj.setHandleStatus(HANDLE_STATUS_PROCESSING);
    } else if (BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(status)
            || BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(status)
            || BpmProcessInstanceStatusEnum.WITHDRAW.getStatus().equals(status)
            || BpmProcessInstanceStatusEnum.NOT_START.getStatus().equals(status)) {
        updateObj.setHandleStatus(HANDLE_STATUS_PENDING);
    }
    officeDocOutsideMapper.updateById(updateObj);
}

这段代码是外部收文状态机的核心。它没有让前端直接传“已办结”,而是把办理状态收敛到后端流程回调里。这样可以避免用户手动篡改状态,也能确保审批中心和业务列表的状态一致。

5.3 归档聚合查询:三类来源合并后分页

归档服务的入口是 getArchivePage。它根据查询条件决定是否查询发文、收文、外部收文,然后把结果合并、按归档时间倒序排序,并在内存中分页:

@Override
public PageResult<OfficeDocArchiveRespVO> getArchivePage(OfficeDocArchivePageReqVO reqVO) {
    String archiveType = reqVO.getArchiveType();

    List<OfficeDocArchiveRespVO> allRecords = new ArrayList<>();

    if (archiveType == null || TYPE_SEND.equals(archiveType)) {
        allRecords.addAll(querySendArchives(reqVO));
    }
    if (archiveType == null || TYPE_RECEIVE.equals(archiveType)) {
        allRecords.addAll(queryReceiveArchives(reqVO));
    }
    if (archiveType == null || TYPE_OUTSIDE.equals(archiveType)) {
        allRecords.addAll(queryOutsideArchives(reqVO));
    }

    allRecords.sort(Comparator.comparing(
            OfficeDocArchiveRespVO::getArchiveTime,
            Comparator.nullsLast(Comparator.reverseOrder())));

    int pageNo = reqVO.getPageNo() != null ? reqVO.getPageNo() : 1;
    int pageSize = reqVO.getPageSize() != null ? reqVO.getPageSize() : 20;
    int start = (pageNo - 1) * pageSize;
    int end = Math.min(start + pageSize, allRecords.size());
    List<OfficeDocArchiveRespVO> pageList = start < allRecords.size()
            ? allRecords.subList(start, end) : new ArrayList<>();
    return new PageResult<>(pageList, (long) allRecords.size());
}

这就是“统一归档视图”的核心:不是让三类公文改变自己的业务模型,而是把它们投影成统一的 OfficeDocArchiveRespVO。

5.4 外部收文归档条件

外部收文进入归档台账的条件是 processStatus = APPROVE。归档投影时,会把外部收文字段映射成统一字段:

private List<OfficeDocArchiveRespVO> queryOutsideArchives(OfficeDocArchivePageReqVO reqVO) {
    LambdaQueryWrapperX<OfficeDocOutsideDO> wrapper = new LambdaQueryWrapperX<OfficeDocOutsideDO>()
            .eq(OfficeDocOutsideDO::getProcessStatus, BpmProcessInstanceStatusEnum.APPROVE.getStatus())
            .eqIfPresent(OfficeDocOutsideDO::getCompanyId, reqVO.getCompanyId())
            .likeIfPresent(OfficeDocOutsideDO::getTitle, reqVO.getTitle())
            .likeIfPresent(OfficeDocOutsideDO::getDocNumber, reqVO.getDocNumber())
            .eqIfPresent(OfficeDocOutsideDO::getSecretLevel, reqVO.getSecretLevel())
            .betweenIfPresent(OfficeDocOutsideDO::getUpdateTime, reqVO.getArchiveTime());

    return officeDocOutsideMapper.selectList(wrapper).stream().map(out -> {
        OfficeDocArchiveRespVO vo = new OfficeDocArchiveRespVO();
        vo.setId(out.getId());
        vo.setArchiveType(TYPE_OUTSIDE);
        vo.setArchiveTypeName("外部收文");
        vo.setBillCode(out.getBillCode());
        vo.setDocNumber(out.getDocNumber());
        vo.setTitle(out.getTitle());
        vo.setDocDate(out.getReceiveDate());
        vo.setDeptName(out.getReceiveDeptName());
        vo.setHandlerName(out.getHandlerName());
        vo.setArchiveTime(out.getUpdateTime());
        return vo;
    }).toList();
}

注意这里外部收文的 docDate 对应的是 receiveDate,deptName 对应的是 receiveDeptName,handlerName 对应的是 handlerName。统一字段名不代表丢失业务语义,而是在归档视图中把不同来源转换成可比较、可展示的共同语言。


六、数据结构:外部收文与归档视图

6.1 外部收文主表字段

外部收文主表对应 OfficeDocOutsideDO,表名为 oa_office_doc_outside。核心字段可以分为五组:

字段类型含义说明
id主键外部收文记录 ID
billCode单据编号系统生成,作为业务单号
processInstanceId流程实例 ID关联 BPM 流程实例
processStatus流程状态BPM 状态
handleStatus办理状态待登记、办理中、已办结
字段类型含义说明
sourceOrg来文单位外部文件来源单位
docNumber来文字号外部公文自带文号
title公文标题外部来文标题
secretLevel密级公开、内部、秘密等
urgencyLevel紧急程度普通、紧急等
receiveDate收文日期企业收到文件的日期
字段类型含义说明
receiveDeptId / receiveDeptName收文部门负责接收和办理的部门
handlerId / handlerName主办人具体承办人
leaderOpinion领导批示领导处理意见
handleResult办理结果承办部门处理结果
handleDeadline办理期限用于督办和时效管理
字段类型含义说明
content内容摘要文件主要内容
docFileUrl正式公文地址外部文件 PDF、Word 或扫描件
companyId / companyName公司信息多组织隔离与展示
deptId / deptName创建部门登记人所在部门
remark备注补充说明

6.2 归档响应视图

归档台账使用 OfficeDocArchiveRespVO 作为统一返回结构:

字段统一含义发文映射收文映射外部收文映射
id原始记录 ID发文 ID收文 ID外部收文 ID
archiveType归档类型sendreceiveoutside
archiveTypeName类型名称发文收文外部收文
billCode单据编号发文单号收文单号外部收文单号
docNumber文号发文字号来文字号来文字号
title公文标题发文标题收文标题外部来文标题
docDate公文日期发文日期收文日期收文日期
deptName责任部门发文部门收文部门收文部门
handlerName经办人签发人主办人主办人
archiveTime归档时间更新时间更新时间更新时间

这张视图表不是数据库表,而是“查询返回模型”。它的价值在于把不同来源的字段压平到一套列表结构,前端不需要关心每类公文背后的表结构差异。

6.3 附件设计

外部收文附件没有直接塞进主表,而是通过通用附件服务维护:

附件类型存储方式说明
正式公文docFileUrl适合单个主文件,如 PDF、Word、扫描件
补充附件AttachmentService适合多个佐证材料、过程附件

这种设计区分了“主文件”和“附件”。主文件用于台账预览和正式文件展示,附件用于保存过程材料。


七、RuoyiOffice 创新设计

7.1 业务状态不等于流程状态

很多系统会直接把 BPM 状态展示给业务用户,比如“运行中、已通过、已驳回”。这对开发者很清楚,但对文秘和业务部门不够友好。

RuoYi Office 做了一层业务状态映射:

BPM 状态外部收文办理状态用户理解
未开始、驳回、取消、撤回待登记还没有形成有效办理流程
运行中办理中已进入内部处理
通过已办结文件处理完成,可归档

这样列表页既能展示流程状态,也能展示办理状态,既满足审批系统的准确性,也满足业务用户的可读性。

7.2 归档台账不是“复制数据”,而是“统一视图”

传统 OA 往往会在归档时复制一份数据,久而久之就出现两份数据不一致的问题。RuoYi Office 当前采用查询层聚合,保证归档台账看到的是业务源数据的最新状态。

这对中小企业很友好:表结构更简单,维护成本更低,数据链路更容易理解。

7.3 三类公文保留各自详情入口

归档台账中点击详情,不是进入一个抽象的“归档详情页”,而是根据类型跳回原始单据:

归档类型详情入口
发文/oa/officedoc/send-info
收文/oa/officedoc/receive-info
外部收文/oa/officedoc/outside-info

这意味着归档台账既是统一检索入口,又不牺牲各类公文自己的业务上下文。

7.4 PC 端与 BPM 审批中心共用表单

外部收文详情页既可以从业务列表打开,也可以在 BPM 审批中心作为流程表单打开。通过 props.isApproval、props.nodeKeyName、viewType 等参数,页面可以自动判断当前是编辑、查看还是审批场景。

这套设计让业务页面和审批页面复用同一份 Vue 组件,避免维护两套表单。

7.5 附件与流程生命周期联动

外部收文删除时,不仅删除主表,还会清理流程实例和附件:

  • 如果存在 processInstanceId,尝试删除 BPM 流程实例。
  • 调用附件服务删除业务附件。
  • 删除外部收文主记录。

这避免了“单据删了,流程还在;附件没人引用,却占用存储”的数据垃圾问题。


八、技术亮点总结

设计要点实现方式业务价值
外部收文流程化提交时创建 BPM 流程实例外来文不止登记,还能办理闭环
状态分层processStatus + handleStatus兼顾流程准确性和业务可读性
状态回调FlowBillService.updateProcessStatusBPM 状态变化自动同步业务状态
附件管理AttachmentService + docFileUrl区分正式文件和补充材料
归档聚合发文、收文、外部收文分别查询后合并保留源数据,不额外复制
统一响应 VOOfficeDocArchiveRespVO前端列表无需感知多表差异
类型化跳转archiveType 映射详情路径台账可回溯原始单据
PDF 预览docFileUrl + iframe 弹窗台账页面快速查看正式文件
多组织过滤companyId、deptId 条件支持集团/多部门数据隔离
导出能力列表导出 Excel满足线下档案移交和统计

九、快速体验路径

如果你想在系统中完整体验外部收文与归档台账,可以按下面的顺序操作:

  1. 进入 OA 办公 → 公文管理 → 外部收文。
  2. 点击“新增外部收文”,填写来文单位、来文字号、公文标题、收文日期。
  3. 上传正式公文或附件,点击保存,确认草稿数据正常。
  4. 点击提交,外部收文进入 BPM 办理流程,办理状态变为“办理中”。
  5. 在审批中心完成领导批示和承办办理。
  6. 流程审批通过后,外部收文办理状态变为“已办结”。
  7. 进入 OA 办公 → 公文管理 → 公文归档台账。
  8. 选择归档类型“外部收文”,查看刚才办结的记录,也可以切换“全部”查看发文、收文、外部收文混合台账。

源码模块对应关系如下:

体验功能前端路径后端服务
外部收文列表views/oa/officedoc/outside/listOfficeDocOutsideServiceImpl
外部收文详情views/oa/officedoc/outside/infoOfficeDocOutsideServiceImpl
公文归档台账views/oa/officedoc/archive/listOfficeDocArchiveServiceImpl

结语

外部收文看起来只是公文管理的一个补充模块,但它其实补齐了企业公文体系中非常关键的一环:不是所有文件都从企业内部发起,但所有进入企业的重要文件都应该被登记、办理和归档。

RuoYi Office 的实现没有把外来文做成孤立附件库,而是通过 BPM 流程、办理状态机、附件服务和统一归档台账,把外部来文纳入企业公文闭环。发文、收文、外部收文三类来源最终汇聚到同一个归档视图中,既保留各自业务差异,又形成统一查询入口。

这也是 RuoYi Office 在 OA 模块设计中的一贯思路:业务可以复杂,但系统边界要清晰;流程可以灵活,但数据状态要可控。OA · HRM · CRM · ERP,一站打通,最终服务的都是同一个目标:让企业的每一类业务都能形成可追踪、可复盘、可沉淀的数字化资产。


RuoYi Office —— 一个平台,管好整个企业

在线演示:http://ruoyioffice.com/web/(账号 admin / admin123)

技术咨询:添加 17156169080,备注「RuoYi Office」

如果觉得不错,请给个 Star 支持一下。


更多推荐