在工作流页面中,除了特定的业务表单信息外,往往也需要同时展示通用申请单的相关信息,因此在页面设计的时候需要使用一些组件化的概念来实现动态的内容展示处理,本篇随笔介绍Vue3+TypeScript+ElementPus的前端工作流模块中实现统一的表单编辑和表单详情查看处理。
1、查看申请单的模块设计处理
在工作流处理表中,首先我们区分流程模板和流程实例两个部分,这个其实就是类似模板和具体文档的概念,我们一份模板可以创建很多个类似的文档,文档样式结构类似的。同理,流程模板实例为流程实例后,就是具体的一个流程表单信息了,其中流程模板和流程实例表单都包括了各个流程步骤。在流程实例的层次上,我们运行的时候,需要记录一些日志方便跟踪,如流程步骤的处理日志,流程实例表单的处理日志等这些信息。
一旦流程实例根据模板创建后,流程先根据模板初始化后,在处理过程还可以动态增加一些审批步骤,使得我们的处理更加弹性化。
当然,为了更好的处理流程的相关信息,还需要记录流程处理人,流程会签人、流程阅办人,以及常用审批意见等相关辅助表,以便对流程的各个处理信息进行合理处理和展示。
对于一个流程处理操作,我们知道一般有审批通过、拒绝、退回到某步骤、转发到内部阅读、阅读,以及包括起草者能撤销表单呢等操作,当然如果还有一些具体的业务,可能还会有一些流程的处理才操作,不过基本上也可以归结为上面几种,只是他们每步处理的数据内容不同而已。因此审批的操作步骤分类如下所示。
在基于 Vue3+TypeScript+ElementPus的前端工作流模块中,我们在查看表单明细的时候,需要包含公用表单信息,特定表单信息两部分内容。前者表单数据可以统一呈现,而后者则是不同业务的表单数据不同。为了实现更好的维护性,把它们分开作为两部分处理,但是页面入口设计为统一的呈现页面。
表单数据按内容区分分为了两类:通用业务表单、特定业务表单
如果我们要把两者统一在一个通用页面中进行展示,就需要根据不同表单名称,动态加载属于特定表单的展示模块,也就是动态组件的实现方式,大概的业务规则如下所示。
页面效果如下图所示。
而编辑界面也是类似,通过动态化组件的方式合并公用信息和特定表单组件信息。
2、查看、编辑页面路由设置及项目视图目录
通过动态化组件的呈现处理,可以实现编辑和查看申请单页面的动态呈现,我们Vue的前端也可以只需要定义一个查看页面路由,和一个编辑界面的路由即可,极大的降低开发代码和复杂度。如下面是路由的JSON文件中关于查看、编辑页面的路由信息。
在 Vue3+TypeScript+ElementPus的前端项目中,我们创建了几个不同的目录来放置不同的页面代码,如edit是编辑特定表单的组件页面目录,view是查看特定表单的组件页面目录,list则是该表单的详细列表信息,而system工作流系统的管理页面等等,如下图所示。
其中Edit、View目录下,都是对应表单名称的页面组件(页面代码)
在通用的查看表单页面中,我们定义了两个部分的内容,包括公用处理单的信息,以及特定表单的信息展示,如下代码所示。
而特定表单的内容展示,这是通过动态化组件的呈现方式(is)来指定具体渲染的那个页面组件
而通用的申请单编辑页面中,则是动态展示编辑对应组件页面的信息即可,如下所示。
而动态组件的处理,我们使用vue3的 defineAsyncComponent (需要了解可以查看官网)的处理方式进行加载对应组件页面。
我们在ts的setup代码块中的代码如下所示。
let viewType = ref(null); // 查看明细的组件类型 //根据申请单的模块类型定义,确定组件名称 function getViewType() { if (applyid.value) { // 一般规则:通过申请单的DataTable去掉前缀,转换小写,获得模块名称,如TW_Payment => payment var param = { applyId: applyid.value }; apply.GetModuleName(param).then(data => { if (data) { console.log(data); let pageComponent = defineAsyncComponent(() => import(`/@/views/workflow/modules/view/${data.toLowerCase()}.vue`)); // console.log(pageComponent); viewType.value = markRaw(pageComponent); } }); } }
而其中viewType就是我们组件的名称,这里能够呈现出来的内容,必须是这些组件在对应的工作流目录中的,通过动态的加载方式,可以实现页面组件的动态渲染处理了。
而我们定义的表单内容可能很多,如下目录所示。
其中我们以报销申请单的查看页面来了解,页面展示部分如下代码所示。
<el-form ref="viewRef" :model="viewForm" label-width="120px"> <el-tabs type="border-card"> <el-tab-pane label="基本信息"> <el-descriptions title="" :column="2" border> <el-descriptions-item label="报销类型"> {{ viewForm.category }} </el-descriptions-item> <el-descriptions-item label="报销事由"> {{ viewForm.reason }} </el-descriptions-item> <el-descriptions-item label="总金额"> <el-input v-model="viewForm.totalAmount" disabled style="width: 150px"> <template #suffix> 元 </template> </el-input> </el-descriptions-item> <el-descriptions-item label="备注信息" :span="2"> {{ viewForm.note }} </el-descriptions-item> <el-descriptions-item label="明细清单" :span="2"> <vxe-table ref="xTable" stripe highlight-current-row highlight-hover-row :data="detailData"> <vxe-column type="seq" width="60" /> <vxe-column field="feeType" title="费用类型" width="100" /> <vxe-column field="occurTime" title="发生时间" width="250" /> <vxe-column field="feeAmount" title="费用金额" width="100" /> <vxe-column field="feeDescription" title="费用说明" width="250" /> </vxe-table> </el-descriptions-item> <el-descriptions-item label="附件" :span="2"> <my-upload v-model="viewForm.attachGUID" :disabled="true" :data="{ guid: viewForm.attachGUID, folder: '申请单图片' }" /> </el-descriptions-item> </el-descriptions> </el-tab-pane> </el-tabs> </el-form>
主从表的数据,我们通过函数来实现加载处理,而后端对应提供相关的数据结构即可。
//挂载的时候初始化数据 onMounted(async () => { await getData(); //打开新增窗体的时候,初始化公司列表 }); function getData() { let applyid = props.applyid + ''; if (applyid) { reimbursement.FindByApplyId(applyid).then(data => { Object.assign(viewForm, data); // 获取从表明细记录 var headerId = viewForm.id; reimbursement.FindDetailByHeaderId(headerId).then(data => { detailData.value = data; }); }); } }
对于审批,我们提供一些通过、退回、取消的申请单处理操作。
审批表单的界面
发起会签操作界面
撤销自己表单的处理界面
由于申请单的各种类型节点的处理不同,如果页面引入这些会显得很臃肿,因此我们把这些处理步骤组件化,然后再通过查看页面中整合审批、发起会签、会签、批示阅办、撤销、阅办等操作即可。
这样我们把一些常用节点的处理,单独作为组件开发,放置在组件目录中即可,方便维护。
Vue的组件化,可以简化页面的内容处理,把特定的部分放在一个组件中实现,更好的实现关注点的分离,以及可以自由组合更好的页面效果。
而为了方便,特定处理单的列表页面,我们也提供了查询展示的处理,便于跟踪查询对应类型的业务表单信息。
以上就是对于 Vue3+TypeScript的前端工作流模块中实现统一的表单编辑和表单详情查看处理的一些总结,希望对您有所启发和帮助。
系列文章:
《基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用》
《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》
《基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发》
《基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理 》
《基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转》
《基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口 》
《基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传》
《基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录》
《基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制》
《基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理》
《基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结》
《基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理》
《基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用》
《基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用》
《基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成》
《基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍》
《基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理》
《基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面》
《基于SqlSugar的开发框架循序渐进介绍(19)-- 基于UniApp+Vue的移动前端的功能介绍》
《基于SqlSugar的开发框架循序渐进介绍(20)-- 在基于UniApp+Vue的移动端实现多条件查询的处理》
《基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换》
《基于SqlSugar的开发框架循序渐进介绍(22)-- Vue3+TypeScript的前端工作流模块中实现统一的表单编辑和表单详情查看处理 》