页面树结构

版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

目录

1 引言

上一章介绍了最简单的操作插件编写方法以后,往往开发者不会只是简单开发一个完全封闭的插件,一般来说,完成一项任务至少需要:

...

因此,需要在插件的代码里调用DWF内部的接口,所以这一章,将接下来深入了解DWF提供给插件开发者的一些基础调用。

2 获得接口的总入口:dwf_ctx

DWF的前端插件配套接口最大限度的集成了本教程 第三部分:脚本开发培训中介绍的接口,也就是说,对于已经掌握脚本开发的程序员,可以不费力气的继续使用他们已经掌握的知识,进行高阶编码工作。

...

代码块
languagejs
<template>
	<div>
		<Alert show-icon>hello world!!!</Alert>
		<Alert type="success" show-icon>{{userName}}</Alert>
	</div>
</template>
 
<script>
export default {
	name: "helloWorldOpr",
		data() {
			return {
				userName: "hello world!!!"
		    }
		},
		created() {
			let ctx = this.dwf_ctx;				// 插件代码里对DWF调用的总入口
			this.userName = `hello ${ctx.user.userName}!!!`;	//获取当前用户名
		}
};
</script>
 
<style>
.ivu-alert{
    margin-left: 10px;
    margin-top: 10px;
}
</style>

上面代码经过装配后得到的效果如下所示:

Image RemovedImage Added

图-显示当前登录用户信息

上述代码中,定义了一个变量userName,并且在data()函数里返回了一个自带userName的JSON对象,该对象会自动传递到created函数。其中,data()和create()函数的作用是标准的vue文件自带的生命周期函数,这里不过多介绍。

重点关注的是created函数的内容,其中包含的this.dwf_ctx这个总入口,其作用和脚本中的this是一样的,因此,通过dwf_ctx可以访问到脚本提供的所有功能,当然,包括user.userName这样的属性。

有关脚本函数和代码之间的一一对应关系,可以参阅 脚本调用和插件调用的对应关系前端脚本和插件开发调用的对应关系详细了解,这里不做过多介绍。

3 操作插件开发的典型案例

下面,结合两个比较有代表性的示例介绍如何在脚本中使用函数调用。

3.1 模块操作开发

针对设备管理系统,将工单列表从DWF数据库里取出来,显示到一个iView的时间线上,点击详情打开工单,如下图所示:

Image RemovedImage Added

图-用时间线显示工单列表

通过restful api获取数据

这个例子中涉及到如何调用DWF数据库中的数据问题,在表单操作中这一目标可以通过调用DWF配套的restful api实现。取得工单对象列表的restful api调用方法如下面的代码所示:

...

Restful API接口的说明文档可以通过在建模工具中点击登录用户,展开API说明查看,如下图所示:

Image RemovedImage Added

图-打开接口文档

将工单查询结果展示到前端

数据加载的方法了解以后,剩下如何展示到前端的工作就取决于开发者对vue的和iView的熟悉程度了,本章一开始的例子里使用了报警(Alert)标签展示数据,在这个例子里我们将采用时间线(Timeline)控件实现希望展示的效果:

...

  1. 标签内定义了一个worklist数组用于进行动态显示,利用iView标签遍历将数组中的每一个对象展示出来。
  2. 在脚本的中的create()方法里,通过调用dwf_aixos获得了工单对象,并且按照要求完成时间(woDeadline)排序。
  3. getdate()函数是为了将DWF中默认返回的时间戳数据类型转换为年月日以方便阅读。
  4. 当详情标签被点击的时候会自动调用openWorkOrder函数,并且将被点击的工单对象作为参数传入表单,并将其显示在界面上。
  5. 在样式<sytle>里增加了边沿设置,整体推进20个像素,以便显示边沿。

显示工单引用的设备和人员信息

在上面的例子中,仅仅显示了工单的内容,但是对于工单针对的设备、工单的负责人工程师的姓名,是没有显示的,接下来看看如何利用DWF提供的Restful API完成引用数据的加载。

...

DWF的restful api会将工单对象作为数组全部返回,同时将所有返回结果中的工单对象引用的设备对象和用户对象作为另外的两个数组返回,如下所示:

Image RemovedImage Added

图-带引用关系返回的结果

这个返回结果携带的信息更加丰富,其携带了3个数组,其中WorkOrder代表查出的工单,User代表工单中牵扯到的负责人,Asset代表工单涉及的所有设备。得到必要的信息以后,只需要在前端对数据进行初始化即可完成显示:

代码块
<template>
	<Timeline>
		<TimelineItem color="green" v-for="t in worklist" :key="t.oid">
			<p>{{`${getdate(t.woDeadline || '未知')}`}}</p>
			<p>
				{{`设备代号为 ${t.assetId} 的 ${t.woTitle} 工作由 ${t.engineerName} 负责完成`}}
				<a
					@click="openWorkOrder(t)"
				>详情</a>
			</p>
		</TimelineItem>
	</Timeline>
</template>

<script>
export default {
	name: "workOrderListOpr",
	data() {
		return {
			worklist: [],
			userlist: [], //新增了用户列表备用
			assetlist: [], //新增了设备列表备用
		};
	},
	created() {
		console.log(this.dwf_ctx);
		let queryConditon = {
			condition: "order by obj.woDeadline",
			refs: [
				{
					sourceAttr: "assetOid",
					targetAttr: "oid",
					targetClass: "Asset",
					sourceAttrSplit: ",",
				},
				{
					sourceAttr: "engineerOid",
					targetAttr: "oid",
					targetClass: "User",
					sourceAttrSplit: ",",
				},
			],
		};
		let that = this; // 临时保存上下文以便异步调用
		this.dwf_ctx.dwf_axios
			.post("/omf/entities/WorkOrder/objects", queryConditon)
			.then((res) => {
				console.log(res);
				if (res.data.success) {
					let resArr = res.data.data;
					that.assetlist = resArr.Asset;
					that.userlist = resArr.User;
					// 重新归置工单信息补充新的属性
					that.worklist = resArr.WorkOrder.map((wo) => {
						let asset = that.assetlist.find((a) => {
							return a.oid === wo.assetOid;
						}); //找到工单提到的设备对象
						let engineer = that.userlist.find((u) => {
							return u.oid === wo.engineerOid;
						}); //找到工单提到的用户对象
						// 如果设备对象不为空则补充设备的代号到工单中
						wo.assetId = 
							typeof asset !== "undefined" ? asset.id : "未知"; 
						// 如果用户对象不为空则补充用户的名称到工单中
						wo.engineerName =
							typeof engineer !== "undefined" ? engineer.displayName : "未知";
						return wo;
					});
				}
			});
	},
	methods: {
		openWorkOrder(wo) {
			// 打开工单对象
			alert(`${wo.woTitle}`);
		},
		getdate(ts) {
			if (ts == "") return "--";
			var now = new Date(ts),
				y = now.getFullYear(),
				m = now.getMonth() + 1,
				d = now.getDate();
			return (
				y +
				"-" +
				(m < 10 ? "0" + m : m) +
				"-" +
				(d < 10 ? "0" + d : d) +
				" " +
				now.toTimeString().substr(0, 8)
			);
		},
	},
};
</script>

<style>
.ivu-timeline {
	margin-left: 20px;
	margin-top: 20px;
}
</style>

上述代码经过装配后显示的结果如下所示:

Image RemovedImage Added

图-引用其他类型数据后显示的工单

注:上述工单的最后一条里面是故意创建的一个未知设备和未知用户的工单,用于检查异常处理是否生效。

弹出表单显示工单详情

最后,如果希望在这个时间线里点击详情用特定的表单打开工单,可以使用openTab方法调用实现,结合上面的例子,只需要修改openWorkOrder方法增加打开页签的调用即可,具体的调用方法如下:

...

在下面章节里,我们还将介绍其他更加简便的方法操作DWF中的概念。

3.2 表单按钮操作开发

在上面的例子里,通过使用模块操作插件实现与DWF互动的方法,包括:

...

接下来,再举一个例子,在设备编辑的界面里增加一个按钮插件,弹框显示一个文本框,然后将文本框数据带回上级表单并且更新被选中的设备对象的描述属性,效果如下图所示:

Image RemovedImage Added

在这个例子里,我们将接管表单绘制过程,绘制一个特殊样式的文字按钮“编码生成工具”,在按钮点击的时候使用iView的弹框示例,来展示对话框本文不对弹框示例进行过多解释,当用户点击确定以后,可以将输入编码返回到设备表单的备注中。

接管绘制逻辑

首先,继续在上一章buttonOpr.vue中继续修改,在单设备编辑表单中,放入一个按钮插件,并且将按钮事件对应的操作设置为动作为implement类型的操作,插件的名字设置为buttonOpr.vue。

...

代码块
<script>
export default {
	...
	methods: {
		// 通知DWF表单引擎接管绘制过程
		canShow() {
			return true;
		},
		// 一旦接管,DWF表单引擎传入当前表单的上下文
		setArgs(args) {
			return this;
		},
		...
	},
};
</script>

绘制标签设置

接下来,编写template标记,将按钮和弹框的基本样式设置出来,标签的样式如下:

...

代码块
languagejs
export default {
	name: "buttonOpr",
	data() {
		return {
			showDlg: false,
			asset: { id: "unknown", assetType: "unknown" },
		};
	},
...

通过函数实现交互

围绕openDialog,ok,cancel的实现如下所示:

...

代码块
languagejs
<template>
	<div>
		<Button type="text" @click="openDialog">编码工具</Button>
		<Modal v-model="showDlg" :title="`${asset.assetType}`" @on-ok="ok" @on-cancel="cancel">
			<Input v-model="asset.id" :placeholder="asset.id" />
		</Modal>
	</div>
</template>
 
<script>
export default {
	name: "buttonOpr",
	data() {
		return {
			showDlg: false,
			asset: { id: "unknown" },
		};
	},
	methods: {
		// 通知DWF表单引擎接管绘制过程
		canShow() {
			return true;
		},
		// 一旦接管,DWF表单引擎传入当前表单的上下文
		setArgs(args) {
			return this;
		},
		openDialog() {
			// 初始化弹框内容
			var a = this.dwf_ctx.obj();
			if (typeof a !== "undefined") {
				this.asset = a;
			}
			// 显示对话框
			this.showDlg = true;
		},
		ok() {
			// 获得备注控件设置内容
			var addin = this.dwf_ctx.getAddinById("TextInput1");
			addin.setValue(this.asset.id);
		},
		cancel() {},
	},
};
</script>

<style>
</style>


4 小结

本章深入介绍了操作插件和按钮插件的开发,要点如下:

...

View file
namebuttonOpr.vuepage第五章,操作插件开发-进阶
spaceDWF
height250
View file
nameworkOrderListOpr.vue
page第五章,操作插件开发-进阶
spaceDWF
height250