@Data
@Entity
@Table(name = "jsd_tree_node")
public class TreeNode {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "pid")
private Long parentId;
@OneToMany(mappedBy = "parentId", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TreeNode> children;
public TreeNode() {
this.children = new ArrayList<>();
}
public TreeNode(String name, Long parentId) {
this.name = name;
this.parentId = parentId;
this.children = new ArrayList<>();
}
public void addChild(TreeNode child) {
child.setParentId(this.id);
if (!this.children.contains(child)) {
this.children.add(child);
}
}
public void removeChild(TreeNode child) {
child.setParentId(null);
this.children.remove(child);
}
public TreeNode findNode(Long nodeId) {
if (this.id.equals(nodeId)) {
return this;
}
for (TreeNode child : children) {
TreeNode foundNode = child.findNode(nodeId);
if (foundNode != null) {
return foundNode;
}
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TreeNode treeNode = (TreeNode) o;
return Objects.equals(id, treeNode.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
import com.jsd.web.attachment.entity.TreeNode;
import org.springframework.data.jpa.repository.JpaRepository;
public interface TreeNodeRepository extends JpaRepository<TreeNode, Long> {
}
public interface TreeNodeService {
List<TreeNode> getAllNodes();
TreeNode getNodeById(Long nodeId);
TreeNode addNode(TreeNode newNode);
TreeNode updateNode(TreeNode updatedNode);
void deleteNode(Long nodeId);
List<Long> getAllChildIds(Long nodeId);
}
@Service
public class TreeNodeServiceImpl implements TreeNodeService {
private final TreeNodeRepository treeNodeRepository;
@Autowired
public TreeNodeServiceImpl(TreeNodeRepository treeNodeRepository) {
this.treeNodeRepository = treeNodeRepository;
}
@Override
public List<TreeNode> getAllNodes() {
List<TreeNode> allNodes = treeNodeRepository.findAll();
List<TreeNode> rootNodes = new ArrayList<>();
Map<Long, TreeNode> nodeMap = new HashMap<>();
for (TreeNode node : allNodes) {
nodeMap.put(node.getId(), node);
Long parentId = node.getParentId();
if (parentId == null) {
rootNodes.add(node);
} else {
TreeNode parent = nodeMap.get(parentId);
if (parent != null) {
parent.addChild(node);
}
}
}
allNodes.removeAll(rootNodes);
return rootNodes;
}
@Override
public TreeNode getNodeById(Long nodeId) {
return treeNodeRepository.findById(nodeId).orElse(null);
}
@Override
public TreeNode addNode(TreeNode newNode) {
return treeNodeRepository.save(newNode);
}
@Override
public TreeNode updateNode(TreeNode updatedNode) {
return treeNodeRepository.save(updatedNode);
}
@Override
public void deleteNode(Long nodeId) {
TreeNode node = treeNodeRepository.findById(nodeId).orElse(null);
if (node != null) {
List<TreeNode> children = node.getChildren();
for (TreeNode child : children) {
child.setParentId(null);
}
treeNodeRepository.delete(node);
}
}
@Override
public List<Long> getAllChildIds(Long nodeId) {
List<Long> childIds = new ArrayList<>();
TreeNode node = treeNodeRepository.findById(nodeId).orElse(null);
if (node != null) {
addChildIds(node, childIds);
}
return childIds;
}
private void addChildIds(TreeNode node, List<Long> childIds) {
List<TreeNode> children = node.getChildren();
if (children != null && !children.isEmpty()) {
for (TreeNode child : children) {
childIds.add(child.getId());
addChildIds(child, childIds);
}
}
}
}
@RestController
@RequestMapping("/api/tree")
public class TreeNodeController {
private final TreeNodeService treeNodeService;
@Autowired
public TreeNodeController(TreeNodeService treeNodeService) {
this.treeNodeService = treeNodeService;
}
@GetMapping("/nodes")
public List<TreeNode> getAllNodes() {
List<TreeNode> allNodes = treeNodeService.getAllNodes();
List<TreeNode> rootNodes = buildTreeStructure(allNodes);
return rootNodes;
}
private List<TreeNode> buildTreeStructure(List<TreeNode> nodes) {
if (nodes == null || nodes.isEmpty()) {
return new ArrayList<>();
}
Map<Long, TreeNode> nodeMap = new HashMap<>();
for (TreeNode node : nodes) {
nodeMap.put(node.getId(), node);
}
for (TreeNode node : nodes) {
Long parentId = node.getParentId();
if (parentId != null) {
TreeNode parent = nodeMap.get(parentId);
if (parent != null) {
parent.addChild(node);
}
}
}
List<TreeNode> rootNodes = new ArrayList<>();
for (TreeNode node : nodes) {
if (node.getParentId() == null) {
rootNodes.add(node);
}
}
return rootNodes;
}
private void buildTreeStructure(TreeNode node) {
List<TreeNode> children = node.getChildren();
if (children != null) {
node.setChildren(new ArrayList<>());
for (TreeNode child : children) {
buildTreeStructure(child);
}
}
}
@GetMapping("/nodes/{id}")
public TreeNode getNodeById(@PathVariable("id") Long nodeId) {
TreeNode node = treeNodeService.getNodeById(nodeId);
if (node != null) {
buildTreeStructure(node);
}
return node;
}
@PostMapping("/nodes")
public TreeNode addNode(@RequestBody TreeNode newNode) {
TreeNode parentNode = treeNodeService.getNodeById(newNode.getParentId());
if (parentNode != null) {
parentNode.addChild(newNode);
} else {
return null;
}
return treeNodeService.addNode(newNode);
}
@PutMapping("/nodes/{id}")
public TreeNode updateNode(@PathVariable("id") Long nodeId, @RequestBody TreeNode updatedNode) {
TreeNode existingNode = treeNodeService.getNodeById(nodeId);
if (existingNode != null) {
existingNode.setName(updatedNode.getName());
existingNode.setParentId(updatedNode.getParentId());
return treeNodeService.updateNode(existingNode);
} else {
return null;
}
}
@DeleteMapping("/nodes/{id}")
public void deleteNode(@PathVariable("id") Long nodeId) {
treeNodeService.deleteNode(nodeId);
}
@GetMapping("/{id}/children")
public List<Long> getAllChildIds(@PathVariable("id") Long nodeId) {
return treeNodeService.getAllChildIds(nodeId);
}
}