如何开发自定义列表界面-使用bos_treelist构造左树右表列表界面原创
金蝶云社区-丨Nick丨
丨Nick丨
14人赞赏了该文章 5,688次浏览 未经作者许可,禁止转载编辑于2022年08月05日 15:51:45
summary-icon摘要由AI智能服务提供

本文档描述了在一个开发平台中实现代购单管理系统的需求、思路、实现过程及注意事项。系统通过树形控件展示代购渠道及其分类,并可根据点击的树节点过滤右侧的代购单据列表。实现过程包括创建渠道和渠道分类的基础资料,构建单据列表插件并继承标准树形列表插件,在插件中手动构建树形数据并在点击事件中触发数据过滤。文档还提到了一些注意事项和可能的扩展功能如新增数据和分类的实现方式,并提供了开发环境版本要求和参考资料。

关键词:单据列表、树形控件

一、需求

物品代购单

二、思路与方案

代购单中含有一个渠道分类,类似京东(电商)、沃尔玛(线下)、米国代购(跨境)等渠道

左树用于记录层分类,右侧展示单据列表,并且可以按照左树点击过滤单据数据

三、实现过程

  1. 新建分组基础资料(kdec_channel) - 采购渠道 :用于维护代购的渠道

  2. 新建基础资料(:kdec_channel_type) - 采购渠道分类 :用于维护采购渠道的分组,使其具有层级关系

  3. 新建单据 (kdec_demo1111tree)- 代购单 :记录代购数据

  4. 维护渠道以及渠道分类

    image.pngimage.png

  5. 在代购单中添加基础资料,绑定渠道,用于记录分组

    image.png

  6. 因为我们要展示树形列表,所以我们要将模板改为bos_treelist,但是注意我们不能直接预览,因为这是单据列表并未实现树形结构,顾我们要在插件中手动构建左树

    image.png

  7. 插件要继承StandardTreeListPlugin 否则无法使用树形列表模板 (extends StandardTreeListPlugin)

  8. 在afterCreateNewData事件中构造数据


  9. /**
    	 * 构造数据
    	 */
    	private void constructorData(TreeView tv1) {
    		// final String rootId = "0"; // 根节点id
    		// TreeNode rootNode = new TreeNode(null, rootId, "根节点", true);
    		// rootNode.setIsOpened(true); // 设置默认展开
    		TreeNode rootNode = this.getTreeModel().getRoot();
    		String rootId = rootNode.getId();
    		// 查出分组数据
    		DynamicObjectCollection types = QueryServiceHelper.query("kdec_channel_type", "Id,name", null);
    		// 查出渠道数据
    		DynamicObjectCollection channels = QueryServiceHelper.query("kdec_channel", "Id,name,group.Id", null);
    		//按照分类分组
    		Map<String, List<DynamicObject>> datatypeMap = channels.stream()
    				.collect(Collectors.groupingBy(it -> it.getString("group.Id")));
    		for (DynamicObject type : types) {//构建树节点
    			// 构造一级子节点
    			String typeId = type.getString("Id");
    			TreeNode tn1 = new TreeNode(rootId, typeId, type.getString("name"), true);
    			tn1.setIsOpened(true);
    			tn1.setColor("red"); // 设置节点文字颜色
    			List<DynamicObject> channelsByType = datatypeMap.get(type.getString("Id"));
    			for (DynamicObject channel : channelsByType) {
    				// 构造二级子节点
    				String channelId = channel.getString("Id");
    				TreeNode tn2 = new TreeNode(typeId, channelId, channel.getString("name"), false);
    				tn1.addChild(tn2);
    			}
    			rootNode.addChild(tn1);
    		}
    
    		// tv1.addNode(rootNode);
    		this.getTreeModel().setRoot(rootNode);//将树节点加到树模型
    		// this.getTreeModel().getRoot().addChild(rootNode);
    	}
  10. 这时候预览就可以看到效果了,但是我们还要实现点击树节点对右侧数据过滤刷新

    image.png

  11. 我们要实现TreeNodeClickListener (TreeNodeClickListener)并做监听(固定的树标识为treeview,模板自带)


  12. @Override
    	public void registerListener(EventObject e) {
    		super.registerListener(e);
    		TreeView tv1 = this.getView().getControl("treeview");
    		tv1.addTreeNodeClickListener(this);
    	}
  13. 在点击事件中默认都写对列表的刷新,这里会触发setfilter方法,所有的过滤都在这个方法实现,不要在其他位置添加过滤,统一由刷新去触发过滤设置

  14. 在setfilter中获取聚焦树节点,获取节点nodeId,因为在构建的时候是将主键设置为nodeId的所以直接可以将其添加为过滤,因为节点可能是渠道分类或渠道,所以书写如下


  15. @Override
    	public void treeNodeClick(TreeNodeEvent e) {
    		super.treeNodeClick(e);
    		BillList billList = this.getControl("billlistap");
    		billList.refresh();
    	}
    
    	@Override
    	public void setFilter(SetFilterEvent e) {
    		super.setFilter(e);
    		String nodeId = this.getTreeModel().getCurrentNodeId().toString();
    		if (this.getTreeModel().getRoot().getId().equals(nodeId)) {
    			return;
    		}
    		e.getQFilters().add(new QFilter("kdec_channel.id", QCP.equals, nodeId)
    				.or(new QFilter("kdec_channel.group.id", QCP.equals, nodeId)));
    
    	}
  16. 将插件注册到列表页,保存,

四、效果图

预览即可

image.png

    image.png

五、开发环境版本

4.0及以上

六、注意事项

1.要将模板改为bos_treelist,否者插件也报错,页面也渲染不出来树

2.不要在列表插件的其他方法setQfilter,所有的位置都可以调用refresh,统一在setFilter设置过滤

思考:

如何在新增数据时将左树数据代入到单据中并赋值渠道字段?

如何实现左树的工具栏中新增分类功能?


七、参考资料

开发平台

学习成长中心

插件开发—标准单据列表插件


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