【重学苍穹】超级 F7 - 自定义列表查询原创
金蝶云社区-周立思
周立思
6人赞赏了该文章 221次浏览 未经作者许可,禁止转载编辑于2024年12月05日 18:53:39
summary-icon摘要由AI智能服务提供

本文讲述了在业务开发过程中,扩展F7列表查询的方法,包括自定义ListDataProvider查询、支持多表关联的复杂查询,以及将F7列表查询改成报表的尝试。同时,介绍了实现过程中需要注意的seq字段处理和报表查询字段要求,并提供了相关代码示例和参考资料。

20241205 更新:增加 ListDataProvider 请求 WebAPI 查询数据


需求

业务开发过程中,对于 F7 自定义代码实现比较多的是 过滤、查询、动态列。现在基于 OEM 版苍穹开发,想要扩展 F7 实现可以自定义 F7 列表查询,可以支持多表关联的复杂查询。


思路

F7 是列表:在设计器的【列表】页签可以看到【F7列表表单模板】bos_listf7 (还有 bos_treelistf7 等)

image.pngimage.png


列表实现自定义查询,列表插件重写 ListDataProvider 可以实现。

我心里有一个疑问:在实际业务开发中使用 F7或者社区看到关于 F7 的相关问题,对于 F7 不仅仅是使用默认的功能就可以满足的,有很多的高代码来实现。

我想自由的配置 F7 列表查询,我为什么不能把 F7 列表查询改成报表。

报表支持实现 Algo/AlgoX 复杂的查询,没有 F7 对应基础资料实体的限制。

F7 自定义 ListDataProvider 代码就是黑盒,传入的 Filter 查询的结果对不对怎么验证?

用报表我就可以搭配过滤面板的条件直观的测试验证 F7 查询结果。


实现过程

踩坑第一步

实现 ListDataProvider 查询 DataSet 转成 DynamicObjectCollection

image.png

需要注意 DataSet 字段包含 id,number,name ,在 toDynamicObjectCollection() 会追加 seq 字段。

这块踩坑不详细说了,因为 toDynamicObjectCollection() 方法 seq 字段没有处理好,导致 F7 已选列表出现无法取消的问题。

toDynamicObjectCollection() 方法可以参考源码 kd.bos.list.query.impl.DataSetMapper

实现 DataSetQuery

查看 ListDataProvider 相关源码,继承 IdQuery 实现 ListDataProvider 查询 DataSet 的需求

public abstract class DemoDataSetQuery extends IdQuery {

    protected abstract DataSet queryDataSet(QueryBuilder queryBuilder);

    @Override
    public DynamicObjectCollection getData(QueryBuilder queryBuilder) {
        DataSet dataSet;
        try {
            dataSet = queryDataSet(queryBuilder);
        } catch (Throwable e) {
            throw new KDException(e, new ErrorCode("superf7.rpt.query", "执行报表查询插件发生异常!"));
        }
        RowMeta rowMeta = dataSet.getRowMeta();
        IdQuery.RowsResult rowsResult = getRowsResultAndCloseDs(dataSet, queryBuilder);
        DynamicObjectCollection collection = this.getDynamicCollection(rowsResult.getDealRows(), null, rowMeta, queryBuilder);
        this.setQueryResult(collection, 0, 0, queryBuilder, rowsResult.getSummaryResults());
        return collection;
    }
}


自定义 DataSetListDataProvider

参考源码在 initContext() 处理 ListDataProvider  IQuery

public abstract class DemoDataSetListDataProvider extends ListDataProvider {

    @Override
    protected void initContext(int start, int limit) {
        super.initContext(start, limit);
        this.query = createQuery();
        this.query.setDataEntityTypes(this.dataEntityTypes);
    }

    protected abstract DemoDataSetQuery createQuery();
}


实现报表 ListDataProvider

DataSetListDataProvider 可以实现 F7 查询 DataSet 需求,继续实现支持查询报表 。


private DataSet execReportPluginQuery(ReportQueryParam reportQueryParam) throws Throwable {
    String formId = MetadataDao.getIdByNumber(reportNumber, MetaCategory.Form);
    FormMetadata formMetadata = (FormMetadata) MetadataDao.readRuntimeMeta(formId, MetaCategory.Form);
    ReportListAp reportListAp = (ReportListAp) formMetadata.getItems().stream()
            .filter(e -> "reportlistap".equals(e.getKey())).findAny().orElse(null);
    String reportPlugin = reportListAp.getReportPlugin();
    AbstractReportListDataPlugin queryPlugin = TypesContainer.createInstance(reportPlugin);
    DataSet dataSet = queryPlugin.query(reportQueryParam, null);
    return dataSet;
}

@Override
protected DataSet queryDataSet(QueryBuilder queryBuilder) {
    DataSet dataSet;
    try {
        ReportQueryParam reportQueryParam = new ReportQueryParam();
        FilterInfo filterInfo = new FilterInfo();
        QFilter[] filters = queryBuilder.getFilters();
        fillFilterInfo(filterInfo, filters);
        reportQueryParam.setFilter(filterInfo);
        dataSet = execReportPluginQuery(reportQueryParam);
    } catch (Throwable e) {
        throw new KDException(e, new ErrorCode("superf7.rpt.query", "执行报表查询插件发生异常!"));
    }
    return dataSet;
}

创建 F7 列表表单模板

继承 bos_listf7 注册插件实现自定义  ListDataProvider 。有需要使用的列表可以直接修改基础资料列表 【F7 列表表单模板】

image.png



实现 WebAPI ListDataProvider

DataSetListDataProvider 扩展实现 F7 数据来自 WebAPI 接口。

基于 Algo CustomizedInput 实现请求 WebAPI 接口构造 DataSet。

WebAPI 接口使用集成服务云 WebAPI 登记


public static class APIInput implements CustomizedInput {

    @Override
    public Iterator<Object[]> createIterator() {
        Map<String, Object> body = new HashMap<>();
        String result =DispatchServiceHelper.invokeBizService("isc", "iscb", "IscWebApiService",
                "invoke", new Object[]{"superf7", body});
        JSONObject jsonObject = JSONObject.parseObject(result);
        List<Object[]> returnResult = new ArrayList<>();
        if(jsonObject!=null){

        }
        return returnResult.iterator();
    }

    @Override
    public void close() {

    }

    @Override
    public RowMeta getRowMeta() {
        return new RowMeta(new String[]{"id", "number", "name"},
                new DataType[]{DataType.LongType, DataType.StringType, DataType.StringType});
    }
}


实现 APIQuery

public class APIQuery extends DataSetQuery {
    @Override
    protected DataSet queryDataSet(QueryBuilder queryBuilder) {
        DataSet dataSet = Algo.create("test").createDataSet(new APIInput());
        return dataSet;
    }
}
public class APIListDataProvider extends DataSetListDataProvider {

    @Override
    protected DataSetQuery createQuery() {
        return new APIQuery();
    }
}




效果图

报表数据

image.png

表单基础资料 F7 查询替换成报表数据

image.png

开发环境版本

v6.0


注意事项

  1. 自定义 ListDataProvider 需要注意 seq 字段处理,会影响 F7 列表右侧已选

  2. 报表查询字段需要包含 id,number,name 字段


参考资料

  1. Algo 高级接口:https://dev.kingdee.com/open/detail/sdk/2077750759931262976 



图标赞 6
6人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!