需求-动态表单展示单据列表控件,Json与DynamicObject转换,显示在列表控件上原创
金蝶云社区-吴锐雄
吴锐雄
16人赞赏了该文章 6,276次浏览 未经作者许可,禁止转载编辑于2021年10月08日 16:39:54
summary-icon摘要由AI智能服务提供

本文介绍了在云苍穹平台上,如何将JSON数据转换为DynamicObject并在动态表单中以列表形式展示的方法。首先,需要创建单据并标识其字段,然后建立动态表单并拖入单据列表控件。接着,编写Java插件来注册和转换JSON字符串为DynamicObject,包括直接构造和使用序列化工具类两种方式。文中详细说明了单据和动态表单的创建过程,Java插件的编写细节,并给出了JSON数据示例和转换代码。关键点在于确保JSON的key与单据的字段标识一致,以便正确映射和显示数据。

如果文章对您有帮助,请为我点击一个朴实无华的赞^_^


1.需求背景

一些场景中,需要将其他系统的数据加载过来,然后放在云苍穹中显示,这个例子展示了如何将Json数据转为DynamicObject,然后在动态表单中以列表显示。


2.实现方案

(1)创建一个单据,之后需要用到单据标识来创建DynamicObject

(2)新建动态表单,在动态表单拖入一个单据列表控件,之后会用这个控件来显示数据。

(3)编写java插件,注册java插件,在插件中将json字符串转换为DynamicObject。


本篇文章的一些个人理解:

(1)json的JsonArray对应云苍穹的DynamicObjectCollection,因为这两者的数据结构都类似于ArrayList。

json的jsonObject对应云苍穹的DynamicObject,因为这两者的数据结构都类似于HashMap。

所以本篇文章把JsonArray转为DynamicObjectCollection,JsonObject转为DynamicObject

(2)java插件代码请查看附件或者实现过程,在转换时,展示了两种转换方式,一种是直接构造DynamicObjectCollection和DynamicObject;另一种是利用云苍穹内部封装好的序列化工具类DynamicObjectSerializeUtil,传递给DynamicObjectSerializeUtil的json要多一个"_Type_":"单据标识名"。

(3)json字符串是写死的,本篇文章仅探讨如何将json与DynamicObject转换并显示。不展示如何从第三方获取json数据。

(4)代码中会在单据列表控件动态添加列,列的标识必须和第1步的单据中的字段标识一致。

提供转换的JsonObject中的key,必须要和第1步的单据中的字段标识一致


3.实现过程

(1)创建单据,标识为kdec_t_bill_1,如图,这个单据用到的字段有单据编号billno,单据状态billstatus,水果产地kdec_production,单据体kdec_entryentity下面的水果名称kdec_fruits,报量kdec_report,产量kdec_output,重量kdec_weight。之后jsonObject的key都必须和这些标识一致。

image.png

(2)新建动态表单,如图,拖入一个单据列表控件,控件标识为kdec_billlistap

image.png


单据列表控件设置单据实体,接下来的例子不会用到这张单据中的数据,数据是用json字符串组装的,但即便如此,也必须设置单据实体


(3)编写java插件

createListColumns()方法中新增了5个列,其中id是单据的id,kdec_entryentity.id是单据体的id,新增列如果是单据体的字段,那么设置setFieldName、setEntityName与普通的列不一样,要增加一个单据体的标识。

image.pngBillListDataProvider内部类中组装DynamicObjectCollection数据并返回,其中展示了两种方式去转换json。

一种是直接构造DynamicObjectCollection和DynamicObject;一种是序列化工具类DynamicObjectSerializeUtil。


在json中,一定要带有id字段;如果数据准备以单据体的形式展现,一定要带有单据体id字段;json的key必须和单据的字段标识一致。

image.png

json如下,代码中也有这段json

[{"id":"101","billno":"1001","kdec_production":"广东","kdec_entryentity.id":"201","kdec_entryentity.kdec_fruits":"番薯","_Type_":"kdec_t_bill_1"},{"id":"101","billno":"1001","kdec_production":"广东","kdec_entryentity.id":"202","kdec_entryentity.kdec_fruits":"木仔","_Type_":"kdec_t_bill_1"},{"id":"101","billno":"1001","kdec_production":"广东","kdec_entryentity.id":"203","kdec_entryentity.kdec_fruits":"桔","_Type_":"kdec_t_bill_1"},{"id":"102","billno":"1002","kdec_production":"海南","kdec_entryentity.id":"204","kdec_entryentity.kdec_fruits":"桔","_Type_":"kdec_t_bill_1"},{"id":"102","billno":"1002","kdec_production":"海南","kdec_entryentity.id":"205","kdec_entryentity.kdec_fruits":"菠萝","_Type_":"kdec_t_bill_1"},{"id":"103","billno":"1003","kdec_production":"甘肃","kdec_entryentity.id":"206","kdec_entryentity.kdec_fruits":"葡萄","_Type_":"kdec_t_bill_1"},{"id":"104","billno":"1004","kdec_production":"新疆","kdec_entryentity.id":"207","kdec_entryentity.kdec_fruits":"葡萄","_Type_":"kdec_t_bill_1"},{"id":"104","billno":"1004","kdec_production":"新疆","kdec_entryentity.id":"208","kdec_entryentity.kdec_fruits":"哈密瓜","_Type_":"kdec_t_bill_1"}]

代码如下,使用了两种方案转换json:

package kd.demo.cosmic.form;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType;
import kd.bos.dataentity.metadata.dynamicobject.DynamicSimpleProperty;
import kd.bos.form.events.BeforeBindDataEvent;
import kd.bos.form.events.BeforeBindDataListener;
import kd.bos.form.events.BeforeCreateListColumnsArgs;
import kd.bos.form.events.BeforeCreateListDataProviderArgs;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.list.BillList;
import kd.bos.list.IListColumn;
import kd.bos.list.ListColumn;
import kd.bos.list.events.CreateListColumnsListener;
import kd.bos.list.events.CreateListDataProviderListener;
import kd.bos.mvc.list.ListDataProvider;
import kd.bos.servicehelper.util.DynamicObjectSerializeUtil;

import java.util.EventObject;
import java.util.List;

public class JsonToBillListFormPlugIn extends AbstractFormPlugin implements CreateListColumnsListener, BeforeBindDataListener {

    @Override
    public void initialize() {
        super.initialize();
        BillList billList = this.getControl("kdec_billlistap");
        billList.addCreateListColumnsListener(this);
        billList.addBeforeBindDataListener(this);
    }

    @Override
    public void createListColumns(BeforeCreateListColumnsArgs arg0) {
        List<IListColumn> columns = arg0.getListColumns();

        ListColumn colUser1 = this.createListColumn("kdec_production", "水果产地", 0);
        colUser1.setParentViewKey("kdec_listgridviewap");
        columns.add(colUser1);

        ListColumn colUser2 = this.createListColumn("kdec_fruits", "水果名称", 1);
        colUser2.setFieldName("kdec_entryentity.kdec_fruits");
        colUser2.setEntityName("kdec_entryentity");
        colUser2.setParentViewKey("kdec_listgridviewap");
        columns.add(colUser2);

        ListColumn colUser3 = this.createListColumn("billno", "编码", 2);
        colUser3.setParentViewKey("kdec_listgridviewap");
        columns.add(colUser3);


        ListColumn colUser4 = this.createListColumn("id", "id", 3);
        colUser4.setParentViewKey("kdec_listgridviewap");
        columns.add(colUser4);

        ListColumn colUser5 = this.createListColumn("kdec_entryentity.id", "水果id", 4);
        colUser5.setFieldName("kdec_entryentity.id");
        colUser5.setEntityName("kdec_entryentity");
        colUser5.setParentViewKey("kdec_listgridviewap");
        columns.add(colUser5);
    }


    @Override
    public void beforeBindData(BeforeBindDataEvent beforeBindDataEvent) {
        BillList billList = this.getControl("kdec_billlistap");
        billList.addCreateListDataProviderListener(new CreateListDataProviderListener() {
            @Override
            public void createListDataProvider(BeforeCreateListDataProviderArgs args) {
                args.setListDataProvider(new BillListDataProvider());
            }
        });
    }

    // 内部类,为单据列表控件添加值
    public class BillListDataProvider extends ListDataProvider {
        @Override
        public DynamicObjectCollection getData(int start, int limit) {
            // json字符串,由一串JsonArray组成,JsonArray的每个子元素是一个JsonObject
            // 这里仅做json转换DynamicObject的示例,不做http耗时请求json
            // TODO: jons和json2相比,对一个键值对"_Type_":"kdec_t_bill_1"
            String json = "[{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"201\",\"kdec_entryentity.kdec_fruits\":\"番薯\"},{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"202\",\"kdec_entryentity.kdec_fruits\":\"木仔\"},{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"203\",\"kdec_entryentity.kdec_fruits\":\"桔\"},{\"id\":\"102\",\"billno\":\"1002\",\"kdec_production\":\"海南\",\"kdec_entryentity.id\":\"204\",\"kdec_entryentity.kdec_fruits\":\"桔\"},{\"id\":\"102\",\"billno\":\"1002\",\"kdec_production\":\"海南\",\"kdec_entryentity.id\":\"205\",\"kdec_entryentity.kdec_fruits\":\"菠萝\"},{\"id\":\"103\",\"billno\":\"1003\",\"kdec_production\":\"甘肃\",\"kdec_entryentity.id\":\"206\",\"kdec_entryentity.kdec_fruits\":\"葡萄\"},{\"id\":\"104\",\"billno\":\"1004\",\"kdec_production\":\"新疆\",\"kdec_entryentity.id\":\"207\",\"kdec_entryentity.kdec_fruits\":\"葡萄\"},{\"id\":\"104\",\"billno\":\"1004\",\"kdec_production\":\"新疆\",\"kdec_entryentity.id\":\"208\",\"kdec_entryentity.kdec_fruits\":\"哈密瓜\"}]";
            String json2 = "[{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"201\",\"kdec_entryentity.kdec_fruits\":\"番薯\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"202\",\"kdec_entryentity.kdec_fruits\":\"木仔\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"101\",\"billno\":\"1001\",\"kdec_production\":\"广东\",\"kdec_entryentity.id\":\"203\",\"kdec_entryentity.kdec_fruits\":\"桔\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"102\",\"billno\":\"1002\",\"kdec_production\":\"海南\",\"kdec_entryentity.id\":\"204\",\"kdec_entryentity.kdec_fruits\":\"桔\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"102\",\"billno\":\"1002\",\"kdec_production\":\"海南\",\"kdec_entryentity.id\":\"205\",\"kdec_entryentity.kdec_fruits\":\"菠萝\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"103\",\"billno\":\"1003\",\"kdec_production\":\"甘肃\",\"kdec_entryentity.id\":\"206\",\"kdec_entryentity.kdec_fruits\":\"葡萄\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"104\",\"billno\":\"1004\",\"kdec_production\":\"新疆\",\"kdec_entryentity.id\":\"207\",\"kdec_entryentity.kdec_fruits\":\"葡萄\",\"_Type_\":\"kdec_t_bill_1\"},{\"id\":\"104\",\"billno\":\"1004\",\"kdec_production\":\"新疆\",\"kdec_entryentity.id\":\"208\",\"kdec_entryentity.kdec_fruits\":\"哈密瓜\",\"_Type_\":\"kdec_t_bill_1\"}]";

            // DynamicObject的属性字段,同时也是json的key,这在之后构造DynamicSimpleProperty需要用到
            String[] propertys = {"id", "billno", "kdec_production", "kdec_entryentity.id", "kdec_entryentity.kdec_fruits"};
            // propertys每个属性的类型,这在之后构造DynamicSimpleProperty需要用到
            Class[] propertyTypes = {String.class, String.class, String.class, String.class, String.class};

            // 构造DynamicObjectCollection用来存储JsonArray
            DynamicObjectCollection data = new DynamicObjectCollection();
            // TODO: 两种方式构造数据
            // TODO: 方法一,fastjson解析构建
            // fastjson将JsonArray转换为一个字符串数组
            /*String[] jsonList = JSON.parseObject(json, String[].class);
            for (String item : jsonList) {
                // fastjson将JsonObject转换为一个Map表
                Map<String, Object> map = JSON.parseObject(item);
                // 构造DynamicObjectType
                DynamicObjectType dynamicObjectType = new DynamicObjectType("kdec_t_bill_1");
                for (int p = 0; p < propertys.length; p++) {
                    DynamicSimpleProperty dynamicSimpleProperty = new DynamicSimpleProperty(propertys[p], propertyTypes[p], null);
                    dynamicObjectType.addProperty(dynamicSimpleProperty);
                }
                // 构造DynamicObject用来存储JsonObject
                DynamicObject dynamicObject = new DynamicObject(dynamicObjectType);
                for (String property : propertys) {
                    // 把Map表中的key和value存进DynamicObject
                    dynamicObject.set(property, map.get(property));
                }
                // 把DynamicObject存进DynamicObjectCollection
                data.add(dynamicObject);
            }*/

            // TODO: 方法二,使用云苍穹封装的DynamicObjectSerializeUtil进行转换
            DynamicObjectType dynamicObjectType = new DynamicObjectType("kdec_t_bill_1");
            for (int p = 0; p < propertys.length; p++) {
                DynamicSimpleProperty dynamicSimpleProperty = new DynamicSimpleProperty(propertys[p], propertyTypes[p], null);
                dynamicObjectType.addProperty(dynamicSimpleProperty);
            }
            DynamicObjectSerializeUtil.serialize(data.toArray(), dynamicObjectType);

            Object[] objects = DynamicObjectSerializeUtil.deserialize(json2, dynamicObjectType);
            for(Object d : objects) {
                data.add((DynamicObject) d);
            }

            getQueryResult().setCollection(data);
            getQueryResult().setDataCount(data.size());
            return data;
        }
    }

    @Override
    public void afterBindData(EventObject e) {
        super.afterBindData(e);

        BillList billList = this.getControl("kdec_billlistap");
        List<IListColumn> columns = billList.getShowListColumns();


        System.out.println("");
    }

    private ListColumn createListColumn(String key, String caption, int colIndex){

        ListColumn col = new ListColumn();

        col.setCaption(new LocaleString(caption));

        col.setListFieldKey(key);
        col.setKey(key);
        col.setFieldName(key);

        col.setSeq(colIndex);

        col.setWidth(new LocaleString("8%"));

        return col;
    }

}


(4)动态表单中注册插件,注册完成之后,点击右上角的保存,然后点击预览

image.png


4.效果图

image.png





    

赞 16