added new category error, and some fixes
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package restricted
|
package restricted
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||||
@@ -23,25 +25,33 @@ func NewMenuHandler() *MenuHandler {
|
|||||||
func MenuHandlerRoutes(r fiber.Router) fiber.Router {
|
func MenuHandlerRoutes(r fiber.Router) fiber.Router {
|
||||||
handler := NewMenuHandler()
|
handler := NewMenuHandler()
|
||||||
|
|
||||||
r.Get("/get-menu", handler.GetMenu)
|
r.Get("/get-category-tree", handler.GetCategoryTree)
|
||||||
r.Get("/get-top-menu", handler.GetTopMenu)
|
r.Get("/get-top-menu", handler.GetTopMenu)
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetMenu(c fiber.Ctx) error {
|
func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
lang_id, ok := c.Locals("langID").(uint)
|
||||||
if !ok {
|
if !ok {
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
}
|
}
|
||||||
menu, err := h.menuService.GetMenu(lang_id)
|
|
||||||
|
root_category_id_attribute := c.Query("root_category_id")
|
||||||
|
root_category_id, err := strconv.Atoi(root_category_id_attribute)
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
||||||
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
||||||
|
}
|
||||||
|
|
||||||
|
category_tree, err := h.menuService.GetCategoryTree(uint(root_category_id), lang_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(response.Make(&menu, 0, i18n.T_(c, response.Message_OK)))
|
return c.JSON(response.Make(&category_tree, 0, i18n.T_(c, response.Message_OK)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
||||||
|
|||||||
@@ -93,16 +93,18 @@ type ScannedCategory struct {
|
|||||||
IsRoot uint `gorm:"column:is_root_category"`
|
IsRoot uint `gorm:"column:is_root_category"`
|
||||||
LinkRewrite string `gorm:"column:link_rewrite"`
|
LinkRewrite string `gorm:"column:link_rewrite"`
|
||||||
IsoCode string `gorm:"column:iso_code"`
|
IsoCode string `gorm:"column:iso_code"`
|
||||||
|
|
||||||
|
Visited bool //this is for internal backend use only
|
||||||
}
|
}
|
||||||
type Category struct {
|
type Category struct {
|
||||||
CategoryID uint `json:"category_id" form:"category_id"`
|
CategoryID uint `json:"category_id" form:"category_id"`
|
||||||
Label string `json:"label" form:"label"`
|
Label string `json:"label" form:"label"`
|
||||||
// Active bool `json:"active" form:"active"`
|
// Active bool `json:"active" form:"active"`
|
||||||
Params CategpryParams `json:"params" form:"params"`
|
Params CategoryParams `json:"params" form:"params"`
|
||||||
Children []Category `json:"children" form:"children"`
|
Children []Category `json:"children" form:"children"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CategpryParams struct {
|
type CategoryParams struct {
|
||||||
CategoryID uint `json:"category_id" form:"category_id"`
|
CategoryID uint `json:"category_id" form:"category_id"`
|
||||||
LinkRewrite string `json:"link_rewrite" form:"link_rewrite"`
|
LinkRewrite string `json:"link_rewrite" form:"link_rewrite"`
|
||||||
Locale string `json:"locale" form:"locale"`
|
Locale string `json:"locale" form:"locale"`
|
||||||
|
|||||||
@@ -37,12 +37,11 @@ func (r *CategoriesRepo) GetAllCategories(idLang uint) ([]model.ScannedCategory,
|
|||||||
ps_category_lang.link_rewrite AS link_rewrite,
|
ps_category_lang.link_rewrite AS link_rewrite,
|
||||||
ps_lang.iso_code AS iso_code
|
ps_lang.iso_code AS iso_code
|
||||||
`).
|
`).
|
||||||
Joins(`LEFT JOIN ? ON ??.id_category = ??.id_category AND ??.id_shop = ? AND ??.id_lang = ?`,
|
Joins(`LEFT JOIN `+categoryLangTbl+` ON `+categoryLangTbl+`.id_category = `+categoryTbl+`.id_category AND `+categoryLangTbl+`.id_shop = ? AND `+categoryLangTbl+`.id_lang = ?`,
|
||||||
categoryLangTbl, categoryLangTbl, categoryTbl, categoryLangTbl, constdata.SHOP_ID, categoryLangTbl, idLang).
|
constdata.SHOP_ID, idLang).
|
||||||
Joins(`LEFT JOIN ? ON ??.id_category = ??.id_category AND ??.id_shop = ?`,
|
Joins(`LEFT JOIN `+categoryShopTbl+` ON `+categoryShopTbl+`.id_category = `+categoryTbl+`.id_category AND `+categoryShopTbl+`.id_shop = ?`,
|
||||||
categoryShopTbl, categoryShopTbl, categoryTbl, categoryShopTbl, constdata.SHOP_ID).
|
constdata.SHOP_ID).
|
||||||
Joins(`JOIN ? ON ??.id_lang = ??.id_lang`,
|
Joins(`JOIN ` + langTbl + ` ON ` + langTbl + `.id_lang = ` + categoryLangTbl + `.id_lang`).
|
||||||
langTbl, langTbl, categoryLangTbl).
|
|
||||||
Scan(&allCategories).Error
|
Scan(&allCategories).Error
|
||||||
|
|
||||||
return allCategories, err
|
return allCategories, err
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func (r *ProductDescriptionRepo) GetProductDescription(productID uint, productid
|
|||||||
var ProductDescription model.ProductDescription
|
var ProductDescription model.ProductDescription
|
||||||
|
|
||||||
err := db.Get().
|
err := db.Get().
|
||||||
|
Model(dbmodel.PsProductLang{}).
|
||||||
Where(&dbmodel.PsProductLang{
|
Where(&dbmodel.PsProductLang{
|
||||||
IDProduct: int32(productID),
|
IDProduct: int32(productID),
|
||||||
IDShop: int32(constdata.SHOP_ID),
|
IDShop: int32(constdata.SHOP_ID),
|
||||||
@@ -50,6 +51,7 @@ func (r *ProductDescriptionRepo) CreateIfDoesNotExist(productID uint, productid_
|
|||||||
}
|
}
|
||||||
|
|
||||||
err := db.Get().
|
err := db.Get().
|
||||||
|
Model(dbmodel.PsProductLang{}).
|
||||||
Where(&dbmodel.PsProductLang{
|
Where(&dbmodel.PsProductLang{
|
||||||
IDProduct: int32(productID),
|
IDProduct: int32(productID),
|
||||||
IDShop: int32(constdata.SHOP_ID),
|
IDShop: int32(constdata.SHOP_ID),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func New() *MenuService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
func (s *MenuService) GetCategoryTree(root_category_id uint, id_lang uint) (*model.Category, error) {
|
||||||
all_categories, err := s.categoriesRepo.GetAllCategories(id_lang)
|
all_categories, err := s.categoriesRepo.GetAllCategories(id_lang)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &model.Category{}, err
|
return &model.Category{}, err
|
||||||
@@ -31,7 +31,7 @@ func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
|||||||
root_index := 0
|
root_index := 0
|
||||||
root_found := false
|
root_found := false
|
||||||
for i := 0; i < len(all_categories); i++ {
|
for i := 0; i < len(all_categories); i++ {
|
||||||
if all_categories[i].IsRoot == 1 {
|
if all_categories[i].CategoryID == root_category_id {
|
||||||
root_index = i
|
root_index = i
|
||||||
root_found = true
|
root_found = true
|
||||||
break
|
break
|
||||||
@@ -44,6 +44,7 @@ func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
|||||||
// now create the children and reorder them according to position
|
// now create the children and reorder them according to position
|
||||||
id_to_index := make(map[uint]int)
|
id_to_index := make(map[uint]int)
|
||||||
for i := 0; i < len(all_categories); i++ {
|
for i := 0; i < len(all_categories); i++ {
|
||||||
|
all_categories[i].Visited = false
|
||||||
id_to_index[all_categories[i].CategoryID] = i
|
id_to_index[all_categories[i].CategoryID] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,19 +59,32 @@ func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// finally, create the tree
|
// finally, create the tree
|
||||||
tree := s.createTree(root_index, &all_categories, &children_indices)
|
tree, success := s.createTree(root_index, &all_categories, &children_indices)
|
||||||
|
if !success {
|
||||||
|
return &tree, responseErrors.ErrCircularDependency
|
||||||
|
}
|
||||||
|
|
||||||
return &tree, nil
|
return &tree, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCategory), children_indices *(map[int][]ChildWithPosition)) model.Category {
|
func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCategory), children_indices *(map[int][]ChildWithPosition)) (model.Category, bool) {
|
||||||
node := s.scannedToNormalCategory((*all_categories)[index])
|
node := s.scannedToNormalCategory((*all_categories)[index])
|
||||||
|
|
||||||
|
if (*all_categories)[index].Visited {
|
||||||
|
return node, false
|
||||||
|
}
|
||||||
|
(*all_categories)[index].Visited = true
|
||||||
|
|
||||||
for i := 0; i < len((*children_indices)[index]); i++ {
|
for i := 0; i < len((*children_indices)[index]); i++ {
|
||||||
node.Children = append(node.Children, s.createTree((*children_indices)[index][i].Index, all_categories, children_indices))
|
next_child, success := s.createTree((*children_indices)[index][i].Index, all_categories, children_indices)
|
||||||
|
if !success {
|
||||||
|
return node, false
|
||||||
|
}
|
||||||
|
node.Children = append(node.Children, next_child)
|
||||||
}
|
}
|
||||||
|
|
||||||
return node
|
(*all_categories)[index].Visited = false // just in case we have a "diamond" diagram
|
||||||
|
return node, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
|
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
|
||||||
@@ -83,7 +97,7 @@ func (s *MenuService) scannedToNormalCategory(scanned model.ScannedCategory) mod
|
|||||||
normal.CategoryID = scanned.CategoryID
|
normal.CategoryID = scanned.CategoryID
|
||||||
normal.Label = scanned.Name
|
normal.Label = scanned.Name
|
||||||
// normal.Active = scanned.Active == 1
|
// normal.Active = scanned.Active == 1
|
||||||
normal.Params = model.CategpryParams{CategoryID: normal.CategoryID, LinkRewrite: scanned.LinkRewrite, Locale: scanned.IsoCode}
|
normal.Params = model.CategoryParams{CategoryID: normal.CategoryID, LinkRewrite: scanned.LinkRewrite, Locale: scanned.IsoCode}
|
||||||
normal.Children = []model.Category{}
|
normal.Children = []model.Category{}
|
||||||
return normal
|
return normal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ var (
|
|||||||
|
|
||||||
// Typed errors for menu handler
|
// Typed errors for menu handler
|
||||||
ErrNoRootFound = errors.New("no root found in categories table")
|
ErrNoRootFound = errors.New("no root found in categories table")
|
||||||
|
ErrCircularDependency = errors.New("circular dependency structure in tree (could be caused by improper root id)")
|
||||||
|
|
||||||
// Typed errors for carts handler
|
// Typed errors for carts handler
|
||||||
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
ErrMaxAmtOfCartsReached = errors.New("maximal amount of carts reached")
|
||||||
@@ -145,6 +146,8 @@ func GetErrorCode(c fiber.Ctx, err error) string {
|
|||||||
|
|
||||||
case errors.Is(err, ErrNoRootFound):
|
case errors.Is(err, ErrNoRootFound):
|
||||||
return i18n.T_(c, "error.no_root_found")
|
return i18n.T_(c, "error.no_root_found")
|
||||||
|
case errors.Is(err, ErrCircularDependency):
|
||||||
|
return i18n.T_(c, "error.circular_dependency")
|
||||||
|
|
||||||
case errors.Is(err, ErrMaxAmtOfCartsReached):
|
case errors.Is(err, ErrMaxAmtOfCartsReached):
|
||||||
return i18n.T_(c, "error.max_amt_of_carts_reached")
|
return i18n.T_(c, "error.max_amt_of_carts_reached")
|
||||||
@@ -189,6 +192,7 @@ func GetErrorStatus(err error) int {
|
|||||||
errors.Is(err, ErrInvalidXHTML),
|
errors.Is(err, ErrInvalidXHTML),
|
||||||
errors.Is(err, ErrBadPaging),
|
errors.Is(err, ErrBadPaging),
|
||||||
errors.Is(err, ErrNoRootFound),
|
errors.Is(err, ErrNoRootFound),
|
||||||
|
errors.Is(err, ErrCircularDependency),
|
||||||
errors.Is(err, ErrMaxAmtOfCartsReached),
|
errors.Is(err, ErrMaxAmtOfCartsReached),
|
||||||
errors.Is(err, ErrUserHasNoSuchCart),
|
errors.Is(err, ErrUserHasNoSuchCart),
|
||||||
errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
errors.Is(err, ErrProductOrItsVariationDoesNotExist):
|
||||||
|
|||||||
57
bo/components.d.ts
vendored
Normal file
57
bo/components.d.ts
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
// oxlint-disable
|
||||||
|
// ------
|
||||||
|
// Generated by unplugin-vue-components
|
||||||
|
// Read more: https://github.com/vuejs/core/pull/3399
|
||||||
|
|
||||||
|
export {}
|
||||||
|
|
||||||
|
/* prettier-ignore */
|
||||||
|
declare module 'vue' {
|
||||||
|
export interface GlobalComponents {
|
||||||
|
CartDetails: typeof import('./src/components/customer/CartDetails.vue')['default']
|
||||||
|
CategoryMenu: typeof import('./src/components/inner/categoryMenu.vue')['default']
|
||||||
|
CategoryMenuListing: typeof import('./src/components/inner/categoryMenuListing.vue')['default']
|
||||||
|
Cs_PrivacyPolicyView: typeof import('./src/components/terms/cs_PrivacyPolicyView.vue')['default']
|
||||||
|
Cs_TermsAndConditionsView: typeof import('./src/components/terms/cs_TermsAndConditionsView.vue')['default']
|
||||||
|
En_PrivacyPolicyView: typeof import('./src/components/terms/en_PrivacyPolicyView.vue')['default']
|
||||||
|
En_TermsAndConditionsView: typeof import('./src/components/terms/en_TermsAndConditionsView.vue')['default']
|
||||||
|
LangSwitch: typeof import('./src/components/inner/langSwitch.vue')['default']
|
||||||
|
PageAddresses: typeof import('./src/components/customer/PageAddresses.vue')['default']
|
||||||
|
PageCarts: typeof import('./src/components/customer/PageCarts.vue')['default']
|
||||||
|
PageOrders: typeof import('./src/components/customer/PageOrders.vue')['default']
|
||||||
|
PageProduct: typeof import('./src/components/customer/PageProduct.vue')['default']
|
||||||
|
PageProducts: typeof import('./src/components/admin/PageProducts.vue')['default']
|
||||||
|
PageProfileDetails: typeof import('./src/components/customer/PageProfileDetails.vue')['default']
|
||||||
|
PageProfileDetailsAddInfo: typeof import('./src/components/customer/PageProfileDetailsAddInfo.vue')['default']
|
||||||
|
PageStatistic: typeof import('./src/components/customer/PageStatistic.vue')['default']
|
||||||
|
Pl_PrivacyPolicyView: typeof import('./src/components/terms/pl_PrivacyPolicyView.vue')['default']
|
||||||
|
Pl_TermsAndConditionsView: typeof import('./src/components/terms/pl_TermsAndConditionsView.vue')['default']
|
||||||
|
ProductCustomization: typeof import('./src/components/customer/components/ProductCustomization.vue')['default']
|
||||||
|
ProductDetailView: typeof import('./src/components/admin/ProductDetailView.vue')['default']
|
||||||
|
ProductVariants: typeof import('./src/components/customer/components/ProductVariants.vue')['default']
|
||||||
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
ThemeSwitch: typeof import('./src/components/inner/themeSwitch.vue')['default']
|
||||||
|
TopBar: typeof import('./src/components/TopBar.vue')['default']
|
||||||
|
TopBarLogin: typeof import('./src/components/TopBarLogin.vue')['default']
|
||||||
|
UAlert: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Alert.vue')['default']
|
||||||
|
UButton: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Button.vue')['default']
|
||||||
|
UCard: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default']
|
||||||
|
UCheckbox: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default']
|
||||||
|
UDrawer: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Drawer.vue')['default']
|
||||||
|
UForm: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Form.vue')['default']
|
||||||
|
UFormField: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default']
|
||||||
|
UIcon: typeof import('./node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default']
|
||||||
|
UInput: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default']
|
||||||
|
UInputNumber: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/InputNumber.vue')['default']
|
||||||
|
UModal: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default']
|
||||||
|
UNavigationMenu: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/NavigationMenu.vue')['default']
|
||||||
|
UPagination: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Pagination.vue')['default']
|
||||||
|
USelect: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Select.vue')['default']
|
||||||
|
USelectMenu: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/SelectMenu.vue')['default']
|
||||||
|
UTable: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Table.vue')['default']
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
info:
|
info:
|
||||||
name: get-menu
|
name: get-category-tree
|
||||||
type: http
|
type: http
|
||||||
seq: 5
|
seq: 5
|
||||||
|
|
||||||
http:
|
http:
|
||||||
method: GET
|
method: GET
|
||||||
url: http://localhost:3000/api/v1/restricted/menu/get-menu?lang_id=1
|
url: http://localhost:3000/api/v1/restricted/menu/get-category-tree?root_category_id=3
|
||||||
params:
|
params:
|
||||||
- name: lang_id
|
- name: root_category_id
|
||||||
value: "1"
|
value: "3"
|
||||||
type: query
|
type: query
|
||||||
auth: inherit
|
auth: inherit
|
||||||
|
|
||||||
22
bruno/b2b-daniel/get-product-description.yml
Normal file
22
bruno/b2b-daniel/get-product-description.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
info:
|
||||||
|
name: get-product-description
|
||||||
|
type: http
|
||||||
|
seq: 17
|
||||||
|
|
||||||
|
http:
|
||||||
|
method: GET
|
||||||
|
url: http://localhost:3000/api/v1/restricted/product-translation/get-product-description?productID=51&productLangID=2
|
||||||
|
params:
|
||||||
|
- name: productID
|
||||||
|
value: "51"
|
||||||
|
type: query
|
||||||
|
- name: productLangID
|
||||||
|
value: "2"
|
||||||
|
type: query
|
||||||
|
auth: inherit
|
||||||
|
|
||||||
|
settings:
|
||||||
|
encodeUrl: true
|
||||||
|
timeout: 0
|
||||||
|
followRedirects: true
|
||||||
|
maxRedirects: 5
|
||||||
Reference in New Issue
Block a user