前言
此系列博客是进行金蝶云苍穹开发时的插件开发的教程,一是在明年要是还要参加软件杯金蝶A6赛题的话,可以看此系列教程的博客来进行复习,同时如果要是我实验室的学弟学妹要参加的话,我这个系列的博客可以给他们提供学习参考,因为插件开发学习的路上很艰难,我学习的时候,能参照的讲解少,要花费大量工夫去猜测去调试才能学会那些语法。在插件开发上,希望我这个系列的博客能帮助到别人。
这个系列的博客只专门讲解插件开发,基本的那些金蝶云苍穹的知识点在这里不多作讲解。
对于插件的 事件 ,金蝶官方文档中更为详细,我这只对一些常见的插件做业务处理的代码作一些笔记。
加载指定基础资料/单据的数据
在插件中,我们想要获得想要的基础资料/单据的信息,是通过load操作。
load操作常见的有两种:
BusinessDataServiceHelper.load() BusinessDataServiceHelper.loadSingle()
二者的区别是,load是加载指定基础资料/单据的一些数据,loadSingle是加载一个数据。前者的返回值类型是DynamicObject[],后者的返回值类型为DynamicObject。基础资料和单据的实体在插件中都是放在DynamicObject类型的对象中。
QFilter过滤器
我也不清楚它的官方叫法,我喜欢叫它过滤器(不是web里面那个Filter)。在load操作时,要确保加载的是一些数据还是一个数据,就是对基础资料/单据中的数据进行过滤操作。在最常用的QFilter的构造器中,有三个参数:
第一个是要过滤的属性,第二个是属性过滤要的操作,第三个是如果操作涉及到另一个值,这个值就放到第三个参数里面。
第二个参数通常使用枚举类QCP类的枚举对象的方式,也可以使用操作对应的字符串。
例:
String name = "xxx";
QFilter qfilter = new QFilter("name", QCP.equals, name);
QFilter qfilter = new QFilter("name", QCP.is_notnull, null);
加载数据
接下来就可以讲解如何加载自己想要的基础资料/单据的数据了。
load和loadSingle方法有三个参数,第一个是基础资料/单据的标识,第二个是指定要加载那些字段,第三个是一个QFilter类型的数组,数组里面是一个个的QFilter过滤器。
第二个参数是一个字符串,里面写着一个一个的字段的标识名,每个标识名之间由逗号隔开,例:
"field1,field2,field3,field4"
具体的加载数据的代码案例:
DynamicObject[] dynamicObjectArray = BusinessDataServiceHelper.load("abq2_schedule_form", //日程安排的基础资料的实体名"name," + //任务名"abq2_done_time," + //执行时间///单据体部分"abq2_task_context," + //任务内容"abq2_expect_minute," + //预期时间"abq2_diff," + //任务难度"abq2_true_minute," + //真实花费时间"abq2_finish," + //完成情况"abq2_task_entryentity" // 加载单据体,new QFilter[]{new QFilter("name", QCP.is_notnull, null)});
DynamicObject thisCourse = BusinessDataServiceHelper.loadSingle("abq2_my_course","abq2_my_course_stu," + //课程内码"name," + //课程名称"abq2_textfield3," + //星期"abq2_textfield1," + //教室"abq2_textfield," + //教师"abq2_textfield4," + //年级"creator," + //学生"abq2_textfield2", //课节new QFilter[]{new QFilter("id", QCP.equals, primaryKeyValue)});
获取指定的基础资料/单据实体的字段值
一级字段
获取到对应的实体的DynamicObject类型的对象后,只要是以上load中第二个参数中加载过的字段,都可以获取到其对应的字段值。
若其对象的变量名为dynamicObject
文本类型的字段:dynamicObject.getString("字段标识")
整型类型的字段:dynamicObject.getInt("字段标识")
其他类型的比如getDate、getLong也是以此类推
要额外说的是getDynamicObject,这个是用来获取基础资料字段的字段值,返回值是DynamicObject,就是获取到了这个字段对应的实体了,是默认所有的一级字段都获取到了,可以直接get它的所有一级字段。
单据体的字段
如果不是一级字段,又该如何获取呢?这里以单据体的里面的二级字段为例。
要想获取一个基础资料/单据里面的单据体的信息,首先要先加载出其基础资料/单据的实体的信息,再获取其实体的单据体的信息,类似于先进大门才能进卧室的意思,还有,在load中的第二个参数中,不管要写好单据体的标识,也要写好单据体中的要加载的二级字段的标识,如上面的第一个例子
DynamicObject[] dynamicObjectArray = BusinessDataServiceHelper.load("abq2_schedule_form", //日程安排的基础资料的实体名"name," + //任务名"abq2_done_time," + //执行时间//以下下是单据体部分"abq2_task_entryentity," // 加载单据体//以下是单据体的二级字段的标识,即单据体的“列”的标识"abq2_task_context," + //任务内容"abq2_expect_minute," + //预期时间"abq2_diff," + //任务难度"abq2_true_minute," + //真实花费时间"abq2_finish" + //完成情况,new QFilter[]{new QFilter("name", QCP.is_notnull, null)});
在get单据体中的二级字段的时候,也要讲究步骤。 要先getDynamicObjectCollection("单据体标识"),获取单据体中的分录(就是单据体的行)的数据的集合,集合中的一个元素就是一个分录(就是一行),再对应去get获取其行的字段的数据即可,例:
//获取DynamicObject列表,即获取学生的单据头的信息DynamicObject[] dys = BusinessDataServiceHelper.load("abq2_int","abq2_billnofield," +"abq2_textfield5," + //学校"abq2_textfield2," + //学生的班级"stu_name," + //学生姓名"abq2_textfield3," + //学生学号"abq2_decimalfield1111," + //学生成绩总分"abq2_textfield8," + //考试名称//把单据体和单据体里的字段加进load里面"abq2_entryentity," + //科目成绩的单据体"abq2_textfield," + //考试科目"abq2_decimalfield111," + //科目对应的成绩"abq2_daterangefield_startdate", //考试日期(new QFilter("stu_name", QCP.is_notnull, null)).toArray());//创建一个JsonArrayJSONArray jsonArray = new JSONArray();for (DynamicObject dynamicObject : dys) {//将学生的考试基本的信息加入JSONArrayJSONObject jsonObject = new JSONObject();jsonObject.put("stu_name", dynamicObject.getString("stu_name"));jsonObject.put("school_name", dynamicObject.getString("abq2_textfield5"));jsonObject.put("stu_id", dynamicObject.getString("abq2_textfield3"));jsonObject.put("class_name", dynamicObject.getString("abq2_textfield2"));jsonObject.put("exam_time", new SimpleDateFormat("yyyy-MM-dd").format(dynamicObject.getDate("abq2_daterangefield_startdate")));jsonObject.put("exam_name", dynamicObject.getString("abq2_textfield8"));jsonObject.put("exam_all_score", dynamicObject.getBigDecimal("abq2_decimalfield1111"));jsonArray.add(jsonObject);//获取学生的成绩信息中的单据体信息,获取学生的各门科目的成绩信息//先把单据体的collection创建出来,再获取这个单据体的collection的字段(按照字段名),如下DynamicObjectCollection dynamicObjectCollection = dynamicObject.getDynamicObjectCollection("abq2_entryentity");for (DynamicObject dynamicObject2 : dynamicObjectCollection) { //遍历分录数据//将各科目的的信息加入JSONArrayJSONObject jsonObject2 = new JSONObject();jsonObject2.put("subject", dynamicObject2.getString("abq2_textfield")); //考试科目jsonObject2.put("sub_score", dynamicObject2.getBigDecimal("abq2_decimalfield111")); //考试成绩jsonArray.add(jsonObject2);}}}
案例
以一个GPT的自定义操作为例,展示数据的加载和获取:
public class ScoreSumAnalysis implements IGPTAction {@Overridepublic Map<String, String> invokeAction(String action, Map<String, String> params) {Map<String , String> result = new HashMap<>();if ("GET_ALL_Score".equalsIgnoreCase(action)) {//获取DynamicObject列表,即获取学生的单据头的信息DynamicObject[] dys = BusinessDataServiceHelper.load("abq2_int","abq2_billnofield," +"abq2_textfield5," + //学校"abq2_textfield2," + //学生的班级"stu_name," + //学生姓名"abq2_textfield3," + //学生学号"abq2_decimalfield1111," + //学生成绩总分"abq2_textfield8," + //考试名称"abq2_entryentity," + //科目成绩的单据体"abq2_textfield," + //考试科目"abq2_decimalfield111," + //科目对应的成绩"abq2_daterangefield_startdate", //考试日期(new QFilter("stu_name", QCP.is_notnull, null)).toArray());//创建一个JsonArrayJSONArray jsonArray = new JSONArray();for (DynamicObject dynamicObject : dys) {//将学生的考试基本的信息加入JSONArrayJSONObject jsonObject = new JSONObject();jsonObject.put("stu_name", dynamicObject.getString("stu_name"));jsonObject.put("school_name", dynamicObject.getString("abq2_textfield5"));jsonObject.put("stu_id", dynamicObject.getString("abq2_textfield3"));jsonObject.put("class_name", dynamicObject.getString("abq2_textfield2"));jsonObject.put("exam_time", new SimpleDateFormat("yyyy-MM-dd").format(dynamicObject.getDate("abq2_daterangefield_startdate")));jsonObject.put("exam_name", dynamicObject.getString("abq2_textfield8"));jsonObject.put("exam_all_score", dynamicObject.getBigDecimal("abq2_decimalfield1111"));jsonArray.add(jsonObject);//获取学生的成绩信息中的单据体信息,即获取学生的各门科目的成绩信息DynamicObjectCollection dynamicObjectCollection = dynamicObject.getDynamicObjectCollection("abq2_entryentity");for (DynamicObject dynamicObject2 : dynamicObjectCollection) {//将各科目的的信息加入JSONArrayJSONObject jsonObject2 = new JSONObject();jsonObject2.put("subject", dynamicObject2.getString("abq2_textfield")); //考试科目jsonObject2.put("sub_score", dynamicObject2.getBigDecimal("abq2_decimalfield111")); //考试成绩jsonArray.add(jsonObject2);}}System.out.println(jsonArray.toJSONString());//加入resultDynamicObject参数,将JsonArray加入到这个参数当中,然后返回result.put("resultDynamicObject", jsonArray.toJSONString());}return result;}
}
加载数据的插件到此讲解结束,有疑问可以在评论区提出。