本文是讲解如何用jxTMS来开发jxTMS示例之故障排查的系列文章中的一篇。整个系列的文章请查看:如何用jxTMS开发一个功能
由于大部分内容前面都已经讲过了,所以主要讲前面没讲过的内容。
1、入口
提取为知识情的入口和之前讲解过的入口有两点不同:
该界面是显示到一个对话框中的
该入口有一个显示条件
显示到对话框中是非常简单的:
json.set('dispInDialog',True)
对话框和主界面的不同点的有三:
每个主界面都是一个新的capa,而对话框和主界面是同一个capa
宽度是600像素
对话框没有工具条,即对话框不能再打开对话框进行套娃
入口的显示条件主要用来控制用户在当前能否操作该入口。role是控制有哪些用户有权限访问本入口,而显示条件是在有权操作时,还要满足什么样的业务条件才可以访问。
如何设置显示条件,请参考jxTMS在线编程手册中的入口显示规则。
提取为知识的入口定义是:
@biz.Demand('disp','addKNFromCase')
@biz.OPDescr
def op(json):
json.setA().text('提取为知识'.decode('utf-8'))
json.set('dispInDialog',True)
json.dispCondition('field.State==已修复 且 field.Tag!=已提取'.decode('utf-8'))
其显示条件是:故障已经修复且标记字段不能是已提取。
然后将提取为知识链接给故障的查看详情界面:
@biz.OPDescr
def oplink(json):
#将【提取为知识】链接给【查看故障详情】
json.setBtnList('disp.dispCase', 'disp.addKNFromCase')
这样在查看故障详情的时候,如果条件满足【故障已经修复且标记字段不能是已提取】,用户就会看到提取为知识,这里考虑到示例的便利没有设置权限,所有任何用户都能执行提取为知识,如果要限制只有特定用户才能执行,只要再用role为提取为知识指定一个执行角色即可,如:技术经理。
2、web界面设计
提取为知识的界面定义如下:
web addKNFromCase type div okBtn='addKNFromCaseBtn';
web addKNFromCaset1 parent addKNFromCase type table title='知识详情',width=600,alone=true;
with addKNFromCaset1 row 0 col c0 web n type text text="名称:",width=100;
with addKNFromCaset1 row 0 col c1 web n bind knName type input width=500,placeholder="请输入名称中应有的关键字...";
with addKNFromCaset1 row 1 col c0 web n type text text="属性:",width=100;
with addKNFromCaset1 row 1 col c1 web n bind knAttr type tag width=500;
with addKNFromCaset1 row 2 col c0 web n type text text="说明:",width=100;
with addKNFromCaset1 row 2 col c1 web n bind knDescr type textarea width=500;
with addKNFromCaset1 row 3 col c0 web n type text text="内容:",width=100;
with addKNFromCaset1 row 3 col c1 web n bind knContent type codeEditor width=500,height=600;
web addKNFromCaseBtn parent addKNFromCase type a width=80,text='添加',
motion=cmd,demand=addKNFromCase,hide=true;
提取为知识是一个对话框,而对话框自身有两个按钮:确定、取消。而一般的操作界面也都会有确定按钮,这就会出现一个歧义:用户点哪个按钮呢?!
所以对话框界面有一个独特的属性:okBtn。jxTMS会用该属性所指定的a控件来取代对话框的确定按钮,同时在定义这个a控件时,为避免出现两个确定按钮,还应将a控件定位为不可见:hide=true。
3、数据
知识管理属于jxTMS内部的管理,所以相应的数据应遵从知识管理的要求。我们在下面讲解业务逻辑时一起进行讲解。
4、业务逻辑
提取为知识的业务逻辑包括三部分:
a:根据知识管理的要求创建知识并写入相关数据
kt = '文本说明'.decode('utf-8')
kn = self.getInputString('knName')
#知识的流水号,这里是直接用自己的模板
kc = self.getSerialNumber(db,'knowledge','ST-{MM}{DD}-{SND3}/{YYYY}')
k = knowledge.create(db,kt,kn)
#因为知识管理模块有自己的语义转换,所以要用知识管理模块的语义转换来保存自己所给出的知识信息
self.execCapaFunc('knowledge.main','setFieldWithNameTrans',db,k,'knSN',kc)
self.execCapaFunc('knowledge.main','setFieldFromVar',db,k,'knDescr')
#从上下文中获取用户的简称
ko = ctx.getCaller().abbreviation()
self.execCapaFunc('knowledge.main','setFieldWithNameTrans',db,k,'knOwner',ko)
self.execCapaFunc('knowledge.main','setFieldWithNameTrans',db,k,'knState','使用中'.decode('utf-8'))
知识管理目前也只有一种知识类型:文本说明。知识管理用knowledge来保存知识的数据。这里有了一个大家从没见过的函数:execCapaFunc。
execCapaFunc(capaname,funcname,ps):
参数:
capaname:功能点名
funcname:函数名
ps:变参,对象数组
返回值:
funcname名的函数的返回值
说明:
调用其它capa的内部函数,目前只允许调用:setFieldWithNameTrans、setFieldFromVar、dispVarFromField这三个语义转换函数
所以大家只要理解了四个execCapaFunc其实就相当于是按知识管理中的语义要求,来设置知识流水号、描述、管理人和状态就好了。
b:打标记。为便于对知识分类,所以知识都会打标记。而打标记则是常规的处理:
#knAttr的类型是tag,其值是用英文逗号连接的一组标记短语
ts = self.getInputString('knAttr')
if not utils.isNull(ts):
ss = ts.split(',')
for t in ss:
#将所有标记提取后逐一打标记
k.tag(db,t)
#在查看时,如果想知道打了哪些标记,就需要查一次数据库,如果是在列表时想知道知识的标记
#那就每显示一行就需要差一次数据库,所以将知识标记保存到知识中,以减少列表查询时数据库开销
k.Info = jxJson.getObjectNode()
k.Info.set('knAttr',ts)
#数据类的对象保存到数据库时非常简单,就是一个update命令即可
db.update(k,'Info')
c:知识管理对知识的处理是有版本的概念,即知识的实际内容是保存在当前版本中的
#知识是有版本的,实际内容是保存到相应的版本中的
kv = k.newVer(db,ctx.getCaller().id())
kv.Info = jxJson.getObjectNode()
c = self.getInputString('knContent')
kv.Info.set('content',c)
db.update(kv,'Info')
大家如果看过自己下载的capa.py文件,会发现后面还有几行注释:
#调用不同类型的知识【参考jxTMS的跨capa协作的框架法
#(https://zhuanlan.zhihu.com/p/482457242)】,其所注册类型的相应处理
#文本说明型知识,其在addKN时的处理,就是上面的5行代码,所以二选一即可
#self.doOtherCapaDual(db,ctx,k,'knActive',kt,'addKN')
也就是说,我们完全可以不使用上面的那5行代码来保存实际的文本说明型知识内容,而是用doOtherCapaDual来注册到系统中用来对文本说明型知识保存实际内容的函数。即:
self.doOtherCapaDual(db,ctx,k,'knActive',kt,'addKN')
该函数的语义就是调用注册用来管理kt【此时是:文本说明】类型的知识capa,通知其需要对k做knActive+addKN的操作。
具体说明,请翻阅:jxTMS的跨capa协作的框架法。