金蝶云苍穹左树右表单据列表插件refreshNode事件案例

涎涎原创约 1978 字大约 7 分钟...KingdeeKingdee

83-金蝶云苍穹左树右表单据列表插件refreshNode事件案例.mdopen in new window

注意

本博文仅供学术研究和交流参考,严禁将其用于商业用途。如因违规使用产生的任何法律问题,使用者需自行负责。

  1. 新建模板单据

  2. 设置单据表名

  3. 添加基础资料并将其资料类型设置为业务应用实体

  4. 如下图所示设置列表属性

列表表单模板: bos_templatetreelist

F7列表表单模板: bos_templatetreelistf7

  1. 编码
package kd.bos.zsybbill.plugin;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import kd.bos.algo.DataSet;
import kd.bos.algo.Row;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.tree.TreeNode;
import kd.bos.form.control.events.RefreshNodeEvent;
import kd.bos.list.events.BuildTreeListFilterEvent;
import kd.bos.list.plugin.AbstractTreeListPlugin;
import kd.bos.orm.ORM;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;

/**
 * <p>Title: </p>
 * <p>
 *    Description:
 *    试验成功
 * </p>
 * <p>Copyright: Copyright (c) 2020</p>
 * @author xx
 * @date 2020年3月16日
 * @version 1.0
 */
public class RefreshNodeSample extends AbstractTreeListPlugin {
	/** 树形控件上方的按钮的主面板 */
	private static final String KEY_TREEBUTTONPANEL  = "flexpanel_treebtn";  
	/** 业务应用字段标识 */
	private static final String KEY_BIZAPPID  = "bizappid";
	
	/**
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 初始化树分组控件上的工具面板时,触发此事件
	 * @remark
	 * 插件在此事件,隐藏树工具面板
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @param e
	 * @see kd.bos.list.plugin.AbstractTreeListPlugin#initTreeToolbar(java.util.EventObject)
	 * @version 1.0
	 */
	@Override
	public void initTreeToolbar(EventObject e) {
		super.initTreeToolbar(e);
		this.getView().setVisible(false, KEY_TREEBUTTONPANEL);//控制树形面板的显示
//		this.getView().setVisible(false, "btndel");//设置新增(btnnew)、修改(btnedit)、删除(btndel)显示与否
	}

	/**
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 加载、刷新子节点事件
	 * @remark
	 * 默认情况下,系统会自动加载基础资料分组表格中的数据作为分组树节点;
	 * 插件可以在此事件中,自行构建分组树上的节点;
	 * 另外,在展开任意节点、或者是列表刷新时,均会触发本事件,需要避免重复添加子节点
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @param e
	 * @see kd.bos.list.plugin.AbstractTreeListPlugin#refreshNode(kd.bos.form.control.events.RefreshNodeEvent)
	 * @version 1.0
	 */
	@Override
	public void refreshNode(RefreshNodeEvent e) {
		super.refreshNode(e);
		
		// 取缓存的根节点
		TreeNode root = this.getTreeModel().getRoot();
		
		// 当前节点
		String currNodeId = (String)e.getNodeId();
		TreeNode currNode = root.getTreeNode(currNodeId, 10);
		
		// 判断当前节点下,是否已经缓存了子节点:如果有,无需重复加载
		if (currNode.getChildren() != null && !currNode.getChildren().isEmpty()){
			// 直接返回缓存的子节点
			e.setChildNodes(currNode.getChildren());
		}
		else {
			// 没有缓存子节点
			if (StringUtils.equals(currNodeId, root.getId())){
				// 当前要刷新的是根节点:读取全部业务云、业务应用,生成节点返回
				e.setChildNodes(this.loadAppNodes());
			}
			else {
				// 当前要刷新非根节点
				// 业务应用节点是一次性加载完毕的,没有采用懒加载;如果在缓存中没有找到其子节点,则说明其没有子节点
				// TODO 如果采用了懒加载子节点方案,则需要在这里尝试加载子节点
				e.setChildNodes(null);
			}
		}
	}

	/**
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 基于当前选择的分组节点,生成单据列表过滤条件时触发
	 * @remark
	 * 插件可以在此插件中,略过系统内置的分组条件,自行生成分组过滤条件
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @param e
	 * @see kd.bos.list.plugin.AbstractTreeListPlugin#buildTreeListFilter(kd.bos.list.events.BuildTreeListFilterEvent)
	 * @version 1.0
	 */
	@Override
	public void buildTreeListFilter(BuildTreeListFilterEvent e) {
		super.buildTreeListFilter(e);
		
		// 生成过滤条件
		QFilter filter = this.buildAppQFilter(KEY_BIZAPPID, (String)e.getNodeId());
		e.addQFilter(filter);
		
		e.setCancel(true);	// 略过系统内置的分组过滤条件
	}
	
	/************** 如下代码,用来加载、搜索业务应用清单  *****************/
	
	/**
	 * List<TreeNode></br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 构造业务应用树节点返回
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @return
	 * @version 1.0
	 */
	private List<TreeNode> loadAppNodes(){
		
		// 读取全部业务云
		Map<String, TreeNode> allNodes = new HashMap<>(); 
		List<TreeNode> cloudNode4 = getCloudData();
		for(TreeNode node: cloudNode4){
			allNodes.put(node.getId(), node);
		}
		
		// 读取全部应用
		List<TreeNode> appNode4 = getAppData();
		for(TreeNode node: appNode4){
			allNodes.put(node.getId(), node);
		}
		
		// 构建节点的父子关系
		for(TreeNode node : allNodes.values()){
			TreeNode parentNode = allNodes.get(node.getParentid());
			if (parentNode != null){
				parentNode.addChild(node);
			}
		}
		
		return cloudNode4;
	}
	
	/**
	 * List<TreeNode></br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 查询数据库,获取业务云数据,构造为树节点集合返回
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @return
	 * @version 1.0
	 */
	private List<TreeNode> getCloudData() {
		List<TreeNode> cloudNode = new ArrayList<TreeNode>();

		ORM orm = ORM.create();
		String fields = "id, number, name";
//		String orderby = "seq asc";
		QFilter[] filters = new QFilter[] {};
		
//		try(DataSet ds = orm.queryDataSet("bos_devportal_bizcloud", "bos_devportal_bizcloud", fields, filters, orderby)) {//这句代码看不懂。。。
		try(DataSet ds = orm.queryDataSet("bos_devportal_bizcloud", "bos_devportal_bizcloud", fields, filters)) {//这句代码看不懂。。。
			Iterator<Row> rows = ds.iterator();
			while (rows.hasNext()) {
				Row row = rows.next();
				TreeNode node = new TreeNode();
				String nodeID = "cloud/" + row.getString("number");
				node.setText(row.getString("name"));
				node.setParentid("0");
				node.setId(nodeID);
				cloudNode.add(node);
			}
		}
		return cloudNode;
	}

	/**
	 * List<TreeNode></br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 *    查询数据库,获取业务应用数据,构造为业务应用树节点集合返回
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @return
	 * @version 1.0
	 */
	private static List<TreeNode> getAppData() {
		// 可见性与发布状态
		List<TreeNode> appNode = new ArrayList<TreeNode>();

		ORM orm = ORM.create();
		String fields = "id,number, name, bizcloud.id, bizcloud.number";
//		String orderby = "seq asc";
		
		QFilter[] filters = new QFilter[] {};
		
//		try (DataSet ds = orm.queryDataSet("bos_devportal_bizapp", "bos_devportal_bizapp", fields, filters, orderby)){
		try (DataSet ds = orm.queryDataSet("bos_devportal_bizapp", "bos_devportal_bizapp", fields, filters)){
			Iterator<Row> rows = ds.iterator();
			while (rows.hasNext()) {
				Row row = rows.next();
				TreeNode node = new TreeNode();
				String parentId = "cloud/" + row.getString("bizcloud.number");
				String nodeID = row.getString("id");
				node.setId(nodeID);
				node.setParentid(parentId);
				node.setText(row.getString("name"));
				appNode.add(node);
			}
		}
		return appNode;
	}
	
	/**
	 * QFilter</br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 根据当前选择节点,生成过滤业务应用范围的条件:
	 * 
	 * 如果当前点击的节点是业务应用,则直接按此业务应用过滤;
	 * 如果点钱点击的节点是业务云,则取此业务云下全部业务应用进行过滤;
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @param appIdFldKey 单据上,业务应用字段名
	 * @param nodeId 当前点击的节点
	 * @return
	 * @version 1.0
	 */
	private QFilter buildAppQFilter(String appIdFldKey, String nodeId){
		
		List<String> appIds = new ArrayList<>();
		TreeNode root = this.getTreeModel().getRoot();
		List<TreeNode> bizCloudNodes = root.getChildren();
		
		if (bizCloudNodes != null){
			for(TreeNode bizCloudNode : bizCloudNodes){
				if (matchCloudNode(nodeId, bizCloudNode, appIds)){
					break;
				}
			}
		}
		
		if (appIds.isEmpty()){
			// 所选节点,未命中任何业务应用:应该选择的是根节点,不限条件
			return null;
		}
		else if (appIds.size() == 0) {
			return new QFilter(appIdFldKey, QCP.equals, appIds.get(0));
		}
		else {
			return new QFilter(appIdFldKey, QCP.in, appIds.toArray(new String[appIds.size()]));
		}
	}

	/**
	 * boolean</br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 判断当前节点,是否与指定的业务云匹配;如果是,返回true,并把本业务云下的全部应用,输出到outAppIds参数中
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @param nodeId 当前节点
	 * @param bizCloudNode 待匹配的业务云节点
	 * @param outAppIds 输出
	 * @return
	 * @version 1.0
	 */
	private boolean matchCloudNode(String nodeId, TreeNode bizCloudNode, List<String> outAppIds){
		
		if (StringUtils.equals(nodeId, bizCloudNode.getId())){
			// 当前节点,就是本次比较的业务云节点:则输出全部业务应用进行过滤
			
			if (bizCloudNode.getChildren() != null){
				for(TreeNode appNode : bizCloudNode.getChildren()){
					outAppIds.add(appNode.getId());
				}
			}
			if (outAppIds.isEmpty()){
				// 如果本业务云下没有任何业务应用:
				// 输出一个不存在的业务应用标识,生成一个永不成立的条件,使单据列表不显示任何数据
				outAppIds.add(nodeId);
			}
			return true;
		}
		else {
			// 当前节点,不是本次比较的业务云节点:则往下匹配其包含的业务应用节点
			
			if (matchAppNode(nodeId, bizCloudNode)){
				outAppIds.add(nodeId);
				return true;
			}
		}
		
		return false;
	}
	
	/**
	 * boolean</br>
	 * 
	 * <p>Title: </p>
	 * <p>
	 *    Description:
	 * 判断当前节点,是否属于所传业务云下的业务应用节点,如果是,返回true
	 * </p>
	 * <p>Copyright: Copyright (c) 2020</p>
	 * @author xx
	 * @date 2020年3月16日
	 * @param param the bare_field_name
	 * @return the bare_field_name
	 * @param nodeId 当前节点
	 * @param bizCloudNode 待匹配的业务云节点
	 * @return
	 * @version 1.0
	 */
	private boolean matchAppNode(String nodeId, TreeNode bizCloudNode){
		if (bizCloudNode.getChildren() != null){
			for(TreeNode appNode : bizCloudNode.getChildren()){
				if (StringUtils.equals(appNode.getId(), nodeId)){
					return true;
				}
			}
		}
		return false;
	}
}
  1. 列表界面预览测试,如下图所示测试成功

分割线


相关信息

以上就是我关于 金蝶云苍穹左树右表单据列表插件refreshNode事件案例 知识点整理与总结的全部内容,希望对你有帮助。。。。。。。

上次编辑于:
贡献者: 涎涎
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.4