Golang电商项目中的分类模块实现
Golang电商项目中的分类模块实现 大家好,
我正在开发一个电子商务项目,需要帮助处理产品的分类部分。
分类表可能包含以下字段:
id - parent - title - level
在函数参数中,我通过查询获取父级UUID并返回该父级的所有子分类。但我不知道如何检测子分类的子分类以及如何识别父级,以便在父子层级结构中将产品关联到相应的分类。以下是我用于返回父级所有子分类的查询:
func GetChildrenCategories(db *sql.DB, w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
type ParentID struct {
ParentUUID uuid.UUID `json:"parentuuid"`
}
parentID := ParentID{}
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&parentID); err != nil {
utils.RespondError(w, http.StatusBadRequest, err.Error())
return
}
defer r.Body.Close()
query := `
WITH RECURSIVE subordinates AS (
SELECT
id,
parent,
title,
level
FROM
categories
WHERE
parent = $1
UNION
SELECT
e.id,
e.parent,
e.title,
e.level
FROM
categories e
INNER JOIN subordinates s ON s.id = e.parent
) SELECT
*
FROM
subordinates;
`
rows, err := db.QueryContext(ctx, query, parentID.ParentUUID)
if err != nil {
panic(err)
}
categories := make([]model.Category, 0)
for rows.Next() {
var category model.Category
if err := rows.Scan(&category.Id, &category.Parent, &category.Title, &category.Level); err != nil {
}
categories = append(categories, category)
}
utils.RespondJSON(w, http.StatusOK, categories)
}
请帮助我修复这个部分。
更多关于Golang电商项目中的分类模块实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang电商项目中的分类模块实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在电商项目中实现递归分类查询,你的思路是正确的。以下是优化后的实现,包含完整的错误处理和更清晰的结构:
func GetChildrenCategories(db *sql.DB, w http.ResponseWriter, r *http.Request) {
ctx := context.Background()
type Request struct {
ParentUUID uuid.UUID `json:"parentuuid"`
}
var req Request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
utils.RespondError(w, http.StatusBadRequest, "Invalid request body")
return
}
defer r.Body.Close()
// 递归查询获取所有子分类
query := `
WITH RECURSIVE category_tree AS (
SELECT
id,
parent,
title,
level,
1 as depth
FROM categories
WHERE parent = $1
UNION ALL
SELECT
c.id,
c.parent,
c.title,
c.level,
ct.depth + 1
FROM categories c
INNER JOIN category_tree ct ON c.parent = ct.id
)
SELECT id, parent, title, level, depth
FROM category_tree
ORDER BY depth, title`
rows, err := db.QueryContext(ctx, query, req.ParentUUID)
if err != nil {
utils.RespondError(w, http.StatusInternalServerError, "Database query failed")
return
}
defer rows.Close()
// 构建分类树结构
type CategoryWithDepth struct {
model.Category
Depth int `json:"depth"`
}
categories := make([]CategoryWithDepth, 0)
for rows.Next() {
var cat CategoryWithDepth
if err := rows.Scan(&cat.Id, &cat.Parent, &cat.Title, &cat.Level, &cat.Depth); err != nil {
utils.RespondError(w, http.StatusInternalServerError, "Data scanning failed")
return
}
categories = append(categories, cat)
}
if err = rows.Err(); err != nil {
utils.RespondError(w, http.StatusInternalServerError, "Row iteration error")
return
}
utils.RespondJSON(w, http.StatusOK, categories)
}
如果需要构建树形结构返回,可以添加以下函数:
func BuildCategoryTree(categories []CategoryWithDepth) []map[string]interface{} {
// 按父级分组
childrenMap := make(map[uuid.UUID][]map[string]interface{})
for _, cat := range categories {
node := map[string]interface{}{
"id": cat.Id,
"title": cat.Title,
"level": cat.Level,
}
childrenMap[cat.Parent] = append(childrenMap[cat.Parent], node)
}
// 递归构建树
var buildTree func(parentID uuid.UUID) []map[string]interface{}
buildTree = func(parentID uuid.UUID) []map[string]interface{} {
children := childrenMap[parentID]
for i := range children {
children[i]["children"] = buildTree(children[i]["id"].(uuid.UUID))
}
return children
}
return buildTree(uuid.Nil) // 从根节点开始
}
对于产品分类关联,可以这样查询:
func GetProductsByCategory(db *sql.DB, categoryID uuid.UUID) ([]model.Product, error) {
query := `
WITH RECURSIVE category_hierarchy AS (
SELECT id FROM categories WHERE id = $1
UNION ALL
SELECT c.id FROM categories c
INNER JOIN category_hierarchy ch ON c.parent = ch.id
)
SELECT p.* FROM products p
INNER JOIN product_categories pc ON p.id = pc.product_id
WHERE pc.category_id IN (SELECT id FROM category_hierarchy)`
rows, err := db.Query(query, categoryID)
if err != nil {
return nil, err
}
defer rows.Close()
var products []model.Product
for rows.Next() {
var p model.Product
if err := rows.Scan(&p.ID, &p.Name, &p.Price, &p.Description); err != nil {
return nil, err
}
products = append(products, p)
}
return products, nil
}
这个实现提供了完整的递归分类查询,包含深度信息,并支持产品与分类的关联查询。

