编写版本:v3.5.8
适用版本:v3.5.8+

一、 Groovy脚本使用说明

1.1、概要说明

说明:在平台配置开发中,如果平台原提供的脚本无法满足业务需要,可根据具体业务情况自定义开发符合自身业务需要的脚本。比如:流程分支网关中需要根据扩展属性值配置走不同分支,这时需要自己开发一个获取扩展属性值的脚本方法!

简介:groovy脚本是维护在后端的iform-excessive-root\modules\platform-excessive工程目录下,产品自带维护在下面脚本类中:

1、BpmnScript.java  //主要与工作流接口业务相关脚本
2、BusinessScript.java //主要业务逻辑相关脚本,比如:库存增/减,查询某个表再增加在另表等
3、CommonScript.java //通用脚本类,比如:获取当前用户信息、组织等
4、JdbcScript.java //主要与jdbc增加、更新、查询的脚本
5、ThridServiceScript.java //主要调用第三方接口相关脚本
6、ValidationScript.java //主要与数据唯一性做校验相关脚本

1.2、常用Bean列表

BeanID Bean说明 使用文档
cmd 流程执行对象(任务、实例) 移步链接地址:流程执行对象上下文说明
execution Activiti任务执行对象 移步链接地址:Activiti任务执行对象
mybatisTemplateProvider SQL执行对象(基于Mybatis,事务一致) 移步链接地址:SQL执行对象
jdbcScript JDBC脚本对象(基于JdbcTemplate,事务不一致) 移步链接地址:JDBC脚本对象
bpmnScript 流程脚本对象 移步链接地址:流程脚本对象
businessScript 业务脚本对象 移步链接地址:业务脚本对象
cscript 通用脚本对象 移步链接地址:通用脚本对象
thridServiceScript 第三方服务脚本对象 移步链接地址:第三方服务脚本对象
validationScript 校验脚本对象 移步链接地址:校验脚本对象

说明:

  • 调用规则:BeanID.方法名进行调用方式,即:cscript.getCurrentName();
  • 本身产品维护的脚本类中没有用户相关的业务方法,可自定义脚本类进行增加,开发指导移步:自定义脚本开发范例

二、平台中使用

2.1、表单管理

2.1.1 默认值-动态脚本(组件输入值来源)

登录系统,在【表单管理】-【表单管理】使用Groovy脚本主要在“默认值-动态脚本”、“选择器-范围脚本”、“标签和按钮-文本固定值动态脚本”的使用操作说明,如下图所示:

选择某条数据直接进入“表单设计器”,选中某个控件,在设计右边选择“默认值”属性下拉选择“动态脚本”,比如:选中是“单行文本”控件,如下图:

点击“动态脚本”进入编写脚本代码编辑器,比如:获取当前用户所在的组织名可调用脚本代码“cscript.getCurrentOrgName();”,如下图:

注意:脚本方法中返回的类型需要与业务对象定义的类型一致,比如:名称是字符串,年龄是数字,那么在后端脚本类方法返回的类型必须匹配一致!

  • CommonScript.java类中常调用方法说明:
方法 说明 返回类型 脚本调用方式
getAccount() 获取当前登录用户账号信息 字符串 cscript.getAccount();
getCurrentUserId() 获取当前登录用户ID信息 字符串 cscript.getCurrentUserId();
getCurrentName() 获取当前登录用户名称信息 字符串 cscript.getCurrentName();
getCurrentOrgName() 获取当前登录用户所在组织名信息 字符串 cscript.getCurrentOrgName();
getCurrentOrgId() 获取当前登录用户所在组织ID信息 字符串 cscript.getCurrentOrgId();
getCurrentPositionName() 获取当前登录用户所在的主岗位名称信息 字符串 cscript.getCurrentPositionName();
getCurrentPositionId() 获取当前登录用户所在的主岗位ID信息 字符串 cscript.getCurrentPositionId();
getCurDate() 获取系统当前日期,默认格式:yyyy-MM-dd 字符串 cscript.getCurDate();
getCurDateTime() 获取系统当前日期时间,默认格式:yyyy-MM-dd HH:mm:ss 字符串 cscript.getCurDateTime();

2.1.2 表单脚本

选择【表单管理】-【表单管理】选择某条数据进入“表单设计器”,选择“特色功能”-“表单脚本”按钮,如下图:

点击“表单脚本”按钮,进入编写前端脚本代码,如下图:

Object.assign(JForm, {
  codetop: new Map(),
  queryData: (request, data, callback) => {
    request({
      //单体服务接口地址
      url: '/form/def/getScriptValue',
      method: 'post',
      data: data
    }).then(response => {
      const { state, data } = response
      if (200 === state) {
        callback(true, data)
      }
    }).catch(error => {
      callback(false)
      console.log(error)
    })
  },
  //加载事件
  onLoad: function (form) {
    form.$refs.dynamicForm.$refs.formItemcgrkmxb[0].$watch('dataModel', (data) => {
      if (data && data.length > 0) {
        data.forEach(d => {
          if (d.propertyId) {
            const varsStr = JSON.stringify({
              subjectId: d.propertyId
            })
            const postData = {
              'script':
              `Map<String, Object> whereMainMap = new HashMap<String,Object>();
              whereMainMap.put("subject_id_",subjectId);
              whereMainMap.put("enable_","Y");
              jdbcScript.queryDataForList("t_materialcodemanage",null,whereMainMap,null);`,
              varsStr: varsStr
            }
            this.queryData(this.$request, postData, (flag, data) => {
              if (flag) {
                //一般只会有一条数据
                if (data && data.length > 0) {
                  if (!d.peopertyCode) {
                    const codefix = data[0].codefix_
                    const codetop = parseInt(this.codetop.get(data[0].id_) || data[0].codetop_ || 0) + 1
                    const codelen = (data[0].codelen_ - 4) > 0 ? (data[0].codelen_ - 4) : 0
                    d.peopertyCode = codefix + (Array(codelen).join(0) + codetop).slice(-codelen);
                    this.codetop.set(data[0].id_, codetop)

                  }
                }
              }
            })
          }
        })
      }
    }, { deep: true })
  }
});

调用原理,是通过this.$request 调用后端脚本,直接调用Groovy脚本类下的方法

 this.$request({
        //微服务的请求地址
        url:'/business/v3/form/def/getScriptValue',
        method: 'post',
        data:  { 
         'script': `Groovy脚本代码`
         }
      }).then(response => {
         //TODO:处理数据返回的逻辑
        }).catch(error => {
            console.log(error)
        })

说明: 表单脚本的细节指导开发说明,移步地址:表单脚本

2.1.3 唯一校验脚本

还是在【表单管理】进入表单设计器,选择“唯一校验脚本”按钮,调用脚本代码,如下图:

进入脚本页面,选择”插入默认脚本”-“所有”,选择后脚本代码自动填入如下图:

说明: 自动填入后只需要手动修改下“tableName”,改成表单对应的表,也就是需要做唯一校验的那张表,用英文的单引号或者双引号括起来,例如:
validationScript.validationDemoFull(‘t_project’, data)。

2.2、流程定义管理

登录系统,在【工作流程】-【流程定义管理】,选择某条数据进入配置页面。

2.2.1、设置事件脚本

在配置页面,选中某个节点再往右边区域选择“事件设置”页面(前置和后置同理),选择“编写脚本”按钮,如下图:

复制的代码范例,如下所示:
(1)直接更新当前业务对象物理表名的状态脚本代码

Map<String,Object> valMaps = new HashMap<String,Object>();
valMaps.put("status_", "spz");
//获取当前表单直接值,更新当前业务对象生成的物理表名,及更新字段数组
jdbcScript.updateDataByBusValue(businessKey_,"t_cgdd",valMaps);

(2)查询从表的信息进行批量保存,并将对应物品的库存进行相减,且将相减库存的信息记录在操作表

import com.ak.iform.platform.script.script.vo.TargetTableVo;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import com.ak.iform.platform.script.script.vo.ArchiveTargetTableVo;

Map<String,Object> valMaps = new HashMap<String,Object>();
valMaps.put("status_", "spz");
//更新当前主表的业务状态为spz(审批中)
jdbcScript.updateDataByBusValue(businessKey_,"t_cksqllb",valMaps);

ArchiveTargetTableVo outerdetailVo = new ArchiveTargetTableVo(
        "t_cksqllb", "id_", businessKey_, "parent_id_", "t_cksqllmxb", "t_kcczlsb", 
        "id_", "shu_liang_", "cao_zuo_shu_liang_", "-{{FIELD:cao_zuo_shu_liang_}}");

Map<String, String> outerdetailFieldRelationMap = new HashMap<>();
outerdetailVo.setFieldRelationMap(outerdetailFieldRelationMap);
outerdetailFieldRelationMap.put("id_", "id_");
outerdetailFieldRelationMap.put("peoperty_code_", "peoperty_code_");
outerdetailFieldRelationMap.put("type_id_", "type_id_");
outerdetailFieldRelationMap.put("storehouse_id_", "storehouse_id_");
outerdetailFieldRelationMap.put("property_id_", "property_id_");
outerdetailFieldRelationMap.put("supplier_id_", "supplier_id_");
outerdetailFieldRelationMap.put("cost_", "dan_jia_");
outerdetailFieldRelationMap.put("shu_liang_", "cao_zuo_shu_liang_");

Map<String, Object> outerdetailFieldParams = new HashMap<>();
outerdetailVo.setFieldParams(outerdetailFieldParams);
outerdetailFieldParams.put("lei_xing_", "outer");
outerdetailFieldParams.put("cao_zuo_ren_", cscript.getCurrentUserId());
outerdetailFieldParams.put("cao_zuo_shi_jian_", cscript.getCurDateTime());
//把当前出库的数据存储操作记录表
businessScript.archiveDataBySql(outerdetailVo);



Map<String, String> linkParams = new HashMap<>();
linkParams.put("wu_liao_id_", "id_");

Map<String, String> params = new HashMap<>();
params.put("shu_liang_", "ku_cun_");

Map<String, String> freeparams = new HashMap<>();
freeparams.put("feeze_count_", "feeze_count_");


TargetTableVo hcpcglbTableVo = new TargetTableVo("id_","t_cksqllmxb","t_materialManage","id_","","","","");

Map<String, String> hcpcglbFieldRelationMap = new HashMap<>();
hcpcglbTableVo.setFieldRelationMap(hcpcglbFieldRelationMap);
hcpcglbFieldRelationMap.put("peoperty_code_", "peoperty_code_");
hcpcglbFieldRelationMap.put("type_id_", "type_id_");
hcpcglbFieldRelationMap.put("storehouse_id_", "storehouse_id_");
hcpcglbFieldRelationMap.put("supplier_id_", "supplier_id_");
hcpcglbFieldRelationMap.put("property_id_", "property_id_");

hcpcglbFieldRelationMap.put("shu_liang_", "ku_cun_");
hcpcglbFieldRelationMap.put("feeze_count_", "feeze_count_");
hcpcglbFieldRelationMap.put("cost_", "cost_");
hcpcglbFieldRelationMap.put("lei_xing_", "lei_xing_");
hcpcglbFieldRelationMap.put("status_", "status_");

Map<String, Object> hcpcglbFieldParams = new HashMap<>();
hcpcglbTableVo.setFieldParams(hcpcglbFieldParams);  
//批量更新库存表
businessScript.syncNumberDataBySql(businessKey_, "t_cksqllmxb", "id_", "parent_id_", "t_materialManage", "parent_id_", linkParams, params, false, hcpcglbTableVo);
businessScript.syncNumberDataBySql(businessKey_, "t_cksqllmxb", "id_", "parent_id_", "t_materialManage", "parent_id_", linkParams, freeparams, true, hcpcglbTableVo);
com.ak.iform.base.framework.utils.J2CacheUtil.flushAll();

2.2.2、人员脚本

在流程配置页面,选中某个节点,在右边区域选择“用户设置”,如下图:

点击“添加人员”按钮,选择“人员脚本”类型,再点击“选择”按钮,如下图:

点击“选择”按钮,进入人员脚本配置页面,根据在后端脚本类中“CommonScript.java”维护的方法,进行调用写入“cscript.findCurrentUserSuperoirs();[获取通过在【上下级管理】维护的上级信息]”,如下图:

2.3、脚本规范

groovy可以直接使用spring中的beanId调用对应方法。

2.3.1、普通脚本

性能有所欠缺。

return cscript.getAccount();

2.3.2、预编译脚本

可以通过预编译方式提高脚本执行效率。

//script-type=pre
//script-name=Script1
//execute-method=execute

public void execute(Map<String, Object> vars) {
    vars.get("cmd");
    vars.get("execution");
    vars.get("businessKey_");
    vars.get("instanceId_");
    vars.get("flowKey_");
}

// 方法规范
// 不能使用run命名,会与groovy的方法冲突
// 开始/结束节点变量说明
//execution 类型 com.ak.iform.bpmn.api.model.delegate.BpmDelegateExecution
// 任务节点变量说明
//execution 类型 com.ak.iform.bpmn.api.model.delegate.BpmDelegateTask
// 通用节点变量说明
//yzfwb 类型 com.ak.iform.base.bo.model.DataObjectModel
//nodeDef 类型 com.ak.iform.bpmn.api.model.node.IBpmNodeDefine
//businessKey_ 类型 java.lang.String
//saveBusinessDataMode_ 类型 java.lang.String
//subject_ 类型 java.lang.String
//processDefId_ 类型 java.lang.String
//curUser 类型 java.lang.String
//task_id_ 类型 java.lang.String
//instanceId_ 类型 java.lang.String
//startUser 类型 java.lang.String
//task_qualfied_executor_ids_ 类型 java.lang.String
//flowKey_ 类型 java.lang.String
//isSaveBusinessData_ 类型 java.lang.Boolean
作者:黄春艳  创建时间:2024-12-17 20:50
最后编辑:黄春艳  更新时间:2025-01-10 15:50