实践案例 | 流程自定义弹窗校验,保障资金审核支付安全

科技   2024-09-25 07:45   广东  

每工作日一、三、五早上07:45

准时为你带来最新产品资讯


面对财务审核的复杂性,企业如何构筑一道坚固的防线,确保资金审核支付的安全性?

本案例介绍了一种审批流程自定义弹窗校验解决方案,简化财务审核流程的同时大幅提升了支付安全性,且二开量小、可复用性强,推荐阅读。















1 业务背景














在国家积极推动企业数字化转型的浪潮中,企业内部数字化升级亟需高效整合各类业务系统,以驱动生产力飞跃。然而,面对财务报销的多样化、流程场景的灵活变化以及财务系统本身的复杂性,如何强化权限控制、确保资金审核支付的安全性,成为亟待破解的难题。


客户A在数字化转型征途中亦遭遇此挑战,其核心痛点包括:


  1. 报销类型繁多,财务系统数据相对独立,审核人员需独立控制付款账户权限,并执行独立校验。

  2. 财务审核链条冗长,校验机制复杂且灵活性不足,难以适应特殊场景下的安全校验需求,缺乏统一的成熟方案。

  3. 鉴于成本控制考虑,如何低成本、高效率地实现可配置化的定制功能开发,促进资产复用,也是客户亟待解决的关键问题。


基于上述痛点分析,客户需求聚焦于:


1. 简化审批流程校验,统一校验入口


集成审核校验流程,简化分散的校验条件,统一入口,无需开发多种校验类型。


2. 场景适应强,自由度高的流程弹窗校验


流程弹窗完全二开,拥有极高的自由度,可适配各类复杂财务审核场景。


3. 资产复用,扩展产品应用场景的能力


标准产品仅支持工作流弹窗校验账户密码或者手机验证码校验,不可同时使用,也无法进行扩展开发。二开方案需扩展标准产品的工作流弹窗应用场景,提高场景适配度和自由度,实现资产复用。



2 解决方案














2.1 方案整体思路


针对以上问题,如何基于苍穹平台,实现工作流自定义弹窗校验,可以从以下三个方面入手:

校验表单开发:根据业务校验流程,二开一个动态校验表单。

审批页面校验弹窗开发:统一审批校验流程入口,流程审批人操作时弹出自定义校验表单弹窗。

工作流审批节点配置:配置工作流审核操作校验,操作完成弹出校验表单弹窗,完成校验信息填写后,后台完成信息校验才可放行审核(强校验),否则不可进行审核。


业务校验流程


2.2 关键实现步骤


1. 校验表单开发


在“开发平台>财务云>出纳>付款单”中新建动态表达元数据(kye_zpsecondvalidate),如下图所示:



在【开发平台】打开二开的元数据(kye_zpsecondvalidate),绑定二开插件后保存。


绑定插件


获取密码及发送的验证码信息校验完成后,向父级页面回传参数(核心要点:通过父级页面回调判断是否已进行二次校验,判断是否提示操作工作流弹窗)


this.getView().returnDataToParent() 插件核心代码如下:


/** *  * @author cyf * 2024.6.22 * 组批审核节点,二次校验表单插件 */
      private static Logger logger = Logger.getLogger(PayzpSecondValiFormPlugin.class);     @Override      public void registerListener(EventObject e) {          super.registerListener(e);          this.addClickListeners("kye_send");          this.addClickListeners("kye_login");                    CountDown countdown = this.getView().getControl("kye_countdownap");          countdown.addCountDownListener(this);      }     @Override      public void click(EventObject evt) {          super.click(evt);          Control control = (Control) evt.getSource();          String itemKey = control.getKey();          switch (itemKey) {              case "kye_send":                  sendSMS();                  break;              case "kye_login":                close();                  break;                default:                  break;          }      }        /**       * 发送短信验证码接口       */      private void sendSMS() {        //发送验证码,并缓存到页面隐藏字段        SecondaccountVerifyHelper.sendSMS(this.getView());      }                  @Override      public void onCountDownEnd(CountDownEvent evt) {          CountDownListener.super.onCountDownEnd(evt);          this.getView().setEnable(true,"kye_send");          this.getView().setVisible(true,"kye_labelap1","kye_labelap2","kye_countdownap");      }            @Override      public void afterCreateNewData(EventObject e) {          super.afterCreateNewData(e);          this.getView().setVisible(false,"kye_labelap1","kye_labelap2","kye_countdownap");      }      /**       * 关闭页面,并且把账号,密码,验证码回传到父级页面缓存       */      private void close() {                  String input = (String) this.getModel().getValue("kye_input");          String userPassword = (String) this.getModel().getValue("kye_password");          if (StringUtils.isBlank(input) || StringUtils.isBlank(userPassword)) {              this.getView().showErrorNotification("请输入验证码或密码!");          } else {                                    //当前账户id            String accountId = RequestContext.get().getAccountId();            //先直接验证,不通过不允许关闭弹窗            SecondaccountVerifyHelper.validateForm(accountId, userPassword, input,  this.getView().getPageCache().get("captcha_chird"), this.getView());            //验证成功,向父级页面-付款组批单传递缓存            IPageCache iPageCache = this.getView().getParentView().getService(IPageCache.class);            iPageCache.put("accountId", accountId);            iPageCache.put("userPassword", userPassword);            iPageCache.put("messageCode", input);            this.getView().returnDataToParent("isOPen");            //关闭当前页面            this.getView().invokeOperation("close");          }      }


2. 审批页面校验弹窗开发


在“开发平台>流程服务云>工作流服务>任务中心”扩展标准审批表单wf_approvalpage_bac,用于审批人操作弹出自定义校验表单,绑定二开插件即可。

注意:必须使用this.getPageCache().get("bizIdentifyKey")来判断当前单据节点是否需要弹窗校验,目前无其他办法。



弹窗核心代码如下:


/** *  * @author cyf * 2024.8.13 * 扩展审批处理页面编码为wf_approvalpage_bac 进行弹窗处理 * */public class ApprovalpageBacFormPlugin extends AbstractFormPlugin{       private static Logger logger = Logger.getLogger(ApprovalpageBacFormPlugin.class);         // 缓存中的kev -用于记录是否已经加载过弹出窗口    private final String PAGECACHEKEY_CALLBACK = "beforeSubmitCustomEventArgsCallbackResult";    //弹出窗口的callbackidprivate     private  final String CALLBACKID ="beforeSubmitCustomEventArgsCallback";            @Override    public void afterCreateNewData(EventObject e) {          super.afterCreateNewData(e);          String isneedValidta=getView().getFormShowParameter().getCustomParam("isneedValidta");          logger.info("=====s审批界面自定义参数isneedValidta:"+isneedValidta);          if("true".equals(isneedValidta)) {             this.getPageCache().put("isneedValidta", "true");          }    }            public void customEvent(CustomEventArgs e) {      if(e instanceof BeforeSubmitCustomEventArgs){      //丛缓存中装取标志      String result = getPageCache().get(PAGECACHEKEY_CALLBACK);      //如果有缓存 且为true,说明之前已经弹出窗口,并且继续往下流转      if(null != result && Boolean.parseBoolean(result)) {          return;      }      //先查询自定义界面参数,看是否需要弹窗校验      String isneedValidta=this.getPageCache().get("bizIdentifyKey");      logger.info("=====审批界面自定义参数bizIdentifyKey:"+isneedValidta);      //获取审批决策项。只有提交才需要弹窗      String combo_decision=(String) this.getModel().getValue("combo_decision");      logger.info("=====审批界面审批决策项combo_decision:"+combo_decision);      if("isneedValidta".equals(isneedValidta)&&combo_decision.contains("Consent")) {        BeforeSubmitCustomEventArgs be=(BeforeSubmitCustomEventArgs)e;        //设置任务不提交        be.setCancel(true);        //弹出自己页面,进行展现        FormShowParameter parameter=new FormShowParameter();        String formId ="kye_zpsecondvalidate";        // TODO 替换为自己的fonmid        parameter.setFormId(formId);        parameter.getOpenStyle().setShowType(ShowType.Modal);        parameter.setCloseCallBack(new CloseCallBack(this, CALLBACKID));        getView().showForm(parameter);      }            }    }        @Override    public void closedCallBack(ClosedCallBackEvent e) {       if(null == e){         return;       }                Object returnData=e.getReturnData();      if(null == returnData) {          return;      }      String callBackId =e.getActionId();      if(CALLBACKID.equals(callBackId)) {        BeforeSubmitCustomEventArgsClosedCallBack args = new BeforeSubmitCustomEventArgsClosedCallBack(this.getView(), null, null, null);        // TODO 做逻辑判断- 是否需要提交任务;true表示需要重新提交、false表示不需要任务提交boolean doSubmitTask =true;        boolean doSubmitTask =true;        //设置是否直接提交任务        args.setDoSubmitTask(doSubmitTask);        //将设置的结果,放到cache中,用于下一次进入custom事件进行判断,是否需要再次弹出窗口        getPageCache().put(PAGECACHEKEY_CALLBACK, String.valueOf(doSubmitTask));        //发送回调事件proxy.fireCustomEvent(args);        FormViewPluginProxy proxy = (FormViewPluginProxy)getView().getService(FormViewPluginProxy.class);        proxy.fireCustomEvent(args);      }}


3. 工作流审批节点配置


在单据的流程审批节点配置业务标识(第二步this.getPageCache().get("bizIdentifyKey")获取的),用于用户操作弹出自定义校验表单:



配置审核操作校验第二步配置的自定义操作accountpss,审核时可触发单据的表单事件beforeDoOperation,在此事件校验业务。



表单事件核心代码如下:


public class OPenValiFormPlugin extends AbstractFormPlugin{  @Override  public void beforeDoOperation(BeforeDoOperationEventArgs args) {    super.beforeDoOperation(args);    FormOperate oprate=(FormOperate) args.getSource();    String opkey=oprate.getOperateKey();    //审批操作二次校验并同时校验用户的银行操作权限(由于工作流只可配置一个操作校验,故先执行弹窗二次校验校验),accountpss操作含银行操作权限插件校验    if("accountpss".equals(opkey)) {      //先判断当前页面缓存,判断是否已经进行弹窗二次校验,      boolean isOPenForm=SecondaccountVerifyHelper.isOPenForm(this.getView());      if(!isOPenForm) {        //未进行弹窗校验,直接弹窗        SecondaccountVerifyHelper.OpenForm(this.getView());        args.setCancel(true);      }    }     }


最后注意点:

由于本质是在审核单据弹窗,标准消息中心批量审核会绕过本表单校验配置,故需要禁用批量审核操作。扩展标准表单禁用批量操作即可。




3 方案效果














直接审核弹出二次校验表单,弹出校验表单,填写校验信息,确认后,后台校验完全通过才可审批通过。




4 方案的可推广价值














  • 行业的普适程度


该方案不限制行业及校验内容,所有需要进行审批自定义弹窗场景的,均可使用。扩展了标准产品的二次校验场景范围,可形成资产复用。


  • 对客户的价值


简化校验流程,开发量小,自由度极高,场景适配广泛。



#往期推荐#

# 实践案例|基金信息投资管理系统,“业务流+工作流”的创新应用!

实践案例|业务批量化工作:实现复制、编辑、审批一体化流程

实践案例 | 如何通过微信公众号模板消息定向推送供应商招投标信息

实践案例 | 巧用操作参数+状态机,个性化组装事件订阅



对文章有任何疑问或建议,欢迎评论区留言~

PaaS平台那些事
分享苍穹最新特性、功能使用和开发小技巧、最佳实践等,做苍穹用户的知心朋友
 最新文章