文章目录
前言
在项目中经常遇到做树形结构的需求,但是可能会有很多种情况不同形式的树形结构,最常见的就是有id,父id,名称这种做树形结构,会比较好做。但是我这边遇到的是单列数据ID,例如最高级id是01,01的下级是0101,0102这种形式的树形结构,可以参考下我是如何实现的;并且是无限下级
我这边用的是SpringCloud+MyBatisPuls
一、表结构以及所需用到的实体
1.数据库表
这边的sCode就是数据ID,最高级是两位数01、02、03,第二级就是0101、0202、0303这种形式;
2.数据库表对应Model
package com.whxx.emr.template.bean;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
/**
* @author 孤巷.
* @description
* @date 2024/4/1 上午 8:58
*/
/**
* 电子病历目录
*/
@ApiModel(description="电子病历目录")
@Data
@TableName(value = "emr_listroot")
public class EmrListroot {
/**
* 文件代码
*/
@TableId(value = "sCode", type = IdType.AUTO)
@ApiModelProperty(value="文件代码")
private String scode;
/**
* 文件名称
*/
@TableField(value = "sNote")
@ApiModelProperty(value="文件名称")
private String snote;
/**
* 在用(0否1是)
*/
@TableField(value = "sOpen")
@ApiModelProperty(value="在用(0否1是)")
private String sopen;
/**
* 运行病历顺序
*/
@TableField(value = "nRun")
@ApiModelProperty(value="运行病历顺序")
private BigDecimal nrun;
/**
* 归档病历顺序
*/
@TableField(value = "nStore")
@ApiModelProperty(value="归档病历顺序")
private BigDecimal nstore;
/**
* 登记时间
*/
@TableField(value = "dTime")
@ApiModelProperty(value="登记时间")
private LocalDateTime dtime;
}
3.最终的树形结构DTO(返回给前端的实体)
备注:patientId和children是我自己加进去的,用来组装树形结构数据
package com.whxx.emr.template.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* @author 孤巷.
* @description
* @date 2024/4/1 上午 9:10
*/
@Data
public class ListRootTreeViewDto {
@ApiModelProperty(value = "目录编码")
private String scode;
@ApiModelProperty(value = "目录名称")
private String snote;
@ApiModelProperty(value = "目录父级编码")
private String patientId;
@ApiModelProperty(value = "目录子节点")
private List<ListRootTreeViewDto> children;
public ListRootTreeViewDto(String scode, String snote, String patientId, List<ListRootTreeViewDto> children) {
this.scode = scode;
this.snote = snote;
this.patientId = patientId;
this.children = children;
}
}
二、业务代码
1.递归填充所有子节点
代码如下:
private void createResourceClassTreeType2(List<ListRootTreeViewDto> parentList,Map<String,List<ListRootTreeViewDto>> tempMap){
for (ListRootTreeViewDto parent : parentList) {
List<ListRootTreeViewDto> children = tempMap.get(parent.getScode());
if( children != null ){
parent.setChildren(children);
createResourceClassTreeType2(children, tempMap);
}
}
}
2.获取树状结构数据数据-无限下级
代码如下(示例):
public List<ListRootTreeViewDto> getResourceClassTreeType2(List<ListRootTreeViewDto> allList) {
List<ListRootTreeViewDto> parentList = new ArrayList<>();
//获取所有父类集合
for(ListRootTreeViewDto dto : allList){
if(dto.getPatientId().equals("0")){
parentList.add(dto);
}
}
// 以 父id 为 KEY ,
Map<String, List<ListRootTreeViewDto>> tempMap = new HashMap<>();
String resourceClassParentId;
List<ListRootTreeViewDto> children;
for (ListRootTreeViewDto classTemp : allList) {
resourceClassParentId = classTemp == null ? null : classTemp.getPatientId();
if( resourceClassParentId == null ){
continue;
}
children = tempMap.get(resourceClassParentId);
if( children == null ){
children = new LinkedList<>();
children.add(new ListRootTreeViewDto(classTemp.getScode(), classTemp.getSnote(), classTemp.getPatientId(),classTemp.getChildren()));
tempMap.put(resourceClassParentId, children);
} else {
children.add(new ListRootTreeViewDto(classTemp.getScode(), classTemp.getSnote(), classTemp.getPatientId(),classTemp.getChildren()));
}
}
// 填充子节点 并 返回
createResourceClassTreeType2(parentList, tempMap);
return parentList;
}
3.最后组装的Service
提示:Result 这个类是我通用的返回类,你也可以根据你自己的需求来;treeViewList 就是最后的树形结构结果了,返回给前段就行!
/**
* 获取病历模板目录-树状结构
* @return Result
*/
public Result<List<ListRootTreeViewDto>> getListRootTreeView(){
LambdaQueryWrapper<EmrListroot> lambda = new LambdaQueryWrapper<>();
lambda.eq(EmrListroot::getSopen,1);
lambda.orderByAsc(EmrListroot::getScode);
//查询所有目录信息
List<ListRootTreeViewDto> emrKeyTitleVoList = new ArrayList<>();
List<EmrListroot> list = list(lambda);
//编辑数据,赋值父ID(我这表里没有父ID,所以要自己组装赋值下父id,有父id的跳过这一步就可以)
for (EmrListroot emrListroot : list){
ListRootTreeViewDto dto = new ListRootTreeViewDto(emrListroot.getScode(),emrListroot.getSnote(),null,new ArrayList<>());
if(emrListroot.getScode().length() == 2){
dto.setPatientId("0");
}else{
String code = dto.getScode();
//我这边因为是01、02、03的形式的id,截取最后两位,前面的就是这条数据的父ID了
String parentId = code.substring(0,code.length() - 2);
dto.setPatientId(parentId);
}
emrKeyTitleVoList.add(dto);
}
List<ListRootTreeViewDto> treeViewList = getResourceClassTreeType2(emrKeyTitleVoList);
return Result.success(treeViewList);
}
总结
看到这里相信你已经实现了树形结构了,后期我会记录更多编写项目中遇到的技术点和问题,欢迎你的关注,有啥不清楚的可以下方评论或私信,我会第一时间回复哦!!!