使用效果
初始化載入頂層節點,點選各層的>載入該節點的子節點,載入後>標識去除不再重複載入。
前端程式碼
vue ant-design元件
- tree-data,樹節點,children方式或id、pid方式
- load-data,展開節點事件,響應該事件載入子節點
<a-tree-select v-model:value="sample" :tree-data="sampleTreeData" :load-data="onLoadSampleTreeData"
style="width: 100%" allowClear treeDataSimpleMode
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
placeholder="請選擇測試計劃/樣品" >
</a-tree-select>
定義interface
- 非同步載入通過id和pid匹配,因此沒有children屬性,替換為id何pid
- 新增level便於後端識別,如果後端為一個表內的資料且通過id和pid或parentid關聯則不需要
export interface TreeDataItem {
id: string | number;
pId: string | number;
value: string;
title: string;
isLeaf?: boolean;
level: string;
}
載入(跟節點)資料
呼叫後端查詢資料並賦值給treeData,treeData繫結控制元件的treeData屬性。
async function loadSampleTreeRootData() {
// loading.value = true
let params = {"level":"0"};
sampleTreeNode(params).then(result => {
console.log(result)
sampleTreeData.value = sampleTreeData.value.concat(result);
}).finally(() => {
});
// loading.value = false
}
loadSampleTreeRootData()
載入(節點的子節點)資料
響應控制元件的load-data事件,查詢要展開節點的子節點資料,併合併到treeData中,控制元件會根據id和pid顯示層級關係。
const onLoadSampleTreeData = (treeNode: any) => {
return new Promise((resolve: (value?: unknown) => void) => {
// console.log("node:");
// console.log(treeNode.dataRef)
const { id,level,value } = treeNode.dataRef;
// console.log("id:"+id);
// console.log("level:"+level);
// console.log("value:"+value);
setTimeout(() => {
let nextLevel = "1";
if(level=="1")nextLevel="2";
let params = {"level":nextLevel, "id":id};
sampleTreeNode(params).then(result => {
// console.log("result:");
// console.log(result);
sampleTreeData.value = sampleTreeData.value.concat(result);
}).finally(() => {
});
resolve();
}, 300);
});
};
後端程式碼
定義treeNodeVO
pId和isLeaf註解下,避免springMVC預設的序列化。
(預設序列化為pid\leaf)
@Data
public class PlantSampleTreeNodeVO {
//key
private String id;
// private long id;
@JsonProperty("pId")
private String pId;
// private long pId;
//樹節點顯示的內容
private String title;
//預設根據此屬性值進行篩選(其值在整個樹範圍內唯一)
private Object value;
//是否是葉子節點
@JsonProperty("isLeaf")
private boolean isLeaf;
//節點層級
private String level;
}
controller提供資料
因為是非同步載入,三個表的查詢可在一個service中實現,或直接使用各自的treeNode的service。
@Override
public List<PlantSampleTreeNodeVO> getPlantSampleTreeNodeVO(String level, String id) {
List<PlantSampleTreeNodeVO> plantSampleTreeVONodeList = new ArrayList<>();
switch (level) {//頂級節點
case "0":
//查詢所在班組,plant member
List<Plant> plantList = plantService.list();
for (Plant plant : plantList) {
//建立頂層樹/節點
PlantSampleTreeNodeVO plantNode = new PlantSampleTreeNodeVO();
// System.out.println(plant.getId());
// System.out.println(Long.parseLong(plant.getId()));
// System.out.println(Long.valueOf(plant.getId()).longValue());
// plantNode.setId(Long.parseLong(plant.getId()));
plantNode.setId(plant.getId());
plantNode.setPId("0");//and-design tree指定的值
plantNode.setValue(plant.getId());
plantNode.setTitle(plant.getPlantName());
plantNode.setLeaf(false);//需根據業務邏輯判斷是否有子節點,省略處理
plantNode.setLevel("0");
plantSampleTreeVONodeList.add(plantNode);
}
break;
case "1":
//查詢班組相關的樣品組模板
QueryWrapper<SampleGroupTemplate> sampleGroupTemplateQueryWrapper = new QueryWrapper<>();
sampleGroupTemplateQueryWrapper.eq("plantid",id);
List<SampleGroupTemplate> sampleGroupTemplateList = sampleGroupTemplateService.list(sampleGroupTemplateQueryWrapper);
//迴圈各樣品組模板顯示其下的測試計劃/樣品
for(SampleGroupTemplate sampleGroupTemplate: sampleGroupTemplateList){
//新增到樹上
PlantSampleTreeNodeVO sampleGroupNode = new PlantSampleTreeNodeVO();
// sampleGroupNode.setId(Long.parseLong(sampleGroupTemplate.getId()));
sampleGroupNode.setId(sampleGroupTemplate.getId());
// sampleGroupNode.setPId(Long.parseLong(id));
sampleGroupNode.setPId(id);
sampleGroupNode.setValue(sampleGroupTemplate.getId());
sampleGroupNode.setTitle(sampleGroupTemplate.getSampleGroupName());
sampleGroupNode.setLeaf(false);
sampleGroupNode.setLevel("1");
plantSampleTreeVONodeList.add(sampleGroupNode);
}
break;
case "2":
//查詢樣品組模板顯示其下的測試計劃/樣品
QueryWrapper<SgtSample> sampleQueryWrapper = new QueryWrapper<>();
sampleQueryWrapper.eq("templateid",id);
List<SgtSample> sampleList = this.list(sampleQueryWrapper);
//迴圈各樣品
for(SgtSample sample: sampleList) {
PlantSampleTreeNodeVO sampleNode = new PlantSampleTreeNodeVO();
// sampleNode.setId(Long.parseLong(sample.getId()));
sampleNode.setId(sample.getId());
// sampleNode.setPId(Long.parseLong(id));
sampleNode.setPId(id);
sampleNode.setValue(sample.getId());
sampleNode.setTitle(sample.getSampleName());
sampleNode.setLeaf(true);//葉子節點
sampleNode.setLevel("2");
plantSampleTreeVONodeList.add(sampleNode);
}
break;
}
return plantSampleTreeVONodeList;
}