@Data
@Builder
public class Menu {
/**
* id
*/
public Integer id;
/**
* 名称
*/
public String name;
/**
* 父id ,根节点为0
*/
public Integer parentId;
/**
* 子节点信息
*/
public List<Menu> childList;
}
/**
* 递归查询子节点
* @param root 根节点
* @param all 所有节点
* @return 根节点信息
*/
private List<Menu> getChildrens(Menu root, List<Menu> all) {
List<Menu> children = all.stream().filter(m -> {
return Objects.equals(m.getParentId(), root.getId());
}).map(
(m) -> {
m.setChildList(getChildrens(m, all));
return m;
}
).collect(Collectors.toList());
return children;
}
我这里目标结构是这样:
就是root里面有个data和children,data是 主节点信息,children是子节点的信息,同时子节点还可以有子节点,主要信息也是data和children。
{
"root": {
"data": {
"category": "Main",
"fontSize": 30,
"uid": "0",
"expand": true,
"richText": true,
"isActive": false
},
"children": [{
"data": {
"uid": "92da6add-7d31-4442-b577-66dd0cb4a580",
"expand": true,
"richText": true,
"isActive": false,
"category": "Custom",
"fontFamily": "Arial"
},
"children": [{
"data": {
"uid": "574f5ada-5566-4eb1-9f74-61dd68e82a5f",
"expand": true,
"richText": true,
"isActive": false,
"category": "Custom",
"fontFamily": "Arial"
},
"children": []
}]
}]
}
}
创建的实体类如下:
1.最外层的Root
@Data
public class DiagramRoot {
private DiagramData data;
private List<DiagramRoot> children;
}
2.data实体类
@Data
public class DiagramData {
private Integer parent;
private Integer uid;
private String text;
private String category;
private List<DiagramData> children;
}
因为children里面又是data和children,所以肯定用到了递归。方法如下:
private DiagramRoot getChildren(DiagramData rootVo, List<DiagramData> all) {
DiagramRoot root = new DiagramRoot();
try{
root.setData(rootVo);
List<DiagramData> childrenList = new ArrayList<>();
for (DiagramData diagramData : all) {
if(ObjectUtil.isNotNull(diagramData.getParent()) && rootVo.getUid().equals(diagramData.getParent())){
childrenList.add(diagramData);
}
}
for (DiagramData childDiagramData : childrenList) {
DiagramRoot childRoot = getChildren(childDiagramData, all);
if(ObjectUtil.isNull(root.getChildren())){
List<DiagramRoot> children = new ArrayList<>();
children.add(childRoot);
root.setChildren(children);
}else{
root.getChildren().add(childRoot);
}
}
}catch (Exception e){
e.printStackTrace();
}
return root;
}
调用方法如下:
@RequestMapping(value = "/getDiagramV3FileContent/{appFileInfoId}", method = RequestMethod.GET)
public ResponseVo getDiagramV3FileContent(HttpServletRequest request, @PathVariable Long appFileInfoId) {
try {
OfficeFileVo officeFileVo = new OfficeFileVo();
AppFileInfo appFileInfo = baseService.getById(appFileInfoId);
if (ObjectUtil.isEmpty(appFileInfo)) {
return AppResultBuilder.faile(ResultCodeEnum.FILE_ID_ERROR);
}
BeanUtils.copyProperties(appFileInfo, officeFileVo);
DiagramRoot root = new DiagramRoot();
//组装数据
if (Objects.equals(officeFileVo.getOfficeFlag(), Constants.INTEGER_DEFAULT_ONE)) {
if (ObjectUtil.equal(Constants.INTEGER_DEFAULT_ZERO, appFileInfoId)) {
return AppResultBuilder.success(null, ResultCodeEnum.SUCCESS);
}
//1.数据是从mongo拿出来的
SpaceOfficeContentVo spaceOfficeContentVo = mongoService.getInfo(appFileInfoId, OfficeMongoEnum.CONTENT_COLLECTION.getCode());
if (ObjectUtil.isNotEmpty(spaceOfficeContentVo)) {
officeFileVo.setContent(spaceOfficeContentVo.getContent());
ArrayList arrayList = (ArrayList)((LinkedHashMap) spaceOfficeContentVo.getContent()).get("data");
String s = JSON.toJSONString(arrayList);
//2.转换成类DiagramData的数据了
List<DiagramData> all = JSONArray.parseArray(s, DiagramData.class);
//获取到主节点
DiagramData diagramData = all.stream().filter(x -> ObjectUtil.isNull(x.getParent())).findFirst().orElse(null);
root = getChildren(diagramData, all);
}
}
return AppResultBuilder.success(root, ResultCodeEnum.SUCCESS);
} catch (Exception e) {
return AppResultBuilder.faile(ResultCodeEnum.SERVER_ERROR);
}
}
运行结果如下:
{
"code": 200,
"data": {
"children": [
{
"children": [
{
"children": [],
"data": {
"category": "Person",
"children": [],
"key": -4,
"parent": -2,
"text": "分支主题1的子节点"
}
}
],
"data": {
"category": "Custom",
"children": [],
"key": -2,
"parent": 0,
"text": "分支主题1"
}
},
{
"children": [
{
"children": [],
"data": {
"category": "Person",
"children": [],
"key": -10,
"parent": -3,
"text": "分支主题2的子节点"
}
},
{
"children": [],
"data": {
"category": "Person",
"children": [],
"key": -12,
"parent": -3,
"text": "分支主题2的子节点"
}
}
],
"data": {
"category": "Custom",
"children": [],
"key": -3,
"parent": 0,
"text": "分支主题2"
}
},
{
"children": [
{
"children": [],
"data": {
"category": "Person",
"children": [],
"key": -9,
"parent": -5,
"text": "分支主题3的子节点"
}
}
],
"data": {
"category": "Custom",
"children": [],
"key": -5,
"parent": 0,
"text": "分支主题3"
}
},
{
"children": [
{
"children": [],
"data": {
"category": "Custom",
"children": [],
"key": -7,
"parent": -6,
"text": "分支主题4的子节点111"
}
},
{
"children": [
{
"children": [],
"data": {
"category": "Person",
"children": [],
"key": -11,
"parent": -8,
"text": "分支主题4的子节点222的子节点1111"
}
}
],
"data": {
"category": "Custom",
"children": [],
"key": -8,
"parent": -6,
"text": "分支主题4的子节点222"
}
}
],
"data": {
"category": "Custom",
"children": [],
"key": -6,
"parent": 0,
"text": "分支主题4"
}
}
],
"data": {
"category": "Main",
"children": [],
"key": 0,
"parent": 0,
"text": "2023年的第一场雪"
}
},
"msg": "成功"
}
但是后来又说要文件的其他信息:
就又包装了一层:
这里的content主要是为了存放刚刚的节点信息,现在要做的就是把root整体放进去。
public class OfficeFileVo extends AppFileInfo {
@ApiModelProperty(value = "内容(大JSON)")
private Object content;
}
AppFileInfo是前端需要的文件信息:
public class AppFileInfo extends BaseEntity {
@ApiModelProperty(value="APPID,自增,唯一",example = "1" ,dataType = "Long")
@TableId(type = IdType.ASSIGN_ID)
private Long appFileInfoId;
@ApiModelProperty(value="用户ID",example = "1" ,dataType = "Long")
private Long hhxsUserId;
@ApiModelProperty(value="上传者ID",example = "1" ,dataType = "Long")
private Long uploadUserId;
@ApiModelProperty(value="文件名称",example = "a.mp4/b.png/c.pdf")
private String fileName;
@ApiModelProperty(value="文件地址",example = "1")
private String fileUrl;
@ApiModelProperty(value="缩略图URL",example = "1")
private String fileAvatar;
@ApiModelProperty(value="预览URL(视频文件转MP4地址)")
private String filePreview;
@ApiModelProperty(value="是否公开(0公开,1非公开)",example = "1" ,dataType = "Integer")
private Integer fileIsPublic;
.....
}
代码更改如下:
@RequestMapping(value = "/getDiagramV3FileContent111/{appFileInfoId}", method = RequestMethod.GET)
public ResponseVo getDiagramV3FileContent111(HttpServletRequest request, @PathVariable Long appFileInfoId) {
try {
OfficeFileVo officeFileVo = new OfficeFileVo();
AppFileInfo appFileInfo = baseService.getById(appFileInfoId);
if (ObjectUtil.isEmpty(appFileInfo)) {
return AppResultBuilder.faile(ResultCodeEnum.FILE_ID_ERROR);
}
BeanUtils.copyProperties(appFileInfo, officeFileVo);
//组装数据
if (Objects.equals(officeFileVo.getOfficeFlag(), Constants.INTEGER_DEFAULT_ONE)) {
if (ObjectUtil.equal(Constants.INTEGER_DEFAULT_ZERO, appFileInfoId)) {
return AppResultBuilder.success(null, ResultCodeEnum.SUCCESS);
}
//1.数据是从mongo拿出来的
SpaceOfficeContentVo spaceOfficeContentVo = mongoService.getInfo(appFileInfoId, OfficeMongoEnum.CONTENT_COLLECTION.getCode());
if (ObjectUtil.isNotEmpty(spaceOfficeContentVo)) {
ArrayList arrayList = (ArrayList)((LinkedHashMap) spaceOfficeContentVo.getContent()).get("data");
String s = JSON.toJSONString(arrayList);
//2.转换成类DiagramData的数据了
List<DiagramData> all = JSONArray.parseArray(s, DiagramData.class);
DiagramData diagramData = all.stream().filter(x -> ObjectUtil.isNull(x.getParent())).findFirst().orElse(null);
DiagramRoot root = getChildren(diagramData, all);
//之前组装的data和children放到这里,又包一层
officeFileVo.setContent(root);
}
}
return AppResultBuilder.success(officeFileVo, ResultCodeEnum.SUCCESS);
} catch (Exception e) {
return AppResultBuilder.faile(ResultCodeEnum.SERVER_ERROR);
}
最后运行结果如下:
{
"code": 200,
"data": {
"appFileInfoId": 7129910661768640,
"appInfoId": 4225135329640576,
"content": {
"children": [],
"data": {
"category": "Main",
"children": [],
"parent": 0,
"text": "中心主题",
"uid": 0
}
},
"deleteTime": 1731568041,
"ext1": "",
"ext2": "",
"ext3": "{\"officeLayout\":\"logicalStructure\",\"memberList\":[],\"officeAllLineColor\":\"#fe5858\",\"officeLineW\":3,\"officeRainbowLine\":true}",
"ext4": "",
"fileAvatar": "",
"fileIsPublic": 0,
"fileIsTop": 0,
"fileLabel": "",
"fileMd5": "",
"fileName": "中心主题.egte",
"filePreview": "",
"fileSort": 1731566889957,
"fileSource": 0,
"fileType": 51,
"fileUrl": "http://10.1.62.111/diagramv3/#/preview?appFileInfoId=7129910661768640&fileType=51&operate=&goback=1",
"graphicFormat": "0",
"hhxsUserId": 3076134814912832,
"imageSource": 0,
"insertedTime": "2024-11-14 14:48:10",
"logicDelete": 0,
"officeFlag": 1,
"params": {},
"privateFlag": 0,
"recoveryShow": 1,
"relyOn": -1,
"sharedFlag": "0",
"shortcut": "0",
"updateTime": "2024-11-14 15:03:22",
"uploadFlag": 2,
"uploadUserId": 3076134814912832,
"version": 1
},
"msg": "成功"
}