为了实现一个获取树状组织结构的接口,首先需要理解数据库表 ms_base_depart 的结构。从表结构来看,部门是以层级的方式存储的,每个部门都有一个 parent_id 字段,表示它的上级部门。因此,可以通过递归查询来构建部门的树状结构。
步骤
-
数据库设计分析
-parent_id字段指向上级部门的id字段。
- 通过递归查询所有部门及其子部门,构建树形结构。 -
GoZero 实现
- 在 GoZero 中,使用sqlx提供的数据库查询方法来获取部门数据。
- 在构建组织树时,利用递归或迭代的方式,根据parent_id进行嵌套构建树状结构。
设计接口
假设我们需要编写一个 RESTful API 接口,该接口通过部门的 org_id 获取部门的树状结构。具体的 API 设计如下:
- GET /api/departments/tree
- 请求参数:
-org_id: 组织 ID(可以用于限定组织的根节点,默认返回全部组织)
- 返回数据:
- 返回树状结构的部门信息。
GoZero 实现
以下是用 GoZero 实现获取树状组织树接口的步骤。
1. 数据库查询
首先,我们需要定义一个部门结构体来映射数据库表 ms_base_depart。
package model
type Department struct {
Id int `db:"id"`
OrgId int `db:"org_id"`
ParentId string `db:"parent_id"`
DepartCode string `db:"depart_code"`
DepartName string `db:"depart_name"`
DepartLeader string `db:"depart_leader"`
Sort int `db:"sort"`
Level int `db:"level"`
Type int `db:"type"`
Desc string `db:"desc"`
Status int `db:"status"`
IsDelete int `db:"is_delete"`
CreateTime int `db:"create_time"`
UpdateTime int `db:"update_time"`
DeleteTime int `db:"delete_time"`
}
接着,我们通过 sqlx 获取部门数据:
package logic
import (
"context"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"ms-base/model"
)
type DepartmentLogic struct {
conn sqlx.SqlConn
}
// GetDepartmentsTree 获取部门的树状结构
func (l *DepartmentLogic) GetDepartmentsTree(ctx context.Context, orgId int) ([]model.Department, error) {
var departments []model.Department
query := "SELECT * FROM ms_base_depart WHERE org_id = ? AND is_delete = 0 AND status = 1 ORDER BY sort"
err := l.conn.QueryRows(&departments, query, orgId)
if err != nil {
return nil, err
}
return departments, nil
}
2. 构建树状结构
接下来,我们需要将数据库查询到的部门数据转换为树形结构。我们可以使用递归的方式来完成。
package logic
import (
"ms-base/model"
"fmt"
)
type DepartmentNode struct {
Department model.Department
Children []*DepartmentNode
}
// BuildDepartmentTree 构建部门树
func BuildDepartmentTree(departments []model.Department) []*DepartmentNode {
var tree []*DepartmentNode
departmentMap := make(map[int][]*DepartmentNode)
// 将部门信息构建成树的节点
for _, dept := range departments {
node := &DepartmentNode{Department: dept}
departmentMap[dept.ParentId] = append(departmentMap[dept.ParentId], node)
}
// 构建树
for _, dept := range departments {
if dept.ParentId == "" {
tree = append(tree, departmentMap[dept.ParentId]...)
} else {
parent := departmentMap[dept.ParentId]
for _, p := range parent {
p.Children = append(p.Children, departmentMap[dept.ParentId]...)
}
}
}
return tree
}
3. 控制器实现
在 handler 层,调用逻辑层的方法并返回树形结构:
package handler
import (
"context"
"ms-base/logic"
"ms-base/model"
"net/http"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/rest/httpx"
)
type GetDepartmentsTreeResponse struct {
Data []*logic.DepartmentNode `json:"data"`
}
func GetDepartmentsTreeHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
orgId := 1 // 假设从请求中获取 org_id
logicLayer := logic.DepartmentLogic{}
// 获取部门数据
departments, err := logicLayer.GetDepartmentsTree(ctx, orgId)
if err != nil {
httpx.Error(w, err)
return
}
// 构建树状结构
tree := logic.BuildDepartmentTree(departments)
// 返回数据
response := GetDepartmentsTreeResponse{
Data: tree,
}
httpx.OkJson(w, response)
}
4. 路由配置
在 GoZero 中,路由配置通过 routes 方法进行:
package main
import (
"ms-base/handler"
"github.com/zeromicro/go-zero/rest"
)
func main() {
server := rest.MustNewServer(cfg)
defer server.Stop()
server.AddRoute(rest.Route{
Method: "GET",
Path: "/api/departments/tree",
Handler: handler.GetDepartmentsTreeHandler,
})
server.Start()
}
总结
在这篇文章中,我们展示了如何使用 GoZero 实现一个获取树状组织结构的接口。通过以下步骤:
- 定义数据库模型。
- 编写逻辑层获取数据库中的部门数据。
- 使用递归或迭代将数据转换为树状结构。
- 编写接口响应树状结构数据。
通过以上方法,可以实现高效且易于扩展的树状组织结构查询接口。如果有多个组织或复杂的树状结构需求,还可以进一步优化查询性能或引入缓存机制。