Skip to content

前端业务组件

RuoYi Office PC 管理端在 Vben Admin 5、Ant Design Vue 和 VxeTable 之上,沉淀了一组面向 OA、HRM、system、合同、项目等模块的业务组件。它们不是简单 UI 控件,而是把「表单布局、BPM 审批、字段权限、文件上传、附件预览」等企业应用常见能力封装成可复用组件。

本文参考 Vben 文档中 API Component 的写法,按 场景说明 → 基础用法 → API → 业务实践 的结构整理,便于二开时直接复制到业务模块。

组件清单

组件路径主要用途典型模块
BasicFormsrc/components/basic-form业务单据详情页容器,集成表头、表单、审批流转、底部操作OA 会议室/用车/公文/出差,HRM 入转调离,项目、合同
CardContainersrc/components/basic-form表单内分组卡片,统一标题、间距和卡片样式OA、HRM、项目详情页
AttachmentListsrc/components/attachment-list附件列表、上传、预览、下载、排序和只读控制OA、HRM、合同、项目
FileUploadsrc/components/upload通用文件上传,支持表单 schema 或模板中使用system、OA、ERP、CRM、合同
ImageUploadsrc/components/upload图片上传和图片列表回显,适合头像、图标、封面system、HRM、Mall、BPM
InputUploadsrc/components/upload上传文本类文件并回填到输入框/文本域Pay 应用配置、证书/密钥配置

BasicForm

BasicForm 是业务表单页面的高阶容器。它内部使用 useVbenForm 渲染 schema 表单,同时叠加业务单据表头、流程时间线、审批任务列表、流程图、打印、撤回、再次提交等能力。

适用场景

  • 业务对象本身有申请单、编号、申请人、部门、公司等表头信息。
  • 页面需要兼容新增、编辑、详情、待办、已办、抄送、我的流程等不同入口。
  • BPM 节点字段权限需要控制字段隐藏、只读、可编辑。
  • 页面底部需要固定保存、提交、删除、撤回、关闭等按钮。

基础用法

vue
<script lang="ts" setup>
import type { VbenFormSchema } from '#/adapter/form';

import { ref } from 'vue';

import { AttachmentList } from '#/components/attachment-list';
import { BasicForm, CardContainer } from '#/components/basic-form';

const formData = ref({});
const attachments = ref([]);

const formSchema: VbenFormSchema[] = [
  { fieldName: 'title', label: '申请标题', component: 'Input' },
  { fieldName: 'applyDate', label: '申请日期', component: 'DatePicker' },
];

const headerData = ref({
  billName: '出差申请',
  billCode: 'TRIP202605240001',
  creatorName: '张三',
  companyName: '总部',
  deptName: '研发部',
});

function handleSave(values: Record<string, any>) {
  // 保存草稿
}

function handleSubmit(values: Record<string, any>) {
  // 提交并发起流程
}
</script>

<template>
  <BasicForm
    :form-data="formData"
    :form-schema="formSchema"
    :header-data="headerData"
    process-definition-key="oa_trip_apply"
    @save="handleSave"
    @submit="handleSubmit"
  >
    <CardContainer title="附件信息">
      <AttachmentList v-model="attachments" />
    </CardContainer>
  </BasicForm>
</template>

Props

属性类型默认值说明
headerDataheaderDataProps空表头单据表头,包含标题、编号、申请人、部门、公司、流程实例等信息
formDataRecord<string, any>{}表单回显数据,变化后会同步到内部 Vben Form
formSchemaVbenFormSchema[][]表单 schema,写法与 Vben Form 保持一致
columnsnumber4表单栅格列数,组件会转换为 span: 24 / columns
disabledbooleanfalse整体只读;待办/已办等入口还会结合 viewType 自动判断
viewTypestringundefined入口类型,常见值:tododonemycopy
timelineDirection'horizontal' | 'vertical'horizontal审批时间线方向
activityNodesany[][]流程节点信息,可由业务页提前传入
processDefinitionanyundefined流程定义对象,用于提交前预测自选审批人
processDefinitionKeystringundefined流程定义 Key,未传 processDefinition 时可用于兜底查询
fieldPermissionBusinessFieldPermissionundefinedBPM 业务表单字段权限配置
isApprovalbooleanundefined是否处于审批态
processStatusnumberundefined流程状态
hideFooterbooleanfalse隐藏底部操作栏
hideSubmitbooleanfalse隐藏提交按钮
hideSavebooleanfalse隐藏保存按钮
hideDeletebooleanfalse隐藏删除按钮
hideRevokebooleanfalse隐藏撤回按钮
showReCreatebooleanfalse显示再次提交按钮

Events

事件参数说明
savevalues点击保存草稿
submitvalues点击提交,通常用于发起/提交业务流程
delete-删除当前单据
revoke-撤销或作废当前单据
reCreate-再次提交
withdraw-BPM 任务撤回
close-关闭或返回列表
valuesChangevalues内部表单值变化

Expose

方法说明
getFormApi()获取内部 Vben Form API,便于业务页执行 setValuesvalidateresetValidate 等操作

表头数据结构

ts
export type headerDataProps = {
  id?: number;
  billCode?: string;
  billName?: string;
  creatorName?: string;
  createTime?: Date | string;
  companyId?: number;
  companyName?: string;
  deptId?: number;
  deptName?: string;
  processInstanceId?: string;
  processStatus?: number;
};

业务实践建议

  1. 先准备后端 SaveReqVO 和详情接口formSchema 字段名应尽量与保存接口字段一致,减少提交前转换。
  2. 流程 Key 不要猜processDefinitionKey 应来自流程配置、菜单或数据库,而不是仅按模块名推断。
  3. 只读入口统一走 props:已办、抄送、详情页优先传 viewTypedisabled,不要在每个字段上重复写 disabled
  4. 字段权限优先级最高:BPM 节点字段权限会覆盖普通 disabled 逻辑,业务页不要绕过组件单独隐藏字段。
  5. 复杂明细用插槽承载:主表字段放在 formSchema,明细表、附件、审批说明放到 CardContainer 中。

CardContainer

CardContainerBasicForm 内部常用的分组容器,适合把基础信息、明细信息、附件信息、审批说明拆成多个卡片。

vue
<CardContainer title="附件信息" :icon="FileOutlined">
  <AttachmentList v-model="attachments" />
</CardContainer>
属性类型说明
titlestring分组标题
iconComponent标题左侧图标

AttachmentList

AttachmentList 面向正式业务附件,不只是上传控件。它会把每个文件转换成附件业务对象,支持列表展示、上传弹窗、删除、预览、下载、排序、只读等能力。

基础用法

vue
<script lang="ts" setup>
import { ref } from 'vue';
import { AttachmentList } from '#/components/attachment-list';

const attachments = ref([]);
</script>

<template>
  <AttachmentList
    v-model="attachments"
    accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg"
    :max-count="10"
    :max-size="20"
  />
</template>

只读详情

vue
<AttachmentList v-model="attachments" readonly />

Props

属性类型默认值说明
modelValueAttachmentSaveReq[][]附件业务对象数组
readonlybooleanfalse只读模式下隐藏上传和删除,仅保留预览/下载
maxCountnumber10最大附件数量
acceptstring*允许上传的文件类型,例如 .pdf,.docx
maxSizenumber10单个文件最大大小,单位 MB
hideUploadButtonbooleanfalse隐藏内置上传按钮,适合外部自定义按钮位置

Events

事件参数说明
update:modelValueAttachmentSaveReq[]附件新增、删除或排序后同步给父组件

Expose

方法说明
handleTriggerUpload()打开上传弹窗,常用于隐藏默认按钮后外部触发
reloadAttachmentGrid()根据当前 modelValue 刷新表格数据
waitUploadFinished()等待上传任务结束,适合提交前兜底校验

附件对象结构

ts
export interface AttachmentSaveReq {
  id?: number;
  businessType: string;
  businessId: number;
  fileName: string;
  filePath: string;
  fileUrl: string;
  fileSize: number;
  fileType?: string;
  fileExtension?: string;
  uploadTime?: Date;
  sortOrder?: number;
  remark?: string;
  rowKey?: string;
}

预览能力

AttachmentList 会按扩展名选择预览方式:

类型处理方式
图片使用 Ant Design Vue Image 预览
PDF弹窗或浏览器预览
DOCX使用 @vue-office/docx 预览
XLSX使用 @vue-office/excel 预览
其他 Office 文件结合配置的 kkFileViewUrl 预览
不支持类型提供下载

FileUpload

FileUpload 是轻量级文件上传控件,适合放在 Vben Form schema 中,也可以在模板中直接使用。它默认调用 useUpload(directory).httpRequest,底层对接 infra 文件上传能力;也可以通过 api 传入自定义上传函数。

Schema 中使用

ts
const schema = [
  {
    fieldName: 'attachmentUrl',
    label: '附件',
    component: 'FileUpload',
    componentProps: {
      accept: ['pdf', 'doc', 'docx'],
      maxSize: 20,
      maxNumber: 3,
      showDescription: true,
    },
  },
];

模板中使用

vue
<FileUpload
  v-model:value="fileUrl"
  :accept="['pdf', 'docx']"
  :max-size="20"
  :max-number="1"
  show-description
/>

Props

属性类型默认值说明
value / modelValuestring | string[][]绑定值,单文件通常为字符串,多文件通常为数组或逗号分隔字符串
acceptstring[][]允许上传的扩展名或 MIME 类型
maxSizenumber2单文件大小限制,单位 MB
maxNumbernumber1最大文件数量
multiplebooleanfalse是否允许多选;maxNumber > 1 时会自动视为多文件
dragbooleanfalse是否显示拖拽上传样式
directorystringundefined上传目录,传给默认上传实现
apiFunctionundefined自定义上传函数
resultFieldstring''从响应中读取结果字段,支持嵌套路径
showDescriptionbooleanfalse是否显示格式、大小、数量说明
helpTextstring''自定义提示文本
disabledbooleanfalse禁用上传和删除
autoUploadbooleantrue是否选择文件后自动上传
fileTypestring[]-兼容 form-create,等同 accept
fileSizenumber-兼容 form-create,等同 maxSize
limitnumber-兼容 form-create,等同 maxNumber
isShowTipboolean-兼容 form-create,等同 showDescription

Events

事件参数说明
update:valuestring | string[]更新 v-model:value
update:modelValuestring | string[]更新 v-model
changestring | string[]文件列表变化
deleteUploadFile删除文件
previewUploadFile点击文件预览
returnTextstring上传前读取文本内容并返回,供 InputUpload 使用

ImageUpload

ImageUploadFileUpload 共享同一套 FileUploadProps,但交互上使用图片墙/图片卡片,适合头像、图标、商品图、流程图标等场景。

vue
<ImageUpload
  v-model:value="avatar"
  :max-size="2"
  :max-number="1"
  :accept="['jpg', 'jpeg', 'png', 'webp']"
/>

常见用法:

  • system OAuth2 客户端图标、用户头像。
  • HRM 员工照片。
  • BPM 流程模型图标。
  • Mall 商品主图、分类图标和装修图片。

InputUpload

InputUpload 组合了只读输入框/文本域和 FileUpload。用户上传文本类文件后,组件读取文件文本内容并回填输入框,适合证书、密钥、公钥、私钥等配置项。

vue
<InputUpload
  v-model="privateKey"
  input-type="textarea"
  :textarea-props="{ rows: 8, placeholder: '上传或粘贴私钥' }"
  :file-upload-props="{
    accept: ['txt', 'pem', 'key'],
    maxSize: 1,
    maxNumber: 1,
    showDescription: false,
  }"
/>
属性类型说明
modelValuestring | number输入框绑定值
defaultValuestring | number默认值
inputType'input' | 'textarea'输入框类型
inputPropsInputProps透传给 Ant Design Vue Input
textareaPropsTextAreaProps透传给 Ant Design Vue Textarea
fileUploadPropsFileUploadProps透传给 FileUpload

常见组合模式

BPM 业务表单 + 附件

vue
<BasicForm
  ref="basicFormRef"
  :form-data="formData"
  :form-schema="formSchema"
  :header-data="headerData"
  :field-permission="fieldPermission"
  :view-type="viewType"
  @save="handleSave"
  @submit="handleSubmit"
>
  <CardContainer title="附件">
    <AttachmentList
      v-model="formData.attachments"
      :readonly="readonly"
      accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg"
    />
  </CardContainer>
</BasicForm>

普通管理弹窗 + 上传字段

ts
{
  fieldName: 'icon',
  label: '图标',
  component: 'ImageUpload',
  componentProps: {
    maxNumber: 1,
    maxSize: 2,
    accept: ['png', 'jpg', 'jpeg', 'webp'],
  },
}

提交前等待附件上传完成

ts
const attachmentRef = ref<InstanceType<typeof AttachmentList>>();

async function handleSubmit() {
  await attachmentRef.value?.waitUploadFinished();
  // 再提交业务数据
}

选型建议

需求推荐组件
正式业务单据页面,包含 BPM、表头、底部按钮BasicForm
只是 Vben Form 的一个文件字段FileUpload / ImageUpload
需要附件表格、预览、下载、业务附件对象AttachmentList
上传证书、密钥等文本文件并回填字段InputUpload
表单分区、详情页分块展示CardContainer

二开注意事项

  • 上传组件返回值默认是文件 URL,业务附件列表返回的是附件对象数组,两者不要混用。
  • AttachmentList 保存前需要业务页补齐 businessTypebusinessId 或在后端创建业务后再绑定。
  • BasicForm 里如果自定义明细表,提交时需要手动把明细数据合并到 SaveReqVO。
  • 文件大小单位统一按 MB,acceptFileUpload 中是数组,在 AttachmentList 中是字符串。
  • PC 端业务表单优先复用这些组件,避免每个 OA/HRM 页面重复实现表头、审批、附件和底部按钮。
联系我们

获取报价、演示和二开方案

微信咨询二维码

微信咨询

17156169080

添加时备注「RuoYi Office」

在线体验商业版