普通单据/基础资料使用任一字段实现左树右表页面原创
金蝶云社区-丁梦洋
丁梦洋
0人赞赏了该文章 230次浏览 未经作者许可,禁止转载编辑于2024年06月30日 14:36:44

一、思路

实现左树右表其实只需要这几步:

  1. 绘制左树右表样式的动态表单来展示数据,这一步可以直接用平台的bos_treelist

  2. 查询左树数据并按格式构建节点

  3. 如果左数要支持搜索框和工具栏,需要自行实现逻辑

  4. 实现点击左数节点时刷新过滤右表

左树右表页面可以理解为有两个普通的列表页面各有各的视图与模型,如下图所示,右边是这个单据本身的列表页面,左边是bos_treelist多加的一块区域供自行绘制,我们平时那些继承AbstractListPlugin的插件里getView拿到的都是右边的页面,只有继承了AbstractTreeListPlugin才能通过getTreeListView()拿到左边的页面和监听左树相应事件

image.png


二、代码实现

以单据里一个普通文本字段(下图中的分组字段)作为左树实现左树右表为例:

首先修改【列表表单模板】,【F7列表表单模板】(此时保存预览就能看到上图效果,左树已经有了,只是为空)

image.png

单据注册插件继承自AbstractTreeListPlugin,实现initializeTree方法初始化左树:

  1. 这里首先要去查询左树的数据,由于示例用的是单据的文本字段作为左树,所以是去查询所有单据数据后再去重,如果你们的左树是单据上的某个基础资料,改下查询为查这个基础资料数据即可(查出id和name就行)

  2. 拿到根节点的TreeNode,添加下级节点(TreeNode构造方法的第二个参数是节点id,这里我用的文本做左树,没有现成的id,就用文本代替了,用基础资料做左树的建议用id

this.getTreeModel().addNode方法可以给指定节点添加下级节点,这里我左树只做一级,所以都是给根节点添加下级,大家想做多级的,调整第一个入参即可(TreeNode为树形结构,有parentid和children

public class TestTreeListPlugin extends AbstractTreeListPlugin {
    @Override
    public void initializeTree(EventObject e) {
        super.initializeTree(e);
        //左树数据来源
        DynamicObjectCollection col = QueryServiceHelper.query("a2h6_treelisttest","a2h6_textfield",new QFilter[]{});
        if (CollectionUtils.isEmpty(col)){
            return;
        }
        Set<String> set = col.stream().map(dy -> dy.getString("a2h6_textfield")).collect(Collectors.toSet());
        //开始插入左树节点
        TreeNode root = this.getTreeModel().getRoot();
        for (String nodeName : set) {
            this.getTreeModel().addNode(root.getId(), new TreeNode(root.getId(),nodeName,nodeName));
        }
        //控制根节点是否可见
//        this.getTreeModel().setRootVisable(false);
    }

}

效果如图所示,根节点默认叫【全部】,想修改文本的在上面加上root.setText("文本");即可,也可以调整根节点可见性,更多方法见左树右表单据列表插件-数据模型 (kingdee.com)

image.png

再就是处理左树搜索框和工具栏:

initTreeToolbar方法可以让我们决定是否展示搜索框,新增,编辑,删除按钮

    @Override
    public void initTreeToolbar(EventObject e) {
        //父类方法会调用this.getView().setVisible(true, new String[]{"btnnew", "btnedit", "btndel", "searchap"});
//        super.initTreeToolbar(e);
    }

search方法可以监听左树的搜索,这里我们要根据搜索内容过滤左树,得先把以前的子节点清掉,再重新查出左树数据再添加新的子节点,最后刷新根节点

@Override
public void search(SearchEnterEvent evt) {
    super.search(evt);
    //清理以前的子节点
    TreeNode root = this.getTreeModel().getRoot();
    if (CollectionUtils.isNotEmpty(root.getChildren())){
        root.getChildren().clear();
    }
    //根据查询内容查询查询左树数据
    QFilter[] filters = StringUtils.isEmpty(evt.getText())?new QFilter[]{}:
            new QFilter("a2h6_textfield", QCP.like,"%"+evt.getText()+"%").toArray();
    DynamicObjectCollection col = QueryServiceHelper.query("a2h6_treelisttest","a2h6_textfield", filters);
    if (CollectionUtils.isNotEmpty(col)) {
        Set<String> set = col.stream().map(dy -> dy.getString("a2h6_textfield")).collect(Collectors.toSet());
        //开始插入左树节点
        for (String nodeName : set) {
            this.getTreeModel().addNode(root.getId(), new TreeNode(root.getId(), nodeName, nodeName));
        }
    }
    //刷新节点
    this.getTreeListView().refreshTreeNode(root.getId());

    //补充功能:同时刷新右表,会和右表过滤控件已选择条件互斥,目前我的处理不太完善,慎用
    if (StringUtils.isNotEmpty(evt.getText())){
        QFilter filter = new QFilter("a2h6_textfield", QCP.like,"%"+evt.getText()+"%");
        ListShowParameter listShowParameter = (ListShowParameter)this.getView().getFormShowParameter();
        List<QFilter> filterList = listShowParameter.getListFilterParameter().getQFilters();
        filterList.add(filter);
        ((IListView)this.getView()).refresh();
    }else {
        ((IListView)this.getView()).refresh();
    }
}

效果如图所示

image.png

treeToolbarClick方法可以监听工具栏的点击事件,如果左树用的基础资料,点击新增可以自行showForm新增页面,然后在closedCallBack方法里参考search方法清掉旧节点,重新插入新节点,再刷新根节点。点击编辑、删除同理,这里就不贴代码了,打个断点看下入参格式

image.png

buildTreeListFilter方法在点击左树节点时会触发,这时需要过滤右表,添加filter即可(这里nodeId我在构造节点时传的就是文本本身,所以直接拿来用了)

@Override
public void buildTreeListFilter(BuildTreeListFilterEvent e) {
    super.buildTreeListFilter(e);
    //点击的是根节点,即全部,不用给右表设置过滤条件
    if (e.getNodeId().equals(this.getTreeModel().getRoot().getId())){
        return;
    }
    //这里的过滤和右表搜索框也会互斥
    e.addQFilter(new QFilter("a2h6_textfield", QCP.equals,e.getNodeId()));
}

效果如图所示

image.png

这样一个左树右表页面就完成了,更多事件可参考:左树右表单据列表插件事件总览 (kingdee.com)


赞 0