根据tree文件菜单的path,拼接文件夹路径

本文介绍了一种在文件管理系统中更新文件夹路径的方法,特别是当改变文件夹的上级目录时如何确保所有相关路径得到正确的更新。包括递归更新上级及子文件夹路径的技术细节。

新添加一个的时候拼接十分简单;如果修改的时候呢,这样的情况就比较复杂了,很多情况可能都考虑不完全。

主要问题:修改一个节点的上级节点时,各个节点的资源路径修改幅度较大,比较容易疏漏。

 比如:1、你将某一个节点的上级节点修改到一个节点下面,那么修改那个节点的子节点路径全部需要更改;

             2、如果将某个节点的上级节点修改到该节点的子节点下呢,那就更麻烦了。。需要更新的节点就更多了。

效果图:


	/**
	 * 拼接保存每个文件夹的路径(filepath字段)【从下至上拼接】
	 * @param parents
	 * @param filePath
	 * @return
	 */
	public String getPathName(TIndex parents,String filePath){
		if(parents!=null){
			filePath = parents.getName()+"/"+filePath;
			return getPathName(parents.getTIndex(), filePath);
		}
		return filePath;
	}

/**
     * 更新文件旅游资源文件夹管理
     */
	@Override
	public void updateFilePath(Index index) {
		 
	  TIndex in = indexDao.get(TIndex.class, index.getId());
      BeanUtils.copyProperties(index, in);
      String pid = index.getPid();
      String filePath = in.getName()+"/";
      TIndex parents = null;
      Boolean flag = false;
      if(pid!=null&&!pid.equals("")&&!pid.endsWith(index.getId())){
    	    parents = indexDao.get(TIndex.class, pid);   //获取到父对象 TIndex
    	    flag = isChildren(in, parents);              // 说明要将当前资源修改到当前资源的子/孙子资源下
    		in.setTIndex(parents);
    		filePath = this.getPathName(parents,filePath);
			//if(parents!=null){
			in.setTIndex(parents);
			//}
			if(flag){  //判断是否将上级菜单选择在了自己原菜单的子菜单下面
				RecursionUpdateParentFilePath(parents);
			}
      }else{
    	  in.setTIndex(null);    // 前台没有选中上级资源,所以就置空 
      }
      in.setFilePath(filePath);
      Set<TIndex> set = null;
      if(!flag){ //没有选择在当前资源修改到当前资源的子/孙子资源下
    	  set = in.getTIndexes();
    	  if(set!=null&&set.size()>0){//判断是否有子菜单
    		  this.HasChildren(in);
    	  }
     }else{//更改上级菜单的子菜单
    	 if(parents.getTIndex()!=null){  //同级目录的资源也同时更改
    		 parents = parents.getTIndex();
    	 }
    	 set = parents.getTIndexes();
         if(set!=null&&set.size()>0){  //判断是否有子菜单
        	 this.HasChildren(parents);
     	 }
       }
	}
	/**
	 * 递归更改上级菜单的filepath
	 * @param parents(选中的上级菜单)
	 * @return
	 */
	public String RecursionUpdateParentFilePath(TIndex parents){
		
		String filePath = "";
		String path = this.getPathName(parents,filePath);
		parents.setFilePath(path);
		
		if(parents.getTIndex()!=null){  //代表还有上级菜单
			return RecursionUpdateParentFilePath(parents.getTIndex());
		}
		return null;
	}
	/**
	 * 分层递归更改子菜单路径
	 * @param in
	 * @return
	 */
	public String HasChildren(TIndex in){
		Set<TIndex> children = in.getTIndexes();
		this.getPathNameDown(children,in);
		if(children!=null&&children.size()>0){
			for(TIndex t :children){
			    HasChildren(t);
			}
		}
		return null;
	}
	/**
	 * 通过递归更改子菜单每个文件夹的路径(filepath字段)【从上至下拼接】
	 * @param children(更改对象子菜单)
	 * @param in(更改对象)
	 * @return
	 */
	public String getPathNameDown(Set<TIndex> children,TIndex in){
		 String filePath = in.getFilePath();
		 if(children!=null&&children.size()>0){
			for(TIndex t :children){
			   filePath = in.getFilePath()+t.getName()+"/";
			   t.setFilePath(filePath);
			}
		}
		return filePath;
	}
	/**
	 * 递归判断是否此次修改, 将自己的上级菜单修改到了自己的子菜单中了;
	 * 如果是,那么将该上级菜单的 最顶级的上级菜单置空;
	 * @param t
	 *            当前节点
	 * @param pt
	 *            要修改到的节点
	 */
	public Boolean isChildren(TIndex t,TIndex pt){

		if(pt!=null&&pt.getTIndex()!=null){  //代表至少是该菜单下的子二级菜单
			if(pt.getTIndex().getId().equalsIgnoreCase(t.getId())){
				pt.setTIndex(null);
				return true;
			}else{
				return isChildren(t,pt.getTIndex());
			}
		}
		return false;
	}

给你们看下我的TIndex的结构吧:

@Entity
@Table(name = "t_index", catalog = "qx")
public class TIndex implements java.io.Serializable {

	// Fields

	private String id;
	private TIndex TIndex;
	private String name;
	private String filePath;
	private String comment;
	private BigDecimal seq;
	private String iconCls;
	private Set<TIndex> TIndexes = new HashSet<TIndex>(0);

}


添加文件夹后刷新import * as path from 'path'; export class DDriveTreeDataProvider implements TreeDataProvider<TreeItem> { private _onDidChangeTreeData: vscode.EventEmitter<TreeItem | undefined | null | void> = new vscode.EventEmitter<TreeItem | undefined | null | void>(); readonly onDidChangeTreeData: Event<TreeItem | undefined | null | void> = this._onDidChangeTreeData.event; private path: string; //通过构造函数接收参数 constructor(path:string) { this.path=path; this.refresh();//构造函数立即触发刷新 } //定义刷新函数 refresh(): void { this._onDidChangeTreeData.fire(); } //将数据项(element)转换为 VS Code 能渲染的 TreeItem getTreeItem(element: TreeItem): TreeItem | Thenable<TreeItem> { return element; } getChildren(element?: TreeItem | undefined): ProviderResult<TreeItem[]> { const path=this.path; //const path='d:/'; if (!element) { //当前节点是否是根节点 // 根节点(d盘),返回一个可展开的文件夹节点 const dDriveItem = new TreeItem(path, TreeItemCollapsibleState.Collapsed); // 创建D盘根节点 dDriveItem.resourceUri = vscode.Uri.file(path);//绑定真实文件路径(方便后续读取子目录) return [dDriveItem]; // 返回根节点(数组形式) } else { // 子节点,读取该文件夹下的文件/子目录并返回 const folderPath = element.resourceUri?.fsPath || path;//获取当前文件夹路径 return this.getFolderItems(folderPath); // 读取该文件夹下的文件/子目录 } } // 读取该文件夹下的文件/子目录 private async getFolderItems(folderPath: string): Promise<TreeItem[]> { try { const uri = vscode.Uri.file(folderPath);//将本地文件路径转换为 VS Code 可识别的资源 URI const children = await vscode.workspace.fs.readDirectory(uri);//异步读取目录内容 //筛选出所有文件夹并转换为 VS Code 树形视图节点(TreeItem) const folderItems = children .filter(([name, type]) => type === vscode.FileType.Directory) .map(([name]) => { const fullPath = path.join(folderPath, name); //拼接 const item = new TreeItem(name, TreeItemCollapsibleState.Collapsed); //创根节点 item.resourceUri = vscode.Uri.file(fullPath); //绑定真实文件路径(方便后续读取子目录) item.tooltip = fullPath;//悬停提示完整路径 item.contextValue = 'folder'; // 可选的上下文标识(用于右键菜单) return item; }); // 在filter后添加文件处理 const fileItems = children .filter(([_, type]) => type === vscode.FileType.File) .map(([name]) => { const fullPath = path.join(folderPath, name); //拼接 const item = new vscode.TreeItem(name, vscode.TreeItemCollapsibleState.None);//创叶节点 item.resourceUri = vscode.Uri.file(fullPath); //绑定真实文件路径(方便后续读取子目录) item.tooltip = fullPath;//悬停提示完整路径 item.contextValue = 'file'; // 可选的上下文标识(用于右键菜单) // 命令配置(点击行为) item.command = { command: 'vscode.open', title: '打开文件', arguments: [vscode.Uri.file(fullPath)] // 传入文件URI }; return item; }); return [...folderItems, ...fileItems]; // 合并返回 } catch (error) { console.error(`Error reading directory ${folderPath}:`, error); return []; } } }
08-07
private async getFolderItems(folderPath: string): Promise<TreeItem[]> { try { const uri = vscode.Uri.file(folderPath);//将本地文件路径转换为 VS Code 可识别的资源 URI const children = await vscode.workspace.fs.readDirectory(uri);//异步读取目录内容 //筛选出所有文件夹并转换为 VS Code 树形视图节点(TreeItem) const folderItems = children .filter(([name, type]) => type === vscode.FileType.Directory) .map(([name]) => { const fullPath = path.join(folderPath, name); //拼接 const item = new TreeItem(name, TreeItemCollapsibleState.Collapsed); //创根节点 item.resourceUri = vscode.Uri.file(fullPath); //绑定真实文件路径(方便后续读取子目录) item.tooltip = fullPath;//悬停提示完整路径 item.contextValue = 'folder'; // 可选的上下文标识(用于右键菜单) return item; }); // 在filter后添加文件处理 const fileItems = children .filter(([_, type]) => type === vscode.FileType.File) .map(([name]) => { const fullPath = path.join(folderPath, name); //拼接 const item = new vscode.TreeItem(name, vscode.TreeItemCollapsibleState.None);//创叶节点 item.resourceUri = vscode.Uri.file(fullPath); //绑定真实文件路径(方便后续读取子目录) item.tooltip = fullPath;//悬停提示完整路径 item.contextValue = 'file'; // 可选的上下文标识(用于右键菜单) // 命令配置(点击行为) item.command = { command: 'vscode.open', title: '打开文件', arguments: [vscode.Uri.file(fullPath)] // 传入文件URI }; return item; });右键菜单刷新
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值