MENU

使用 Go 语言拼装 Tree 结构数据

February 28, 2023 • Read: 978 • 编码,Go

有一张表名称为 cate 包含树形结构关系的表,数据内容如下

mysql> select * from cate;
+----+-----+--------------+------+-------+
| id | pid | title        | sort | level |
+----+-----+--------------+------+-------+
|  1 |   0 | 新闻         |    0 |     0 |
|  2 |   0 | 图片         |    0 |     0 |
|  3 |   1 | 国内新闻     |    0 |     1 |
|  4 |   1 | 国际新闻     |    0 |     1 |
|  5 |   3 | 北京新闻     |    0 |     2 |
|  6 |   4 | 美国新闻     |    0 |     2 |
|  7 |   2 | 美女图片     |    1 |     1 |
|  8 |   2 | 风景图片     |    2 |     1 |
|  9 |   7 | 日韩明星     |    0 |     3 |
| 10 |   9 | 日本电影     |    0 |     4 |
+----+-----+--------------+------+-------+
10 rows in set (0.01 sec)

利用 Go 语言递归函数组装为 Tree 结构:

package main

import (
    "github.com/gin-gonic/gin"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "net/http"
)

// 查询结果集的结构体
type Cate struct {
    ID    uint32
    Pid   uint32
    Title string
}

// 树的结构体 用于生成 JSON
type Tree struct {
    ID       uint32 `json:"value"`
    Title    string `json:"label"`
    Children []Tree `json:"children,omitempty"`
}

func main() {
    dsn := "root:root@(127.0.0.1:3308)/test?charset=utf8mb4&parseTime=True&loc=Local"
    db, _ := gorm.Open(mysql.New(mysql.Config{
        DSN: dsn,
    }), &gorm.Config{})

    var result []Cate
    db.Table("cate").Find(&result)

    r := gin.Default()

    // 指定路由
    r.GET("/", func(context *gin.Context) {
        tree := CreateTree(result, 0)
        context.JSON(http.StatusOK, tree)
    })

    // 启动服务 默认 8080 端口
    r.Run()

}

// 递归生成树
func CreateTree(result []Cate, id uint32) []Tree {
    var tree []Tree
    // 遍历结果集
    for _, item := range result {
        if item.Pid == id {
            node := &Tree{}
            node.ID = item.ID
            node.Title = item.Title
            node.Children = CreateTree(result, item.ID)
            tree = append(tree, *node)
        }
    }
    return tree
}

接口返回内容如下:

[
    {
        "value": 1,
        "label": "新闻",
        "children": [
            {
                "value": 3,
                "label": "国内新闻",
                "children": [
                    {
                        "value": 5,
                        "label": "北京新闻"
                    }
                ]
            },
            {
                "value": 4,
                "label": "国际新闻",
                "children": [
                    {
                        "value": 6,
                        "label": "美国新闻"
                    }
                ]
            }
        ]
    },
    {
        "value": 2,
        "label": "图片",
        "children": [
            {
                "value": 7,
                "label": "美女图片",
                "children": [
                    {
                        "value": 9,
                        "label": "日韩明星",
                        "children": [
                            {
                                "value": 10,
                                "label": "日本电影"
                            }
                        ]
                    }
                ]
            },
            {
                "value": 8,
                "label": "风景图片"
            }
        ]
    }
]