1 初级开发
1.1 前端脚本开发
1.1.1 脚本基础
前端脚本是标准的JavaScript脚本,语法与ECMAScript 6相同,开发人员与实施人员需要一定的JavaScript基础。同时,前端脚本为配合DWF的UI表单的操作而编写,还需理解DWF的界面表单定制功能。
下面介绍前端JS脚本常用的API。
1.1.1.1 获取表单界面各元素控件
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//控件的id可在app端开发者工具中拾取,后期可在modeler中直接拷贝
var addinElement = this.GetAddinById("指定控件的id");
//设置控件在界面中的错误信息提示
addinElement.setError("存在异常");
//$el为指定控件的dom元素,可以直接对dom元素修改其样式
addinElement.$el.style.display = "none"; |
1.1.1.2 修改表单界面元素控件的样式
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//控件的 id 可在 app 端开发者工具中拾取,后期可在 modeler 中直接拷贝
var addinElement = this.GetAddinById("指定控件的 id");
//$el 为指定控件的 dom 元素,设置该元素隐藏
addinElement.$el.style.display = "none";
// 设置该元素重新显示
addinElement.$el.style.display = "block"; |
1.1.1.3 获取单对象表单中的对象
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
// obj为当前单对象(修改)表单绑定的业务对象 (且被表单修改后的数据)
var curObj = this.obj;
// 修改数据属性
curObj.wfstate = "已安装";
// 1-执行对象修改保存
this.editEObj({ className: this.className, obj: curObj });
// 2-edit=editEObj+ fresh前端;更适用于单对象表单的保存后UI刷新.
this.edit(curObj, this.className); |
1.1.1.4 单业务类型(表单)表格操作
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//前提说明:单对象表单表格,表示该表单中主要就一个表格控件,且绑定了表单对应的业务类型,同时打开该表单的操作动作也是list模式,在这种前提下可简化表格数据的操作处理
//获取当前表单中主表格中选中的(多)行数据
var selectedObjs = this.selectedObjs;
if(selectedObjs && selectedObjs .length > 0){
selectedObjs.forEach(x => {
//对选中的数据进行修改
x.assetState = "已安装";
// 对修改后的数据进行保存
this.editEObj({ className: this.className, obj: x });
})
}s
//获取表格中所有的的行数据对象集合
var allRowDatas = this.getAll();
//TODO:… |
1.1.1.5.1 获取表格与表格中数据操作(获取与刷新)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取表格控件
var grdiAddin = this.GetAddinById("表格控件的id");
//获取表格中选中的(多)行数据
var selectedObjs = grdiAddin.getSelected();
if(selectedObjs && selectedObjs .length > 0){
selectedObjs.forEach(x => {
//对选中的数据进行修改
x.assetState = "已安装";
// 对修改后的数据进行保存,此时优先editEObj而非edit
this.editEObj({ className: this.className, obj: x });
})
}
//获取表格中所有的的行数据对象集合
var allRowDatas = grdiAddin.getAll();
//处理表格数据的刷新
let query = `and obj.tyWorkOrderOid = '${this.obj.oid}'`;
//表格后台数据强制刷新
this.handleQueryData({query:query,targetClass:"TyWork",fresh:true}).then(res=>{
//后台数据强查后,store会更新,会更新相同查询条件的多对象控件(表格)
grdiAddin.freshData(query); //如果store有数据,就不进行后台数据查询,不然就会进行后台数据查询(可以理解为调用freshData后,一定至少发生过一次后台数据查询).这里在handleQueryData之后调用,所以不会进行后台数据查询. 用处是用指定查询的最新结果刷新表格
grdiAddin.fresh(); //不执行后台数据查询,从store中获取原查询条件的最新结果刷新表格. 区别在于: 1. 查询条件为原查询条件,不能指定新的查询条件; 2. 不进行后台数据查询
this.msgbox.success("表格已刷新!");
})
//表格行数据额外操作(如:删除一行)
//grdiAddin.rowData.splice(selected[0].order,1);
/*针对关联对象handleQueryData查询示例*/
var query = {query:`and obj.left_oid in (${conceptoidlists})`,type:'relation'};
his.handleQueryData({query:query, relationClass:"OntologyConcept2Attribute", fresh:true}).then(
res=>{
//todo:
}); |
1.1.1.5.2 表格头部生成与数据结构数据操作(增删改,浏览器内存实现,不涉及数据库)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取表格控件
var grdiAddin = this.GetAddinById("表格控件的id");
//通过getDefaultColumnDefs方法获取列定义对象
//通过传入一个对象进行个性化定制
var columnDefs1 = grdiAddin.getDefaultColumnDefs();
var columnDefs2 = grdiAddin.getDefaultColumnDefs();
...
var columnDefsn = grdiAddin.getDefaultColumnDefs();
//设置表头
grdiAddin.setColumnDefs([columnDefs1, columnDefs2, ..., columnDefsn]);
var rowData = [
{field: 'field1', oid: 'oid1'},
{field: 'field2', oid: 'oid2'},
...
]
//设置表格数据
grdiAddin.setRowData(rowData);
//添加表格数据
grdiAddin.setRowData(rowData, 'add');
//删除表格数据(参数对应行)
grdiAddin.deleteRowData('1');
grdiAddin.deleteRowData(['2','3']);
//修改表格数据(参数对应行)
grdiAddin.updateRowData('4', {field: 'updatefield'}); |
1.1.1.6 业务对象的创建保存
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var newObj = {id:’idXXX’,name:’nameXXX’};
var className = ‘Part’;
//新增保存
this.create(newObj, className).then(newRtnObj =>{
//返回的newRtnObj为后台新增后返回的对象,即包含了oid等属性
//todo:针对newRtnObj继续处理…
});
this.create(newObj, className,{isRelation:false}/*如果关联类对象保存为true*/).then(newRtnObj =>{
//返回的newRtnObj为后台新增后返回的对象,即包含了oid等属性
//todo:针对newRtnObj继续处理…
});
/*补充说明关联类对象保存,如下所示:*/
var linkOBJ = {left_属性名:属性值,right_属性名:属性值,relation_属性名:属性值}; /*需扁平化的关联类属性*/
this.create(linkOBJ, className,{leftClass:左类类名,rightClass:右类类名,relationClass:关联类名,isRelation:true}/*如果关联类对象保存为true*/).then(newRtnObj =>{
//返回的newRtnObj为后台新增后返回的对象,即包含了oid等属性
//todo:针对newRtnObj继续处理…
}); |
1.1.1.7 业务对象的修改保存
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var editObj = {id:'idXXX’,name:'nameXXX’};
var className = ‘Part’;
editObj.id = ‘idYYY’;
this.edit(editObj, className).then(rtnObj =>{ /*是否区分实体类与关联类?*/
//返回的rtnObj为后台修改保存后返回的对象
//todo:针对rtnObj继续处理…
}); |
1.1.1.8 业务对象的删除
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var curObj = {oid:uuid,id:’idXXX’,name:’nameXXX’};
var className = ‘Part’;
this.delete(curObj, className).then(rtnObj =>{
// rtnObj返回值 = true/false,是否删除成功
//建议如果返回false,那么返回message错误原因提示信息
}); |
1.1.1.9 业务对象查询(前端store中查询)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//查询条件
let queryConditon = {
targetClass:"Part",
query:{query:`and obj.id='${this.obj.name}'`},
fresh: true //是否从后台强制刷新查询(建议默认值为true)
};
//该接口主要在store中进行查询(不查询后台DB)
let queryResult = this.QueryResultAll(queryConditon);
//TODO:查询结果queryResult处理 |
1.1.1.10 业务对象查询(DB中查询)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//针对实体类查询
let queryConditon = {
targetClass:"Part",
query:{query:`and obj.id='${this.obj.name}'`},
fresh: true //是否从后台强制刷新查询(建议默认值为true)
};
//基于DB进行查询
this.handleQueryData(queryConditon).then(res => {
//针对res值(查询返回值)直接处理…
});
//针对关联类查询
let queryPara = {
relationClass:"OntologyConcept2Attribute",
query:{query:`and obj.left_oid in (${conceptoidlists})`,type:'relation'},
fresh: true //是否从后台强制刷新查询(建议默认值为true)
};
//基于DB进行查询
this.handleQueryData(queryPara).then(res => {
//针对res值(查询返回值)直接处理…
}); |
1.1.1.11 打开表单前的数据初始化-实体类
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//1-单打开前初始化脚本(所有参数说明)
return {
//对象对象
/*@扩展点:该处还需要考虑link关联类对象的json对象格式与表单初始化时针对该变量的解释,link对象的json格式参考如下:
obj:{leftObj:{…},linkObj:{…},rightObj:{…}}
或
obj:{oid:’’,id:’’,name:’’, leftoid:’’, leftoid_id:’’, leftoid_name:’’,rightoid:’’, rightoid_id:’’, rightoid_name:’’}
//上面两种格式可任取其中一种?
*/
obj:{…}, //单对象json
//查询语句模式
query:`and obj.state='editing'` , //如果直接传空(``)那么表示全查
show:false, //是否显示,如果false渲染出来的是空白页面
data:{…} //是否有效待验证?
};
//2-表单打开前初始化脚本(如根据当前所选对象打开弹窗查看详情)
var curOBJ = this.selectedObjs[0];
return {
obj: curOBJ, //单对象
data:{…} //补充参数对象,可空
};
//3-表单打开前初始化脚本(根据查询条件)
return {
query: `and obj.state='editing'`, //查询条件
data:{…} //补充参数对象,可空
};
//4-表单打开前初始化脚本(补充传递参数)
return {
data:{…} //补充参数对象,可空
};
//5-表单打开前初始化脚本(补充传递参数)
var judgeRtn = false; //or true
//TODO: judgeRtn赋值?
return {
if(judgeRtn){
show:true, //正常渲染表单界面元素
data:{…} //补充参数对象,可空
}else{
show:false //目前指不渲染表单界面元素
}
}; |
1.1.1.12 打开表单前的数据初始化(新建对象-典型场景)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//新建实体对象弹窗前处理
var judgeRtn = true;
//TODO: judgeRtn值逻辑判断
var newObj= {};
//TODO: 给新对象赋初始值,建议前后端能提供API获取默认新内存对象(包括默认值处理),如:newObj = this.getDefaultNewOBJ(‘className’);
newObj.state = ‘新建中’;
return {
if(judgeRtn){
obj: newObj, //正常渲染表单界面元素
data:{…} //补充参数对象,可空
}else{
show:false //不渲染表单界面元素
}
};
//新建关联表单前初始化
//左对象保留字:left_[属性英文名],右对象保留字:right_[属性英文名],关联对象保留字:relation_[属性英文名]
var grid = this.getAddinById("");
var rels = grid.getSelected();
if (rels.length > 0){
return{
obj:{
relation_leftOid: rels[0].relation_leftOid
}
}
} |
1.1.1.13 得到系统的上下文信息(当前登录用户与服务器IP等)
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取当前服务器端IP
var curServerIP = this.env.serverIp;
//获取当前登录用户
var curUserId = this.user.oid;
//调用modeler端的restful API
this.dwf_modeler_axios("/dwf/v1/org/users/${curUserId}/groups"); |
1.1.1.14 获取实体类与关联类的元信息
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取实体类的元模型信息
this.queryEntity(targetClassName).then(resMetaObj => {
//在回调中处理resMetaObj值…
});
//获取关联类的元模型信息
this.queryRelation(targetClassName).then(resMetaObj => {
//在回调中处理resMetaObj值…
}); |
1.1.1.15 调用restful API
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//1-调用modeler的restful API
this.dwf_modeler_axios("/dwf/v1/org/users/${curUserId}/groups"),param).then(rtnOBJ => {
// 在回调中处理rtnOBJ值…
//
});
//2-调用app的restful API示例1
//this.dwf_axios.post(`http://192.168.30.63/workorder/init`,param);
let param = {
};
this.dwf_axios.post(`/workorder/init?tyWorkOrderOid=${this.obj.oid}`,param).then(initRes => {
//在回调中处理
if(initRes && initRes.data && initRes.data.result && initRes.data.result == true){
this.msgbox.success('已完成基于专家库作业信息的初始创建!');
}else if(initRes && initRes.data && initRes.data.msg){
alert(initRes.data.msg);
}
});
//2-调用app的restful API示例2
let param = [{
comment: "string",
displayName: "测试创建用户",
email: "string@fds.com",
expiredTime: "2018-11-28T08:57:03.034Z",
name: "testClientScriptHTTPRequest",
password: "string"
}]
let res = this.dwf_axios.post(`org/users-create`,param).then(res => {
if(res && res.返回值?){
alert("用户创建成功!");
}else{
alert("用户创建失败!");
}
});
//3-调用其它服务器的restful API
var param = {…};
this.axios.post(`uri全路径`,param).then(rtnOBJ => {
//回调处理…
}); |
1.1.1.16 Tab页签控件处理
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var tabAddin = this.GetAddinById("e09c6207-b578-4992-9f77-cbdc75bf86ce");
tabAddin.setDisable('子页签名称',true); //禁用子页签
tabAddin.setDisable('子页签名称',false); //取消子页签禁用
tabAddin.getSelectedTab(); //获取当前选中子页bi
tabAddin.turnTo("作业卡下步骤"); //跳转激活子页签 |
1.1.1.17 表单中嵌套子表单的控制
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var subFormAddin = this.GetAddinById("表单控件ID");//获取子表单控件
subFormAddin.setDisplayType("visit");
var targetClass = ‘业务类型名称’;
var viewName = ‘表单名称’;
subFormAddin.updateShow(targetClass, viewName, {
obj: {…}, //单业务对象
query: `and obj.oid = ${selectOBJOid} `, //查询条件,只能使用${变量名}
data: {}, //其它扩展传递的参数
show: true, //控制子表单是否渲染显示
initScript: "", //初始化脚本
condition: " and obj.oid=$obj.oid " //可使用$obj,$env转义字符变量(在前端解释这些变量)
}); |
1.1.1.18 设置单对象表单的(增改查)三态
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//@扩展点: (暂不支持)
//在表单初始化事件中脚本处理表单的增删改三态(暂不可用,建议后期平台提供)
var formType= this.data.formType; //data对象在表单打开前初始事件中赋值
this.t_create=false;
this.t_edit=false;
this.t_visit=false;
if(formType == ‘create’){
this.t_create = true ;
}else if(formType == ‘edit’){
this.t_edit = true;
}else if(formType == ‘visit’){
this.t_visit = true;
this.args.readonly = true;
} |
1.1.1.19 DWF的几种msgbox用法
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//目前如下几种消息提示都是在界面上方提示后自动关闭
this.msgbox.success("成功的提示");
this.msgbox.info("一般的提示");
this.msgbox.error("错误的提示");
//@扩展点(暂不支持)
//建议补充模态弹窗提示后需手动关闭的msg提示框,参考如下:
this.msgboxDialog.success(“title标题”,"成功的提示");
this.msgboxDialog.info(“title标题”,"一般的提示");
this.msgboxDialog.error(“title标题”,"错误的提示");
//@扩展点(暂不支持)
//建议补充comfirm确认弹窗(包括确认与取消按钮)
this.msgboxDialog.confirm (“title标题”,"请确认是否删除?", <function>(点击确定之后的回调函数), <function>(点击取消之后的回调函数));
|
1.1.1.20 如何获取用户所属的用户组信息
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var userId = this.store.state.user.userId;
var param = {…};
this.dwf_modeler_axios(`/dwf/v1/org/users/${userId}/groups`),param).then(groupOBJ => {
// 在回调中处理groupOBJ值…
//
}); |
1.1.1.21 如何通过脚本在新的标签打开界面
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
var targetClass = 'part';
var viewName = 'allPartList';
var args = {}; //args是{ conditionExpre: 查询条件, params: 初始化脚本 },如果没有args可以传空
this.openForm(targetClass, viewName, args); |
1.1.1.22 在前端利用vueX保存自定义参数信息
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//增加自定义参数
this.store.state.DWF_customer["testCustomerData"] = {"hello":"world"}
{hello: "world"}
//查询自定义参数
this.store.state.DWF_customer["testCustomerData"]
{hello: "world"}
//修改自定义参数
this.store.state.DWF_customer["testCustomerData"] = {"hello":"hello world"}
{hello: "hello world"}
//删除自定义参数
delete this.store.state.DWF_customer["testCustomerData"]
//localStorage前端存储
localStorage.setItem("key",'value');
var data=localStorage.getItem("key");
localStorage.removeItem("key");
localStorage.clear();//清空localStorage中所有信息,慎用
//sessionStorage与localStorage类似,只是作用域小一些,推荐 |
1.1.1.23 表单点选器控件与调用
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//控件作用:获取指定类的表单模板下拉列表
//要获取表单模板的类名称(实体类或关联类)
var targetClass = "Part";
//多对象控件组中的'表单点选器'控件【内置的控件】
var addinElement = this.GetAddinById("表单点选器控件ID");
//控件updateClass方法:刷新类的表单下拉列表
addinElement.updateClass(targetClass); |
1.1.1.24 弹窗中确认按钮脚本终止弹窗
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//...
return {error:'当前弹窗保存时发生错误,该Dialog窗口不能关闭!'}
//... |
1.1.1.24 Tree控件脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取树控件
var tree = this.getAddInByID('TreeID');
//刷新整颗树
tree.updateTree();
//... |
1.1.1.25 树表联动
代码块 |
---|
|
var tree = this.getAddinById("BomTree");
var grid = this.getAddinById("MaterialList");
//获取当前被选中的树节点,树节点如果是根节点,则返回根节点的实体类对象,如果是中间节点则返回父亲到孩子的关联
var nodes = tree.getSelected();
if (nodes.length == 0) {
return;
}
let query = "";
if ('right_oid' in nodes[0]){
//说明是孩子节点,表示是关联关系,其中右对象是选中对象,左对象是选中对象的父亲
query = `and leftclass.plt_oid = "${nodes[0].right_oid}"`;
}
else{
//说明是根节点
query = `and leftclass.plt_oid = "${nodes[0].oid}"`;
}
//要求表格刷新
grid.freshData(query); |
1.1.1.25 Combox下拉列表控件脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取控件
var comB = this.getAddInByID('uuid');
//设置控件值
comB.args.selectList = [{label:"label1", value:"value1"}, {label:"label2", value:"value2"}] ;
//... |
1.1.1.26 表单点选器API
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//获取控件
var formModelSelected = this.getAddInByID('uuid');
var targetClass = 'classNameA';
formModelSelected.updateClass(targetClass);
//实体表映射-plt_mdl_metaclass |
1.1.1.27 通过脚本下载附件
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//直接弹框拿到指定oid对象附件属性,并弹窗
window.open("http://[服务器IP]:9090/dwf/v1/omf/classes/[实体类名]/objects/8572063499837340B8246FB37C596806/attributes/[附件属性名称]/bytes?attachment=true&0")
//不用弹框当前页面直接下载
const downloadFileA = document.createElement('a')
document.body.append(downloadFileA)
downloadFileA.href= "http://[服务器IP]:9090/dwf/v1/omf/classes/[实体类名称]/objects/8572063499837340B8246FB37C596806/attributes/[附件属性名称]/bytes?attachment=true&0"
downloadFileA.click()
document.body.removeChild(downloadFileA)
//多附件下载补充说明
1-多附件的话,http://192.168.1.81:6060/dwf/v1/files-download/{fdsafds}, 大括号中是文件ID。文件ID则需要从对象的多附件属性当中取出来
2-对象中对应多附件控件的那个属性中存储的内容的格式是这样的:[{"name":"大数据时代.txt","size":"106.085KB","file_id":"ff8081816cedab93016cedc61a70004f"}] |
1.1.1.28 创建前端内存对象
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//新创对象的业务类名称
var className = "TeacherAuto";
//创建前端内存对象
var newBizOBJ = this.createObj(className);
//测试
console.log("新增内存对象oid=" + newBizOBJ.oid); |
1.1.1.29 如何调用自定义控件读取后端数据显示在Echart里面
代码块 |
---|
//通过异步调动获取数据
this.handleQueryData({targetClass:"DataSource"}).then(res => {
//将返回结果的特定属性提取出来
let dsNames = res.map( o => o.sourceName );
let dsTypes = res.map( o => o.sourceType );
//设置Echart的选项
option = {
xAxis: {
type: 'category',
data: dsNames
},
yAxis: {
type: 'category'
},
series: [{
type: 'line',
data: dsTypes
}]
};
//myChart是约定的全局变量
myChart.setOption(option);
}) |
1.2 后端脚本开发
1.2.1 脚本基础
后端脚本由服务端的JavaScript解释器解释执行,通过内置对象完成业务逻辑。默认的内置对象与解释如下:
...
eg: console.log(obj)
1.2.2 脚本示例
1.2.2.1 启动Shell命令
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//开始脚本编写
serverScript:
//在/home/dwf目录中根据当前对象的oid和用户名创建一个文件
this.sh.execute("cd /home/dwf && touch " + _obj.oid + "-" + _env.userName); |
1.2.2.2 直接执行SQL
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
//开始脚本编写
serverScript:
//先定义一个函数,产生UUID
function id() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
//利用hibernate的em对象执行SQL
this.em.createNativeQuery("insert into public.plt_org_user(plt_oid, plt_creator, plt_lastmodifier, plt_name, plt_displayname) values ('" + id() + "', '9C92E891E9AE534DB685737DE467A9D0', '9C92E891E9AE534DB685737DE467A9D0', 'testServerScript', '测试服务端脚本')").executeUpdate(); |
1.2.2.3 执行存储过程
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
serverScript:
/* 假设库中已经存在一个名为 test_procedure 的函数:
CREATE OR REPLACE FUNCTION public.test_procedure()
RETURNS void AS
$BODY$
BEGIN
insert into test_procedure_table (id, create_time) values (1, now());
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.test_procedure()
OWNER TO postgres;
即,这个存储过程是向一个名为 test_procudure_table 的表中插入一条新数据
表 test_procudure_table 的定义:
CREATE TABLE public.test_procedure_table
(
id integer NOT NULL,
create_time timestamp without time zone
)
*/
// 执行存储过程
this.em.createNativeQuery("select cast(test_procedure() as text)").getResultList();
|
1.2.2.4 发送HTTP请求(restfulAPI调用)
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
/*1-Get请求,获取Json响应*/
this.logger.info("Get请求,获取Json响应");
var get_response = this.restTemplate.getForEntity("http://127.0.0.1:6060/test/get-admin-token"
, java.util.Map.class); // 如果返回结果是json,response建议反序列化为Map,从而可以用.直接访问属性
var get_response_body = get_response.getBody();
this.logger.info("body: "+ get_response_body);
// 访问Json中的属性
this.logger.info("body.message: " + get_response_body.message);
/*2-Get请求,获取String响应*/
this.logger.info("Get请求,获取String响应");
get_response = this.restTemplate.getForEntity("http://www.baidu.com"
, java.lang.String.class); // 如果返回结果不是json,response建议反序列化为String
get_response_body = get_response.getBody();
this.logger.info("body: "+ get_response_body);
/*3-Post请求,传递request body,获取json响应*/
var Map = Java.type('java.util.Map');
this.logger.info("Post请求,传递request body,获取json响应");
var request_body = {"name" : "hahahaname"};
var post_response = this.restTemplate.postForEntity("http://127.0.0.1:6060/dwf/v1/testPost", request_body, Map.class);
var post_response_body = post_response.getBody();
this.logger.info("body: "+ post_response_body);
/*4-Post请求,传递request body和http header,获取json响应*/
this.logger.info("Post请求,传递request body和http header,获取json响应");
// 引入Java中的相关类型
var HttpHeaders = Java.type("org.springframework.http.HttpHeaders");
var HttpEntity = Java.type('org.springframework.http.HttpEntity');
headers = new HttpHeaders();
headers.set("Authorization", "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTU2ODAzNTcxOX0.5dfoAvd1SFQ7V_CnmzKMNbB7qR_k9Y1BK5zJXUuzc_BkhMFu9oEAVT3EUky1qhBlpihyPd7hV6136I1dnMX-GA");
request_body = {
"appName": "test_json_engine",
"extConfig": "string",
};
request = new HttpEntity(request_body,headers);
var Map = Java.type('java.util.Map');
post_response = this.restTemplate.postForEntity("http://127.0.0.1:6060/dwf/v1/apps-create", request, Map.class);
post_response_body = post_response.getBody();
this.logger.info("body: "+ post_response_body);
|
1.2.2.5 更新实体类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
var newobj = this.omf.edit({
"creator": "9C92E891E9AE534DB685737DE467A9D0",
"createTime": 1574322941000,
"lastModifyTime": 1574322941000,
"lastModifier": "9C92E891E9AE534DB685737DE467A9D0",
"yzqplainref": "new_obj_3",
"oid": "D883978E62398F4FB35F30A669B0E113",
"id": "YZ20191121155541204",
"currentProcess": "test_script1"
}, "yzqright"); |
1.2.2.6 创建实体类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
var newobj = this.omf.create({
"creator": "9C92E891E9AE534DB685737DE467A9D0",
"createTime": 1574322941000,
"lastModifyTime": 1574322941000,
"lastModifier": "9C92E891E9AE534DB685737DE467A9D0",
"yzqplainref": "new_obj_3",
"oid": "D883978E62398F4FB35F30A669B0E113",
"id": "YZ20191121155541204",
"currentProcess": "test_script_create"
}, "yzqright");
// 返回值是最终的存储到数据库的对象 |
1.2.2.7 删除实体类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
this.omf.delete({oid: "5b68802859fc8da24c8da28be1640444c"}, "car"); |
1.2.2.8 更新关联类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
serverScript:
var newobj = this.omf.edit(
{
"creator": "9C92E891E9AE534DB685737DE467A9D0",
"rightClass": "yzqright",
"rightOid": "D883978E62398F4FB35F30A669B0E113",
"oid": "988310EF59582C4E9DD11816DD0687CD",
"version": 999,
"leftOid": "2A47A5892C3C5746B0C063C72617E90F",
"createTime": "1574322941000",
"leftClass": "yzqleft",
"multiFile": "[{\"name\":\"canlendar.png\",\"size\":\"4.863KB\",\"file_id\":\"ff8081816e8cc9d6016e8cf5a7cb0047\"}]"
}, "yzqrelation" ); |
1.2.2.9 创建关联类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
var newRelation = this.omf.create(
{
"creator": "9C92E891E9AE534DB685737DE467A9D0",
"rightClass": "yzqright",
"rightOid": "D883978E62398F4FB35F30A669B0E113",
"version": 1024,
"leftOid": "2A47A5892C3C5746B0C063C72617E90F",
"createTime": "1574322941000",
"leftClass": "yzqleft",
"multiFile": "[{\"name\":\"canlendar.png\",\"size\":\"4.863KB\",\"file_id\":\"ff8081816e8cc9d6016e8cf5a7cb0047\"}]"
}, "yzqrelation"); |
1.2.2.10 删除关联类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
this.omf.delete({oid: "5b68802859fc8da24c8da28be1640444c"}, "carrel"); |
1.2.2.10 查询实体类和关联类对象
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
// 使用查询条件进行查询
var objs = this.omf.handleQueryData("and obj.version > 100 order by obj.version limit 5", "yzqrelation");
this.logger.info(JSON.stringify(objs));
// 使用oid进行查询
var obj = this.omf.getByOid("021C686BD26F594F9CA8AE56489BBEE7", "yzqrelation");
console.log(obj); |
1.2.2.11 发出POST请求百度AI,识别车型
使用百度人工智能开放平台,对实体类对象附加的图片进行分析,更新车型颜色信息。
...
代码块 |
---|
// 识别车辆信息
// 详细说明见:https://ai.baidu.com/ai-doc/VEHICLE/tk3hb3eiv
var r = carAi(this.obj.oid, 'Asset', 'assetImg');
// 根据情况更新对象,例如:
this.obj.assetDesc = r.result[0].name //识别出车型信息
this.omf.edit(this.obj, this.className);
// 也可以绘制图像
drawResult(this.obj.oid, 'Asset', 'assetImg');
// 返回识别结果
this.res = r.result[0].name + r.color_result
//在指定属性上绘制图像
function drawResult(oid, targetClass, targetAttr, r){
var Color = Java.type('java.awt.Color');
var Font = Java.type('java.awt.Font');
var Graphics = Java.type('java.awt.Graphics');
var BasicStroke = Java.type('java.awt.BasicStroke');
var BufferedImage = Java.type('java.awt.image.BufferedImage');
var File = Java.type('java.io.File');
var ImageIO = Java.type('javax.imageio.ImageIO');
//绘制图像
img = null; f = null;
path = this.omf.getFilePath(this.obj.oid, 'Asset', 'assetImg');
try {
f = new File(path);
img = ImageIO.read(f);
} catch(e) {
this.logger.error(e.toString());
}
temp = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
x = Math.round(r.location_result.left);
y = Math.round(r.location_result.top);
h = Math.round(r.location_result.width);
w = Math.round(r.location_result.height);
g = temp.getGraphics();
g.drawImage(img, 0, 0, null);
g.setFont(new Font("Arial", Font.PLAIN, 80));
g.setColor(new Color(255, 0, 0, 255));
g.setStroke(new BasicStroke(3.0));
g.drawRect(x, y, h, w);
g.dispose();
f = new File(path);
try {
ImageIO.write(temp, "png", f);
} catch (e) {
this.logger.error(e.toString());
}
}
function carAi(oid, targetClass, targetAttr){
// 引入SpringBoot中的一些关键类
var HttpHeaders = Java.type('org.springframework.http.HttpHeaders');
var HttpEntity = Java.type('org.springframework.http.HttpEntity');
var MediaType = Java.type('org.springframework.http.MediaType');
var StringHttpMessageConverter = Java.type('org.springframework.http.converter.StringHttpMessageConverter');
var StandardCharsets = Java.type('java.nio.charset.StandardCharsets');
var LinkedMultiValueMap = Java.type('org.springframework.util.LinkedMultiValueMap');
var JString = Java.type('java.lang.String');
// 将当前实体类中文件对象转变成Base64String,DWF内置调用
var imgStr = this.omf.getString(oid, targetClass, targetAttr);
//替换成UTF-8编码
this.restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
//必须设置请求头
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//设置请求体
var request_body= new LinkedMultiValueMap();
request_body.add("image", imgStr);
request = new HttpEntity(request_body,headers);
// access_token需要从百度人工智能平台申请
var baiduai = "https://aip.baidubce.com/rest/2.0/image-classify/v1/car?access_token=[自己申请的]";
post_response = this.restTemplate.postForEntity(baiduai, request, JString.class);
var body = post_response.getBody();
this.logger.info(body);
//处理返回结果
return JSON.parse(body);
} |
1.2.3 工作流相关脚本
在流程模版编辑界面,可以绑定工作流的相关脚本,包括:开始节点的起始脚本(发起工作流实例后调用)、人工节点的前处理脚本(人工任务被激活后调用)和后处理脚本(提交人工任务时调用)、结束节点的结束脚本(流程被终止或完成时调用)。
...
eg:this.wfEngine.saveAccessibleDataVariable(taskId, userId, list) 修改当前流程实例的流程变量值
1.2.3.1 (任务前处理脚本) 根据流程发起人修改当前人工节点所绑定的表单
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
var launchUser = this.wfProcess.getLaunchUser(); //获得流程发起人的DisplayName
this.logger.info(launchUser);
if(launchUser == "零件报销员1"){
this.wfTask.setFormName("applicationForm1");//设置为零件报销申请表1
}else if(launchUser == "零件报销员2"){
this.wfTask.setFormName("applicationForm2");//设置为零件报销申请表2
}
this.logger.info(this.wfTask.getFormName); |
1.2.3.2 (任务前处理脚本) 根据上一个任务设置当前任务的办理人
代码块 |
---|
language | js |
---|
linenumbers | true |
---|
|
var lastTaskId = this.wfTask.getLastTaskId(); //获得上一步任务的Id
this.logger.info("lastTaskId:"+lastTaskId);
var lastManualTaskInstance = this.wfEngine.getManualTaskInstanceById(lastTaskId); //获取上一步任务实例
var lastSubmitter = lastManualTaskInstance.submitter;
this.logger.info("lastSubmitter:"+lastSubmitter);
if(lastSubmitter == "零件报销员1"){
this.wfTask.setSubmitter("领导1");//设置为零件报销员1的领导
this.wfTask.setSubmitterId("00000000000000000000000000000Hgn");//设置为零件报销员1的领导的oid
}else if(launchUser == "零件报销员2"){
this.wfTask.setFormName("领导2");//设置为零件报销员2的领导
this.wfTask.setSubmitterId("00000000000000000000000000000Hgn");//设置为零件报销员2的领导的oid
}
this.logger.info("this.wfTask.getFormName:"+this.wfTask.getFormName); |
1.2.3.3(任务后处理脚本)任务完成之后将对象的属性更改为任务的名称
代码块 |
---|
//this.obj代表流程中正在处理的对象
this.obj.woDesc = this.wfTask.name;
//将需要更新数据库的对象转化为数组
var objs = [this.obj];
//this.wfProcess.targetClassName代表流程中的对象类名称
var newObjs = this.entityUpdateService.updateEntityObjs(this.wfProcess.targetClassName, objs); |
1.3 应用场景脚本示例
1.3.1 应用场景介绍
通过DWF的(数据、UI表单与功能等)建模功能,快速实现设备与工单管理的业务应用:
1.设备的增删改查。
2.设备维修工单的管理。
...
5.历史工单查询:针对“已完成“状态的工作进行查询与浏览。
注:该界面可基于DWF模拟一下稍复杂页面的定义:表格 + 查询条件 + 表单 + 脚本(通过脚本实现查询条件、表格与表单的事件解释与联动)
1.3.2 界面操作脚本-新增
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
let obj = {
woId:'',
name:'',
eqOid:'',
eqName:'',
woDescription:'',
dowDescription:'',
toolDescription:'',
planStartDate:null,
planEndDate:null,
planDuration:1.0,
startDate:null,
endDate:null,
actualDurationNew:1.0,
woState:'创建中',
executorOid:'',
executorId:'',
executorName:'',
excuteLog:''
}
return {
obj: obj,
data:{/*其它参数,可为空*/}
}; |
1.3.3 界面操作脚本-提交
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
debugger;
var selectedWOObjs = this.selectedObjs;
if(selectedWOObjs.length < 1){
this.msgbox.info("请选择工单后再提交!");
}else if(selectedWOObjs.length > 1){
this.msgbox.info("不能一次提交多个工单,请选择一个工单后再提交!");
}else{
//修改工单属性
var editOBJ = selectedWOObjs[0];
editOBJ.woState = '待派工';
//对象修改保存
this.edit(editOBJ, 'WorkOrder');
this.msgbox.success("当前所选工单已完成提交,请处理后续的派工操作!");
} |
1.3.4 界面操作脚本-刷新
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
//获取表格,表格的ID目前可通过APP前端获取(在modeler中也可获取)
var allRowDatas = this.selectedObjs;
let query = ` and obj.woState = '创建中' `; //查询条件
//开始后台数据的查询
this.handleQueryData({query:query,targetClass:"WorkOrder",fresh:true}).then(res=>{
grid.freshData(query); //数据查询
this.msgbox.success("表格已刷新!");
}); |
1.3.5 功能界面: 工单派工
注:执行角色约定“服务经理”。
1.3.6 界面操作脚本-提交
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
debugger;
var selectedWOObjs = this.selectedObjs;
if(selectedWOObjs.length < 1){
this.msgbox.info("请选择工单后再提交!");
}else if(selectedWOObjs.length > 1){
this.msgbox.info("不能一次提交多个工单,请选择一个工单后再提交!");
}else{
//修改工单属性
var editOBJ = selectedWOObjs[0];
//弹窗确认提示
isConfirm = window.confirm("请确认该工单完成派工的提交操作?");
if(!isConfirm){
return;
}
if(editOBJ.woState == '待派工' && editOBJ.executorOid && editOBJ.executorOid != ''){
}else{
alert('当前工单不是[待派工]状态,或者没有选择工单执行人,不能执行提交操作!');
}
editOBJ.woState = '已派工';
//对象属性保存
this.edit(editOBJ, 'WorkOrder');
this.msgbox.success("已完成派工提交!");
} |
1.3.7 功能界面: 工单作业
注:执行角色约定“服务工程师”。
1.3.8 开始作业-操作脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
debugger;
var selectedWOObjs = this.selectedObjs;
if(selectedWOObjs.length < 1){
this.msgbox.info("请选择工单后再开始作业!");
}else if(selectedWOObjs.length > 1){
this.msgbox.info("不能一次提交多个工单,请选择一个工单后再开始作业!");
}else{
//修改工单属性
isConfirm = window.confirm("确认自己开始该工单的作业处理?");
if(!isConfirm){
return;
}
var editOBJ = selectedWOObjs[0];
//开始工单作业的逻辑判断
if(editOBJ.woState == '已派工' && editOBJ.executorOid && editOBJ.executorOid != ''){
}else{
alert('当前工单不是[已派工]状态,或者没有选择工单执行人,不能开始作业操作!');
}
editOBJ.woState = '作业中'; //修改工单状态
//editOBJ.startDate = $env.nowDate(); //类似变量
this.edit(editOBJ, 'WorkOrder'); //修改保存
//执行表单刷新
this.msgbox.success("当前所选工单已开始作业,请处理后续的工单现场作业与完成作业操作!");
} |
1.3.9 完成工单-操作脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
debugger;
var curWO = this.obj; //获取当前列表所选的对象(简介的写法)
if(!curWO){
return null;
}
curWO.woState = '已完成'; //在完成工单弹窗前默认状态赋值
return{
obj:curWO
} |
1.3.10 功能界面: 历史工单查询
注:执行角色约定“所有人员”。
1.3.11 查询操作脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
debugger;
//获取并拼接查询条件
//工单编号
var querySQL = ` and plt_woState='已完成' ` ;
var txt_GDBH = this.GetAddinById("ce1e78c5-5dfd-449c-97fc-1d761215f998");
try {
txt_GDBH = txt_GDBH.getValue().replace(/^\s+|\s+$/g, "");
} catch (error) {
txt_GDBH = '';
}
if(txt_GDBH != ''){
querySQL += ` and plt_woId LIKE '%${txt_GDBH}%'`;
}
//工单名称
var txt_GDMC = this.GetAddinById("439b8e11-d35c-427f-a45d-63d7fa5b293a");
try {
txt_GDMC = txt_GDMC.getValue().replace(/^\s+|\s+$/g, "");
} catch (error) {
txt_GDMC = '';
}
if(txt_GDMC != ''){
querySQL += ` and plt_name LIKE '%${txt_GDMC}%'`;
}
//设备编号
var txt_SBBH = this.GetAddinById("5ef0826b-d1a0-4bca-a645-f2d918e395de");
try {
txt_SBBH = txt_SBBH.getValue().replace(/^\s+|\s+$/g, "");
} catch (error) {
txt_SBBH = '';
}
if(txt_SBBH != ''){
querySQL += ` and plt_eqId LIKE '%${txt_SBBH}%'`;
}
//设备名称
var txt_SBMC = this.GetAddinById("7b74e053-7ee9-432f-bac5-87e842325f91");
try {
txt_SBMC = txt_SBMC.getValue().replace(/^\s+|\s+$/g, "");
} catch (error) {
txt_SBMC = '';
}
if(txt_SBMC != ''){
querySQL += ` and plt_eqName LIKE '%${txt_SBMC}%'`;
}
var query = querySQL + ` order by plt_woId `; //增加排序
var grid = this.GetAddinById('be59e6a9-0b85-4279-85fc-ce1b76f06d7e'); //获取表格
//后台数据刷新查询
this.handleQueryData({ "query": query, "targetClass": "WorkOrder", fresh: true }).then(res => {
//表格数据刷新
grid.freshData(query);
this.msgbox.success("历史工单列表已刷新!");
}); |
1.3.12 重置(查询)操作脚本
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
debugger;
var grid = this.GetAddinById("be59e6a9-0b85-4279-85fc-ce1b76f06d7e");
//工单编号
var txt_GDBH = this.GetAddinById("ce1e78c5-5dfd-449c-97fc-1d761215f998");
try {
txt_GDBH.setValue('');
} catch (error) {
}
//工单名称
var txt_GDMC = this.GetAddinById("439b8e11-d35c-427f-a45d-63d7fa5b293a");
try {
txt_GDMC.setValue('');
} catch (error) {
}
//设备编号
var txt_SBBH = this.GetAddinById("5ef0826b-d1a0-4bca-a645-f2d918e395de");
try {
txt_SBBH.setValue('');
} catch (error) {
}
//设备名称
var txt_SBMC = this.GetAddinById("7b74e053-7ee9-432f-bac5-87e842325f91");
try {
txt_SBMC.setValue('');
} catch (error) {
}
//清空还原默认的查询条件
var query = ` and 1=1 and plt_woState='已完成' order by plt_woId `;
//后台数据查询
this.handleQueryData({ "query": query, "targetClass": "WorkOrder", fresh: true }).then(res => {
//表格数据刷新
grid.freshData(query);
this.msgbox.success("历史工单列表已刷新!");
}); |
1.3.13 表格行切换选择后刷新子属性卡表单
代码块 |
---|
language | js |
---|
firstline | 1 |
---|
linenumbers | true |
---|
|
clientScript:
//开始脚本编写
debugger;
//获取内嵌的子表单容器控件
var detailForm = this.GetAddinById("4a609028-59f4-404c-8da2-8d12be161949"); //内嵌表单
var selectedWOObjs = this.selectedObjs;
if(!selectedWOObjs || selectedWOObjs.length != 1){
detailForm.$el.style.display = 'block'; //block
alert('不能获取到所选中的行数据!');
return;
}
//当前表格所选行对象
var curObj = selectedWOObjs[0];
//还原内嵌子表单的样式:即恢复显示
detailForm.$el.style.display = 'initial'; //block
//刷新子表单的数据显示
detailForm.updateShow('WorkOrder', 'woForm', {
obj: curObj,
//query: "obj.tyWorkItemOid = '$(rowData.oid)'", /*查询条件方式获取子表单关联的业务对象*/
//data: {}, /*补充参数*/
show: true /*子表单可界面渲染显示,否则false不显示表单界面元素*/
//initScript: "", /*通过初始化脚本方式获取子表单关联的业务对象*/
//condition: "", /*通过查询条件方式获取子表单关联的业务对象,这种方式可使用到$obj 形式变量*/
}); |
...