Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfc488bad8 | ||
|
|
f5f23f8a27 | ||
| cffe4c2f83 | |||
| 15e8626280 |
4
.env
4
.env
@@ -25,6 +25,9 @@ AUTH_REFRESH_EXPIRATION=604800
|
|||||||
MEILISEARCH_URL=http://localhost:7700
|
MEILISEARCH_URL=http://localhost:7700
|
||||||
MEILISEARCH_API_KEY=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
MEILISEARCH_API_KEY=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||||
|
|
||||||
|
# OpenAI
|
||||||
|
OPENAI_KEY=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
|
||||||
|
|
||||||
# Google Translate Client
|
# Google Translate Client
|
||||||
GOOGLE_APPLICATION_CREDENTIALS=./google-cred.json
|
GOOGLE_APPLICATION_CREDENTIALS=./google-cred.json
|
||||||
GOOGLE_CLOUD_PROJECT_ID=translation-343517
|
GOOGLE_CLOUD_PROJECT_ID=translation-343517
|
||||||
@@ -33,6 +36,7 @@ GOOGLE_CLOUD_PROJECT_ID=translation-343517
|
|||||||
OAUTH_GOOGLE_CLIENT_ID=331979954218-9vrpe08oqhhcgj6bvu6d4lds0dt630m9.apps.googleusercontent.com
|
OAUTH_GOOGLE_CLIENT_ID=331979954218-9vrpe08oqhhcgj6bvu6d4lds0dt630m9.apps.googleusercontent.com
|
||||||
OAUTH_GOOGLE_CLIENT_SECRET=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
|
OAUTH_GOOGLE_CLIENT_SECRET=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
|
||||||
OAUTH_GOOGLE_REDIRECT_URL=http://localhost:3000/api/v1/public/auth/google/callback
|
OAUTH_GOOGLE_REDIRECT_URL=http://localhost:3000/api/v1/public/auth/google/callback
|
||||||
|
|
||||||
# Email Configuration (SMTP)
|
# Email Configuration (SMTP)
|
||||||
# Set EMAIL_ENABLED=true to require email verification
|
# Set EMAIL_ENABLED=true to require email verification
|
||||||
EMAIL_ENABLED=true
|
EMAIL_ENABLED=true
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package restricted
|
package restricted
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/listProductsService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/listProductsService"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||||
@@ -52,13 +50,13 @@ func (h *ListProductsHandler) GetListing(c fiber.Ctx) error {
|
|||||||
// "override_currency": c.Query("override_currency", ""),
|
// "override_currency": c.Query("override_currency", ""),
|
||||||
// }
|
// }
|
||||||
|
|
||||||
id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2"))
|
id_lang, ok := c.Locals("langID").(uint)
|
||||||
if err != nil {
|
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)))
|
||||||
}
|
}
|
||||||
|
|
||||||
listing, err := h.listProductsService.GetListing(uint(id_lang), paging, filters)
|
listing, err := h.listProductsService.GetListing(id_lang, paging, filters)
|
||||||
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)))
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package restricted
|
package restricted
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/service/meiliService"
|
"git.ma-al.com/goc_daniel/b2b/app/service/meiliService"
|
||||||
"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"
|
||||||
@@ -32,13 +30,13 @@ func MeiliSearchHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
||||||
id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2"))
|
id_lang, ok := c.Locals("langID").(uint)
|
||||||
if err != nil {
|
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)))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.meiliService.CreateIndex(uint(id_lang))
|
err := h.meiliService.CreateIndex(id_lang)
|
||||||
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)))
|
||||||
@@ -49,13 +47,13 @@ func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *MeiliSearchHandler) Test(c fiber.Ctx) error {
|
func (h *MeiliSearchHandler) Test(c fiber.Ctx) error {
|
||||||
id_lang, err := strconv.Atoi(c.Cookies("lang_id", "2"))
|
id_lang, ok := c.Locals("langID").(uint)
|
||||||
if err != nil {
|
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)))
|
||||||
}
|
}
|
||||||
|
|
||||||
test, err := h.meiliService.Test(uint(id_lang))
|
test, err := h.meiliService.Test(id_lang)
|
||||||
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)))
|
||||||
|
|||||||
@@ -24,33 +24,18 @@ func MenuHandlerRoutes(r fiber.Router) fiber.Router {
|
|||||||
handler := NewMenuHandler()
|
handler := NewMenuHandler()
|
||||||
|
|
||||||
r.Get("/get-menu", handler.GetMenu)
|
r.Get("/get-menu", handler.GetMenu)
|
||||||
r.Get("/get-routes", handler.GetRouting)
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MenuHandler) GetMenu(c fiber.Ctx) error {
|
func (h *MenuHandler) GetMenu(c fiber.Ctx) error {
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
id_lang, 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)
|
|
||||||
if err != nil {
|
menu, err := h.menuService.GetMenu(id_lang)
|
||||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(response.Make(&menu, 0, i18n.T_(c, response.Message_OK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *MenuHandler) GetRouting(c fiber.Ctx) error {
|
|
||||||
lang_id, ok := c.Locals("langID").(uint)
|
|
||||||
if !ok {
|
|
||||||
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
|
|
||||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
|
|
||||||
}
|
|
||||||
menu, err := h.menuService.GetRoutes(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)))
|
||||||
|
|||||||
@@ -110,10 +110,6 @@ func (s *Server) Setup() error {
|
|||||||
meiliSearch := s.restricted.Group("/meili-search")
|
meiliSearch := s.restricted.Group("/meili-search")
|
||||||
restricted.MeiliSearchHandlerRoutes(meiliSearch)
|
restricted.MeiliSearchHandlerRoutes(meiliSearch)
|
||||||
|
|
||||||
s.api.All("*", func(c fiber.Ctx) error {
|
|
||||||
return c.SendStatus(fiber.StatusNotFound)
|
|
||||||
})
|
|
||||||
|
|
||||||
// // Restricted routes example
|
// // Restricted routes example
|
||||||
// restricted := s.api.Group("/restricted")
|
// restricted := s.api.Group("/restricted")
|
||||||
// restricted.Use(middleware.AuthMiddleware())
|
// restricted.Use(middleware.AuthMiddleware())
|
||||||
|
|||||||
@@ -19,10 +19,26 @@ type ProductDescription struct {
|
|||||||
Usage string `gorm:"column:usage;type:text" json:"usage" form:"usage"`
|
Usage string `gorm:"column:usage;type:text" json:"usage" form:"usage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MeiliSearchProduct struct {
|
type ProductRow struct {
|
||||||
ProductID uint
|
IDProduct int `gorm:"column:id_product"`
|
||||||
Name string
|
IDShop int `gorm:"column:id_shop"`
|
||||||
Description string
|
Name string `gorm:"column:name"`
|
||||||
DescriptionShort string
|
Active uint8 `gorm:"column:active"`
|
||||||
Usage string
|
Reference string `gorm:"column:reference"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MeiliSearchProduct struct {
|
||||||
|
ProductID uint `gorm:"column:id_product"`
|
||||||
|
Name string `gorm:"column:name"`
|
||||||
|
Active uint8 `gorm:"column:active"`
|
||||||
|
Price float64 `gorm:"column:price"`
|
||||||
|
Description string `gorm:"column:description"`
|
||||||
|
DescriptionShort string `gorm:"column:description_short"`
|
||||||
|
Usage string `gorm:"column:usage"`
|
||||||
|
EAN13 string `gorm:"column:ean13"`
|
||||||
|
Reference string `gorm:"column:reference"`
|
||||||
|
Width float64 `gorm:"column:width"`
|
||||||
|
Height float64 `gorm:"column:height"`
|
||||||
|
Depth float64 `gorm:"column:depth"`
|
||||||
|
Weight float64 `gorm:"column:weight"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type Route struct {
|
|
||||||
ID uint `gorm:"primaryKey;autoIncrement"`
|
|
||||||
Name string `gorm:"type:varchar(255);not null;unique"`
|
|
||||||
Path *string `gorm:"type:varchar(255);default:null"`
|
|
||||||
Component string `gorm:"type:varchar(255);not null;comment:path to component file"`
|
|
||||||
Layout *string `gorm:"type:varchar(50);default:'default';comment:'default | empty'"`
|
|
||||||
Meta *string `gorm:"type:longtext;default:'{}'"`
|
|
||||||
IsActive *bool `gorm:"type:tinyint;default:1"`
|
|
||||||
SortOrder *int `gorm:"type:int;default:0"`
|
|
||||||
|
|
||||||
ParentID *uint `gorm:"index"`
|
|
||||||
Parent *Route `gorm:"constraint:OnUpdate:RESTRICT,OnDelete:SET NULL;foreignKey:ParentID"`
|
|
||||||
|
|
||||||
Children []Route `gorm:"foreignKey:ParentID"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (Route) TableName() string {
|
|
||||||
return "b2b_routes"
|
|
||||||
}
|
|
||||||
@@ -12,6 +12,7 @@ type UIProductDescriptionRepo interface {
|
|||||||
GetProductDescription(productID uint, productLangID uint) (*model.ProductDescription, error)
|
GetProductDescription(productID uint, productLangID uint) (*model.ProductDescription, error)
|
||||||
CreateIfDoesNotExist(productID uint, productLangID uint) error
|
CreateIfDoesNotExist(productID uint, productLangID uint) error
|
||||||
UpdateFields(productID uint, productLangID uint, updates map[string]string) error
|
UpdateFields(productID uint, productLangID uint, updates map[string]string) error
|
||||||
|
GetMeiliProducts(id_lang uint) ([]model.MeiliSearchProduct, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductDescriptionRepo struct{}
|
type ProductDescriptionRepo struct{}
|
||||||
@@ -73,3 +74,35 @@ func (r *ProductDescriptionRepo) UpdateFields(productID uint, productLangID uint
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We assume that any user has access to all product descriptions
|
||||||
|
func (r *ProductDescriptionRepo) GetMeiliProducts(id_lang uint) ([]model.MeiliSearchProduct, error) {
|
||||||
|
var products []model.MeiliSearchProduct
|
||||||
|
|
||||||
|
err := db.DB.
|
||||||
|
Select("pl.`usage` AS `usage`").
|
||||||
|
Select(`
|
||||||
|
ps.id_product AS id_product,
|
||||||
|
pl.name AS name,
|
||||||
|
ps.active AS active,
|
||||||
|
ps.price AS price,
|
||||||
|
pl.description AS description,
|
||||||
|
pl.description_short AS description_short,
|
||||||
|
p.ean13 AS ean13,
|
||||||
|
p.reference AS reference,
|
||||||
|
p.width AS width,
|
||||||
|
p.height AS height,
|
||||||
|
p.depth AS depth,
|
||||||
|
p.weight AS weight
|
||||||
|
`).
|
||||||
|
Table("ps_product_shop AS ps").
|
||||||
|
Joins("LEFT JOIN ps_product_lang AS pl ON ps.id_product = pl.id_product AND pl.id_shop = ? AND pl.id_lang = ?", constdata.SHOP_ID, id_lang).
|
||||||
|
Joins("LEFT JOIN ps_product AS p ON p.id_product = ps.id_product").
|
||||||
|
Where("ps.id_shop = ?", constdata.SHOP_ID).
|
||||||
|
Scan(&products).Error
|
||||||
|
if err != nil {
|
||||||
|
return products, fmt.Errorf("database error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return products, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package routesrepo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/db"
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UIRoutesRepo interface {
|
|
||||||
GetRoutes(langId uint) ([]model.Route, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RoutesRepo struct{}
|
|
||||||
|
|
||||||
func New() UIRoutesRepo {
|
|
||||||
return &RoutesRepo{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *RoutesRepo) GetRoutes(langId uint) ([]model.Route, error) {
|
|
||||||
routes := []model.Route{}
|
|
||||||
err := db.DB.Find(&routes).Error
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return routes, nil
|
|
||||||
}
|
|
||||||
8
app/service/meiliService/blank.json
Normal file
8
app/service/meiliService/blank.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"products-openai": {
|
||||||
|
"source": "openAi",
|
||||||
|
"model": "text-embedding-3-small",
|
||||||
|
"apiKey": "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",
|
||||||
|
"documentTemplate": "{{doc.Name}} is equipment used for {{doc.Description | truncatewords: 20}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,13 +9,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/db"
|
"git.ma-al.com/goc_daniel/b2b/app/repos/productDescriptionRepo"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
|
||||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||||
"github.com/meilisearch/meilisearch-go"
|
"github.com/meilisearch/meilisearch-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MeiliService struct {
|
type MeiliService struct {
|
||||||
|
productDescriptionRepo productDescriptionRepo.UIProductDescriptionRepo
|
||||||
meiliClient meilisearch.ServiceManager
|
meiliClient meilisearch.ServiceManager
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,56 +30,41 @@ func New() *MeiliService {
|
|||||||
|
|
||||||
return &MeiliService{
|
return &MeiliService{
|
||||||
meiliClient: client,
|
meiliClient: client,
|
||||||
|
productDescriptionRepo: productDescriptionRepo.New(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================================== FOR SUPERADMIN ONLY ====================================
|
// ==================================== FOR SUPERADMIN ONLY ====================================
|
||||||
func (s *MeiliService) CreateIndex(id_lang uint) error {
|
func (s *MeiliService) CreateIndex(id_lang uint) error {
|
||||||
var products []model.ProductDescription
|
products, err := s.productDescriptionRepo.GetMeiliProducts(id_lang)
|
||||||
|
|
||||||
err := db.DB.
|
|
||||||
Table("ps_product_lang").
|
|
||||||
Where("id_shop = ? AND id_lang = ?", constdata.SHOP_ID, id_lang).
|
|
||||||
Scan(&products).Error
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("database error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var meiliProducts []model.MeiliSearchProduct
|
|
||||||
for i := 0; i < len(products); i++ {
|
for i := 0; i < len(products); i++ {
|
||||||
var nextMeiliProduct model.MeiliSearchProduct
|
products[i].Description, err = cleanHTML(products[i].Description)
|
||||||
|
|
||||||
nextMeiliProduct.ProductID = products[i].ProductID
|
|
||||||
nextMeiliProduct.Name = products[i].Name
|
|
||||||
|
|
||||||
nextMeiliProduct.Description, err = cleanHTML(products[i].Description)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("nextMeiliProduct.Description: %v\n", nextMeiliProduct.Description)
|
fmt.Printf("products[i].Description: %v\n", products[i].Description)
|
||||||
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
||||||
fmt.Println("failed at description")
|
fmt.Println("failed at description")
|
||||||
fmt.Printf("err: %v\n", err)
|
fmt.Printf("err: %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nextMeiliProduct.DescriptionShort, err = cleanHTML(products[i].DescriptionShort)
|
products[i].DescriptionShort, err = cleanHTML(products[i].DescriptionShort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("nextMeiliProduct.DescriptionShort: %v\n", nextMeiliProduct.DescriptionShort)
|
fmt.Printf("products[i].DescriptionShort: %v\n", products[i].DescriptionShort)
|
||||||
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
||||||
fmt.Println("failed at description short")
|
fmt.Println("failed at description short")
|
||||||
fmt.Printf("err: %v\n", err)
|
fmt.Printf("err: %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nextMeiliProduct.Usage, err = cleanHTML(products[i].Usage)
|
products[i].Usage, err = cleanHTML(products[i].Usage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("nextMeiliProduct.Usage: %v\n", nextMeiliProduct.Usage)
|
fmt.Printf("products[i].Usage: %v\n", products[i].Usage)
|
||||||
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
fmt.Printf("products[i].ProductID: %v\n", products[i].ProductID)
|
||||||
fmt.Println("failed at usage")
|
fmt.Println("failed at usage")
|
||||||
fmt.Printf("err: %v\n", err)
|
fmt.Printf("err: %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
meiliProducts = append(meiliProducts, nextMeiliProduct)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indexName := "meili_products_shop" + strconv.FormatInt(constdata.SHOP_ID, 10) + "_lang" + strconv.FormatInt(int64(id_lang), 10)
|
indexName := "meili_products_shop" + strconv.FormatInt(constdata.SHOP_ID, 10) + "_lang" + strconv.FormatInt(int64(id_lang), 10)
|
||||||
@@ -89,7 +74,7 @@ func (s *MeiliService) CreateIndex(id_lang uint) error {
|
|||||||
SkipCreation: false,
|
SkipCreation: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
task, err := s.meiliClient.Index(indexName).AddDocuments(meiliProducts, docOptions)
|
task, err := s.meiliClient.Index(indexName).AddDocuments(products, docOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("meili AddDocuments error: %w", err)
|
return fmt.Errorf("meili AddDocuments error: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,26 +5,23 @@ import (
|
|||||||
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/repos/categoriesRepo"
|
"git.ma-al.com/goc_daniel/b2b/app/repos/categoriesRepo"
|
||||||
routesRepo "git.ma-al.com/goc_daniel/b2b/app/repos/routesRepo"
|
|
||||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MenuService struct {
|
type MenuService struct {
|
||||||
categoriesRepo categoriesRepo.UICategoriesRepo
|
categoriesRepo categoriesRepo.UICategoriesRepo
|
||||||
routesRepo routesRepo.UIRoutesRepo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *MenuService {
|
func New() *MenuService {
|
||||||
return &MenuService{
|
return &MenuService{
|
||||||
categoriesRepo: categoriesRepo.New(),
|
categoriesRepo: categoriesRepo.New(),
|
||||||
routesRepo: routesRepo.New(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
func (s *MenuService) GetMenu(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
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the root
|
// find the root
|
||||||
@@ -38,7 +35,7 @@ func (s *MenuService) GetMenu(id_lang uint) (*model.Category, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !root_found {
|
if !root_found {
|
||||||
return &model.Category{}, responseErrors.ErrNoRootFound
|
return model.Category{}, responseErrors.ErrNoRootFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// now create the children and reorder them according to position
|
// now create the children and reorder them according to position
|
||||||
@@ -60,7 +57,7 @@ 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 := s.createTree(root_index, &all_categories, &children_indices)
|
||||||
|
|
||||||
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 {
|
||||||
@@ -73,10 +70,6 @@ func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCate
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
|
|
||||||
return s.routesRepo.GetRoutes(id_lang)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *MenuService) scannedToNormalCategory(scanned model.ScannedCategory) model.Category {
|
func (s *MenuService) scannedToNormalCategory(scanned model.ScannedCategory) model.Category {
|
||||||
var normal model.Category
|
var normal model.Category
|
||||||
// normal.Active = scanned.Active
|
// normal.Active = scanned.Active
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func New() *ProductDescriptionService {
|
|||||||
log.Fatalf("productDescriptionService: cannot create Translation client: %v", err)
|
log.Fatalf("productDescriptionService: cannot create Translation client: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
openAIClient := openai.NewClient(option.WithAPIKey("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"),
|
openAIClient := openai.NewClient(option.WithAPIKey(os.Getenv("OPENAI_KEY")),
|
||||||
option.WithHTTPClient(&http.Client{Timeout: 300 * time.Second})) // five minutes timeout
|
option.WithHTTPClient(&http.Client{Timeout: 300 * time.Second})) // five minutes timeout
|
||||||
|
|
||||||
return &ProductDescriptionService{
|
return &ProductDescriptionService{
|
||||||
|
|||||||
@@ -2,19 +2,20 @@
|
|||||||
import TopBar from '@/components/TopBar.vue';
|
import TopBar from '@/components/TopBar.vue';
|
||||||
import { getMenu } from '@/router/menu'
|
import { getMenu } from '@/router/menu'
|
||||||
import type { NavigationMenuItem } from '@nuxt/ui';
|
import type { NavigationMenuItem } from '@nuxt/ui';
|
||||||
|
import { on } from 'events';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
let menu = await getMenu() as NavigationMenuItem[]
|
let menu = await getMenu() as NavigationMenuItem[]
|
||||||
|
|
||||||
const openAll = ref(false)
|
function adaptMenu(menu) {
|
||||||
|
|
||||||
function adaptMenu(menu: NavigationMenuItem[]) {
|
|
||||||
for (const item of menu) {
|
for (const item of menu) {
|
||||||
if(item.children && item.children.length > 0){
|
if (item.children && item.children.length > 0) {
|
||||||
console.log(item);
|
|
||||||
adaptMenu(item.children);
|
adaptMenu(item.children);
|
||||||
item.open = openAll.value
|
// item.children.unshift({ label: item.label, icon: 'i-lucide-book-open', popover: item.label ,to: { name: 'category', params: item.params }})
|
||||||
item.children.unshift({ label: item.label, icon: 'i-lucide-book-open', popover: item.label ,to: { name: 'category', params: item.params }})
|
// item.type = 'trigger'
|
||||||
|
// item.icon = 'i-lucide-book-open'
|
||||||
|
// item.onSelect(e){ console.log(e, 'adasdasdas'); }
|
||||||
} else {
|
} else {
|
||||||
|
// console.log(item.params);
|
||||||
item.to = { name: 'category', params: item.params };
|
item.to = { name: 'category', params: item.params };
|
||||||
item.icon = 'i-lucide-file-text'
|
item.icon = 'i-lucide-file-text'
|
||||||
}
|
}
|
||||||
@@ -22,12 +23,14 @@ function adaptMenu(menu: NavigationMenuItem[]) {
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
menu = adaptMenu(menu)
|
menu = adaptMenu(menu.children)
|
||||||
|
|
||||||
|
console.log(menu);
|
||||||
|
|
||||||
const items = ref<NavigationMenuItem[][]>([
|
const items = ref<NavigationMenuItem[][]>([
|
||||||
[
|
[
|
||||||
|
|
||||||
...menu as NavigationMenuItem[]
|
...menu
|
||||||
],
|
],
|
||||||
|
|
||||||
])
|
])
|
||||||
@@ -38,13 +41,15 @@ const items = ref<NavigationMenuItem[][]>([
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-screen grid grid-rows-[auto_1fr_auto]">
|
<div class="h-screen grid grid-rows-[auto_1fr_auto]">
|
||||||
<main class="p-10">
|
<main class="p-10">
|
||||||
<TopBar/>
|
<div class="mt-24 bg-accented w-1/5 rounded-2xl">
|
||||||
<div class="mt-24 w-1/4 bg-accented rounded-2xl">
|
<UNavigationMenu orientation="vertical" type="single" :items="items" class="p-4">
|
||||||
<button @click="openAll = !openAll">open all</button>
|
|
||||||
<UNavigationMenu arrow orientation="vertical" :items="items" class="p-4" :key="openAll">
|
|
||||||
</UNavigationMenu>
|
</UNavigationMenu>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <template #item>{{ item }}</template> -->
|
||||||
|
|
||||||
|
|
||||||
|
<TopBar/>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ function isAuthenticated(): boolean {
|
|||||||
|
|
||||||
|
|
||||||
await getSettings()
|
await getSettings()
|
||||||
const routes = await getMenu()
|
// await getMenu()
|
||||||
|
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@@ -1,16 +1,7 @@
|
|||||||
import { useFetchJson } from "@/composable/useFetchJson";
|
import { useFetchJson } from "@/composable/useFetchJson";
|
||||||
import type { MenuItem, Route } from "@/types/menu";
|
|
||||||
|
|
||||||
export const getMenu = async () => {
|
export const getMenu = async () => {
|
||||||
const resp = await useFetchJson<MenuItem>('/api/v1/restricted/menu/get-menu');
|
const resp = await useFetchJson('/api/v1/restricted/menu/get-menu');
|
||||||
|
|
||||||
return resp.items.children
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export const getRoutes = async () => {
|
|
||||||
const resp = await useFetchJson<Route[]>('/api/v1/restricted/menu/get-routes');
|
|
||||||
|
|
||||||
return resp.items
|
return resp.items
|
||||||
|
|
||||||
|
|||||||
26
bo/src/types/menu.d.ts
vendored
26
bo/src/types/menu.d.ts
vendored
@@ -1,26 +0,0 @@
|
|||||||
export interface MenuItem {
|
|
||||||
category_id: number
|
|
||||||
label: string
|
|
||||||
params: Params
|
|
||||||
children: MenuItem[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Params {
|
|
||||||
category_id?: number
|
|
||||||
link_rewrite?: string
|
|
||||||
locale?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Route {
|
|
||||||
ID: number
|
|
||||||
Name: string
|
|
||||||
Path: string
|
|
||||||
Component: string
|
|
||||||
Layout: string
|
|
||||||
Meta: string
|
|
||||||
IsActive: boolean
|
|
||||||
SortOrder: number
|
|
||||||
ParentID: any
|
|
||||||
Parent: any
|
|
||||||
Children: any
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
-- +goose Up
|
-- +goose Up
|
||||||
-- create routes table
|
-- create routes table
|
||||||
CREATE TABLE IF NOT EXISTS b2b_routes (
|
CREATE TABLE IF NOT EXISTS b2b_tracker_routes (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
name VARCHAR(255) NOT NULL UNIQUE,
|
name VARCHAR(255) NOT NULL UNIQUE,
|
||||||
path VARCHAR(255) NULL,
|
path VARCHAR(255) NULL,
|
||||||
@@ -13,11 +13,11 @@ CREATE TABLE IF NOT EXISTS b2b_routes (
|
|||||||
|
|
||||||
CONSTRAINT fk_parent
|
CONSTRAINT fk_parent
|
||||||
FOREIGN KEY (parent_id)
|
FOREIGN KEY (parent_id)
|
||||||
REFERENCES b2b_routes(id)
|
REFERENCES b2b_tracker_routes(id)
|
||||||
ON DELETE SET NULL
|
ON DELETE SET NULL
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
INSERT IGNORE INTO b2b_routes
|
INSERT IGNORE INTO b2b_tracker_routes
|
||||||
(name, path, component, layout, meta, is_active, sort_order, parent_id)
|
(name, path, component, layout, meta, is_active, sort_order, parent_id)
|
||||||
VALUES
|
VALUES
|
||||||
('root', '', '', 'default', '{"trans": "route.root"}', 0, 0, 0),
|
('root', '', '', 'default', '{"trans": "route.root"}', 0, 0, 0),
|
||||||
@@ -30,5 +30,5 @@ VALUES
|
|||||||
|
|
||||||
-- +goose Down
|
-- +goose Down
|
||||||
|
|
||||||
DROP TABLE IF EXISTS b2b_routes;
|
DROP TABLE IF EXISTS b2b_tracker_routes;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user