

A表示區域節點,S表示站點結點
問題描述:現有jstree包含左圖中的所有結點信息(包含區域結點和站點結點),需要做到輸入站點名稱模糊查詢,顯示查詢子樹結果如右圖
解決策略:
1、先模糊查詢所得站點所在區域結點A5,A6,A4,根據這些從下往上搜索所有子樹的區域結點(主義表述,是區域結點),存至set集合(避免重復放入)
2、找出set集合中的最高點A1(最高點的父節點為空),查詢結點信息放入jsonobject,從上往下搜索子樹中A1所有孩子結點(A2,A4),遞歸遍歷A2,A4的孩子結點,存至孩子結點數組,
遇到區域結點沒有孩子結點則表示其到了最底層區域結點(A5,A6,A4),將其對應區域結點信息存至其孩子結點數組
3、兩步遞歸操作,設值注入最高點結點信息,最終得到包含整棵子樹的所有結點信息。返回給頁面
if (name != null && !"".equals(name)) { name = new String(name.getBytes("iso-8859-1"),"utf-8"); //字符串轉碼 StringBuffer searchValue = new StringBuffer(); searchValue.append("%").append(name).append("%"); //模糊查詢格式化 List<StationBase> stationBaseList = stationBaseService.findStationBaseByName(searchValue.toString()); //根據站點名稱模糊查找站點集合 List<String> stationCodes = new ArrayList<>(); //裝填上面模糊查詢中所負責的站點code, List<Integer> areaIds_bottom = new ArrayList<>(); //存放上面站點所在區域id,即最底層的區域結點id Set<Integer> areaIdSet = new HashSet<Integer>(); //存放子樹中所有區域結點的id,避免重復用set集合 for (StationBase stationBase:stationBaseList) { if(areaIds.contains(stationBase.getArea().getId())){ //areaIds表示用戶所負責的所有區域站點的id,即整顆樹區域節點id stationCodes.add(stationBase.getStationCode()); areaIds_bottom.add(stationBase.getArea().getId()); areaIdSet.add(stationBase.getArea().getId()); } } areaIdSet = getAllAreaIdBySearch(areaIdSet,areaIds_bottom); //設值注入獲取子樹中所有區域結點的id //找出最高點,裝入集合 JSONObject jo_top = new JSONObject(); //最高點結點 for(Integer area_Id : areaIdSet){ if(area_Id!=null){ List<Integer> area_Ids = new ArrayList<>(); //為了符合傳入的是List集合 area_Ids.add(area_Id); if(stationBaseService.findParentIdsByAreaIds(area_Ids).get(0)==null) { //找出最高點,並裝填信息 Area area = areaService.findAllArea(area_Id).get(0); JSONObject state = new JSONObject(); jo_top.put("id", areaPrefix + area.getId()); jo_top.put("text", area.getArea()); jo_top.put("type", "areatype"); state.put("opened", true); jo_top.put("state", state); jo_top = findChainArea(jo_top, areaIdSet, areaPrefix, stationCodes); //設值注入獲取包含根結點的子樹 break; } } } jsonArray.add(jo_top); //存入json數組 return jsonArray; }
/** * 遞歸查找包括最底層areaIdSet一直往上的所有areaId,避免重復用Set集合 * @param areaIdSet 最底層到最高層所有層的areaId集合 * @param areaId_row 根據用戶輸入站點名所查的最底層areaId集合 * @return */ protected Set<Integer> getAllAreaIdBySearch(Set<Integer> areaIdSet,List<Integer> areaId_row){ if(areaId_row!=null && areaId_row.size()>0 && areaId_row.get(0)!=null){ //areaId_row寫在與前面,避免為空先做判斷,直到查到ParentId為空結束遞歸 List<Integer> areaParentIdList = stationBaseService.findParentIdsByAreaIds(areaId_row); //獲取當前areaId_row所有的parentId for (Integer areaId:areaParentIdList){ areaIdSet.add(areaId); //使用set集合對所搜集areaId進行去重 } return getAllAreaIdBySearch(areaIdSet,areaParentIdList); //遞歸訪問上一層區域結點 } return areaIdSet; } /** * 遞歸查找從最高點jo往下一層層遍歷,將遍歷結點存至孩子結點數組中 * @param jo 最高點 * @param areaIdSet 整顆樹區域id * @param areaPrefix 區域id前綴 * @param stationCodes 子樹所有站點code * @return */ protected JSONObject findChainArea(JSONObject jo,Set<Integer> areaIdSet,String areaPrefix,List<String> stationCodes){ List<Integer> childIds = stationBaseService.findIdsByParent(Integer.parseInt(jo.get("id").toString().split("_")[1])); if(childIds!=null && childIds.size()>0 && childIds.get(0)!=null){ //有子區域節點,非葉節點 //查詢子區域節點信息,添加到jo中,areaIdSet中對應的id JSONArray areaChildArray = new JSONArray(); //存放該結點在對應子樹中的孩子結點數組 for (Integer childId:childIds) { if(areaIdSet.contains(childId)){ //屬於子樹中結點便添加到孩子結點數組中 Area area = areaService.findAllArea(childId).get(0); JSONObject jo_child = new JSONObject(); JSONObject state = new JSONObject(); jo_child.put("id",areaPrefix+area.getId()); jo_child.put("text",area.getArea()); jo_child.put("type","areatype"); state.put("opened", true); jo_child.put("state",state); jo_child = findChainArea(jo_child,areaIdSet,areaPrefix,stationCodes); areaChildArray.add(jo_child); } } jo.put("children",areaChildArray); }else{ //無子區域,葉節點,添加站點信息 List<StationBase> stationBaseList = stationBaseService.findByAreaId(Integer.parseInt(jo.get("id").toString().split("_")[1])); JSONArray stationArray = new JSONArray(); //該站點下的所有站點 for (StationBase stationBase : stationBaseList){ if(stationCodes.contains(stationBase.getStationCode())){ JSONObject stationObj = new JSONObject(); stationObj.put("id", "s_" + stationBase.getStationCode()); stationObj.put("text", stationBase.getStationName()); stationObj.put("type", "stationInfo"); stationObj.put("children", false); stationArray.add(stationObj); } } jo.put("children",stationArray); } return jo; }