Add tree structure to categories API
Introduced a new method `GetTreeCategories` to provide a hierarchical structure for categories. Fixed typos in variable names and integrated utility functions for converting flat lists to nested dictionaries and vice versa. Added `TreeCategories` model for representing nested category structures.
This commit is contained in:
parent
25e131269d
commit
8c3541a892
@ -9,13 +9,14 @@ type Api struct {
|
|||||||
Client *client.Client
|
Client *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type IApi interface {
|
type Method interface {
|
||||||
GetParentCategories() ([]model.Category, error)
|
GetParentCategories() ([]model.Category, error)
|
||||||
GetCategories() ([]model.Category, error)
|
GetCategories() ([]model.Category, error)
|
||||||
|
GetTreeCategories() ([]model.TreeCategories, error)
|
||||||
GetProducts() ([]model.Product, error)
|
GetProducts() ([]model.Product, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApi(credentials client.Credentials) IApi {
|
func NewApi(credentials client.Credentials) Method {
|
||||||
return &Api{
|
return &Api{
|
||||||
Client: client.NewClient(credentials),
|
Client: client.NewClient(credentials),
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,26 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"gitea.24example.ru/spavelit/bpiek/model"
|
"gitea.24example.ru/spavelit/bpiek/model"
|
||||||
|
"gitea.24example.ru/spavelit/bpiek/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var categories []model.Category
|
var categories []model.Category
|
||||||
var parentCategories []model.Category
|
var parentCategories []model.Category
|
||||||
|
var treeCategories []model.TreeCategories
|
||||||
|
|
||||||
func (a *Api) GetCategories() ([]model.Category, error) {
|
func (a *Api) GetCategories() ([]model.Category, error) {
|
||||||
if len(categories) > 0 {
|
if len(categories) > 0 {
|
||||||
return categories, nil
|
return categories, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentCategoris, err := a.GetParentCategories()
|
parentCategories, err := a.GetParentCategories()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, category := range parentCategoris {
|
for _, category := range parentCategories {
|
||||||
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(category.Slug)
|
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(category.Slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -75,3 +76,36 @@ func (a *Api) GetCategoriesAndProductsBySlugParentCategory(slug string) (*model.
|
|||||||
|
|
||||||
return apiResponse.Result().(*model.CategoriesAndProductsBySlugParentCategoryResponse), nil
|
return apiResponse.Result().(*model.CategoriesAndProductsBySlugParentCategoryResponse), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Api) GetTreeCategories() ([]model.TreeCategories, error) {
|
||||||
|
if len(treeCategories) > 0 {
|
||||||
|
return treeCategories, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tree := map[string]interface{}{}
|
||||||
|
|
||||||
|
parentCategories, err := a.GetParentCategories()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, parent := range parentCategories {
|
||||||
|
tree[parent.Slug] = map[string]interface{}{
|
||||||
|
"name": parent.Name,
|
||||||
|
"slug": parent.Slug,
|
||||||
|
"url": parent.Url,
|
||||||
|
"children": map[string]interface{}{},
|
||||||
|
}
|
||||||
|
|
||||||
|
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(parent.Slug)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.ConvertListToNestedDict(categoriesAndProduct.Categories, tree)
|
||||||
|
}
|
||||||
|
|
||||||
|
treeCategories = utils.ConvertToNestedList(tree)
|
||||||
|
|
||||||
|
return treeCategories, nil
|
||||||
|
}
|
||||||
|
@ -10,13 +10,13 @@ func (a *Api) GetProducts() ([]model.Product, error) {
|
|||||||
return products, nil
|
return products, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentCategoris, err := a.GetParentCategories()
|
parentCategories, err := a.GetParentCategories()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, category := range parentCategoris {
|
for _, category := range parentCategories {
|
||||||
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(category.Slug)
|
categoriesAndProduct, err := a.GetCategoriesAndProductsBySlugParentCategory(category.Slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -6,3 +6,10 @@ type Category struct {
|
|||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
ApiUrl string `json:"apiUrl"`
|
ApiUrl string `json:"apiUrl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TreeCategories struct {
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Children []TreeCategories `json:"children"`
|
||||||
|
}
|
||||||
|
@ -30,8 +30,3 @@ type RemainsAndPlanresiduesResponse struct {
|
|||||||
Date string `json:"date"`
|
Date string `json:"date"`
|
||||||
Products []ShortProduct `json:"products"`
|
Products []ShortProduct `json:"products"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TreeCategoriesResponse struct {
|
|
||||||
Category
|
|
||||||
Children []Category `json:"children"`
|
|
||||||
}
|
|
||||||
|
81
utils/utils.go
Normal file
81
utils/utils.go
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitea.24example.ru/spavelit/bpiek/model"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func updateNested(d map[string]interface{}, keys []string, value map[string]interface{}) {
|
||||||
|
for _, key := range keys[:len(keys)-1] {
|
||||||
|
if _, exists := d[key]; !exists {
|
||||||
|
d[key] = map[string]interface{}{}
|
||||||
|
}
|
||||||
|
d = d[key].(map[string]interface{})
|
||||||
|
}
|
||||||
|
d[keys[len(keys)-1]] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertListToNestedDict(list []model.Category, tree map[string]interface{}) {
|
||||||
|
var tmpCategories []model.TreeCategories
|
||||||
|
for _, item := range list {
|
||||||
|
tmpCategories = append(tmpCategories, model.TreeCategories{
|
||||||
|
Name: item.Name,
|
||||||
|
Slug: item.Slug,
|
||||||
|
Url: item.Url,
|
||||||
|
Children: []model.TreeCategories{},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
idx := 0
|
||||||
|
for idx < len(tmpCategories) {
|
||||||
|
category := tmpCategories[idx]
|
||||||
|
if category.Url == "/" || category.Url == "" {
|
||||||
|
idx++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
paths := strings.Split(strings.Trim(category.Url, "/"), "/")
|
||||||
|
|
||||||
|
var strBuilder strings.Builder
|
||||||
|
for i, path := range paths {
|
||||||
|
if len(paths) == i+1 {
|
||||||
|
strBuilder.WriteString(path)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
strBuilder.WriteString(fmt.Sprintf("%s,children,", path))
|
||||||
|
}
|
||||||
|
updateNested(
|
||||||
|
tree,
|
||||||
|
strings.Split(strBuilder.String(), ","),
|
||||||
|
map[string]interface{}{
|
||||||
|
"name": category.Name,
|
||||||
|
"slug": category.Slug,
|
||||||
|
"url": category.Url,
|
||||||
|
"children": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
tmpCategories = append(tmpCategories[:idx], tmpCategories[idx+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertToNestedList(nestedDict map[string]interface{}) []model.TreeCategories {
|
||||||
|
var result []model.TreeCategories
|
||||||
|
|
||||||
|
for _, value := range nestedDict {
|
||||||
|
if valueMap, ok := value.(map[string]interface{}); ok {
|
||||||
|
childCategories := ConvertToNestedList(valueMap["children"].(map[string]interface{}))
|
||||||
|
|
||||||
|
category := model.TreeCategories{
|
||||||
|
Name: valueMap["name"].(string),
|
||||||
|
Slug: valueMap["slug"].(string),
|
||||||
|
Url: valueMap["url"].(string),
|
||||||
|
Children: childCategories,
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, category)
|
||||||
|
} else if category, ok := value.(model.TreeCategories); ok {
|
||||||
|
result = append(result, category)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user