|
问题背景工作量优化思路与方法优化用户体验总结未来的展望问题背景企业法务部门一直以来承担着合同处理的重要职责。随着企业规模的扩大,合同数量和复杂度不断增加,例如劳动合同、租赁合同、签约协议等。这些合同的内容一般都比较复杂,不同的合同需要经常修改。再加上各级审批人的审批流程冗长,修改成本和审批成本的叠加导致法务部门处理合同效率低下。为此,企业法务部门根据合同的特点将其分为模板合同和非模板合同。模板合同是指内容比较固定,只需针对部分内容进行填写或修改的合同。企业法务部门希望将模板合同的能力扩展到OA系统上,借助OA系统完成合同填写、修改、归档审批等工作,从而提高工作效率。工作量优化思路与方法为了解决法务部门的工作量问题,让我们来看看法务部门的工作流程。法务部门的工作流程如图1所示:图1.工作流程从图中可以看出,法务部门原来的工作流程主要包括合同的转化、填写、归档审核等环节。合同的转化步骤:法务同事将合同的设计文件定版转化为PDF文件。填写步骤:在转化后的PDF文件中,法务同事填写本次合同要用到的信息,例如联系人电话、联系人地址等。归档审核步骤:法务同事将填写完成的合同逐级提交给上级和不同的负责人审阅。最后,将经过审核的合同归档保存。这样的工作流程,法务同事需要花费时间去填写合同的内容。而且,在定稿之后,还需要发送给各级领导进行审阅。但是,由于合同的内容复杂,加之让领导来回审阅的过程也比较繁琐,导致工作效率低下。针对上面的情况,我们可以将法务模板合同的工作流程抽象为OA系统中的线上流程。首先,我们可以将合同的转化步骤抽象为OA系统中的上传步骤。预先处理好PDF文件,并将要填写的内容处理为XLS文件,然后上传到系统中。然后,我们可以将合同的各级负责人审阅的步骤抽象为Activiti引擎中的一个流程。OA系统会代替法务同事完成PDF文件的转化和填写内容的校验和填写。流程步骤作为审批步骤,不需要法务同事再去挨个找不同的负责人审阅。这样,如图2所示,我们就将合同的转化、填写、归档审核等环节抽象为了OA系统中的上传、填写、审批流程线上化等环节,从而提高了工作效率。image图2.初步流程等等,这可不行!如果这样做,真的能提高效率吗?随着公司持续发展,模板合同的数量会越来越多。像上图所示,每一个模板合同都对应着一个Activiti流程。每新增一个模板合同,就需要设计一个Activiti流程。熟悉Activiti引擎的同学都知道,设计一个Activiti流程需要构造Bpmn图、编写流程代码、部署流程等,这会给开发人员带来很大的工作量。在大量模板添加的情况下,开发人员就会成为瓶颈,无法快速提高效率,最终导致工作效率并没有提升。那么,我们应该如何优化呢?别急,一切皆可抽象。通过梳理已有的几十个模板合同的逻辑,我发现,这些模板合同虽然内容各不相同,但总体上可以分为5个大类。并且,这五个大类的审批流程中,有些审批节点是相同的,例如,每个合同都需要财务部门的同事审阅。因此,我们可以重用这些审批节点。图3展示了优化前后的对比图:image图3.优化前后对比image图4.流程隶属的五大类流程因此,我们可以将N次的工作量简化为一次,只需将5个大类的审批流程抽象出来。这样,每新增一个模板合同,只需要根据合同的分类,即可执行对应的流程,从而减少了工作量。此外,上述流程中的文件内容校验,可以在Apollo配置中心配置对应的校验规则,以进一步减少工作量。我们可以利用Excel的数据校验、数据选择框等功能来限制填写内容。同时,利用Apollo配置中心将每个合同的填写内容规则抽象出来,设置为一个个的Apollo配置。然后,在上传合同时,根据合同的分类获取对应的Apollo配置,实现一个通用的校验器。最后,根据配置来校验填写的内容是否符合规则。图5展示了配置中心和校验器的交互过程:image图5.配置中心和检验器交互通用的校验器的实现示例代码如下所示: public static OpResult> checkExcelIsValidOrNot(InputStream inputStream, String templateName) throws Exception { Sheet sheetByStream = getSheetByStream(inputStream, "sheet1"); StringBuilder errMsg = new StringBuilder(); String templateData = config.getProperty(templateName, ""); JsonNode jsonNode = JsonUtil.string2JsonNode(templateData); JsonNode content = jsonNode.get("content"); HashMap DFNeedMap = Maps.newHashMap(); int row = 1; int max = 200; while (row
|
|