This commit is contained in:
2025-03-03 13:49:36 +01:00
parent 016b54f8dd
commit c7b10d24be
7 changed files with 147 additions and 71 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"example.com/gin/test/models" "example.com/gin/test/models"
//"example.com/gin/test/services"
"example.com/gin/test/repositories" "example.com/gin/test/repositories"
) )
@@ -24,6 +25,8 @@ type ShopItemController interface {
ShopItemView(*gin.Context) ShopItemView(*gin.Context)
AddItemView(*gin.Context) AddItemView(*gin.Context)
AddItemHandler(*gin.Context) AddItemHandler(*gin.Context)
CreateTag(*gin.Context)
GetAllTags(*gin.Context)
} }
type shopItemController struct {} type shopItemController struct {}
@@ -54,26 +57,60 @@ func (rc *shopItemController) GetById(c *gin.Context) {
ReplyOK(c, shopItem) ReplyOK(c, shopItem)
} }
func (rc *shopItemController) Create(c *gin.Context) { func (rc *shopItemController) NewShopItemFromForm(ctx *gin.Context) (models.ShopItem, error) {
shopItem, err := models.NewShopItem(c) name := ctx.PostForm("name")
abstract := ctx.PostForm("abstract")
description := ctx.PostForm("description")
priceStr := ctx.PostForm("price")
tagIds := ctx.PostFormArray("tags[]")
if err != nil { if name == "" || description == "" {
ReplyError(c, err) return models.ShopItem{}, fmt.Errorf("Name or description empty")
} }
_, err = repositories.ShopItems.Create(shopItem) // Convert the price string to float64
price, err := strconv.ParseFloat(priceStr, 64)
if err != nil {
return models.ShopItem{}, fmt.Errorf("Could not parse price")
}
shopItem := models.ShopItem{
Name: name,
Abstract: abstract,
Description: description,
Price: price,
IsPublic: true,
}
for _, tagId := range tagIds {
tag, err := repositories.Tags.GetById(tagId)
if err != nil {
return models.ShopItem{}, fmt.Errorf("Could not get tag by id")
}
shopItem.Tags = append(shopItem.Tags, tag)
}
return shopItem, nil
//return services.ShopItems.NewShopItem(name, abstract, description, price, tagIds)
}
func (rc *shopItemController) Create(c *gin.Context) {
shopItem, err := rc.NewShopItemFromForm(c)
if err != nil { if err != nil {
ReplyError(c, fmt.Errorf("shopItem creation failed: %s", err)) ReplyError(c, fmt.Errorf("shopItem creation failed: %s", err))
return return
} }
//userID := user.(models.User).ID _, err = repositories.ShopItems.Create(shopItem)
//rc.DB.Model(&models.shopItem{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID})
//if result.Error != nil { if err != nil {
// ReplyError(c, fmt.Errorf("shopItem creation failed: %s", result.Error)) ReplyError(c, fmt.Errorf("shopItem creation failed: %s", err))
// return return
//} }
ReplyOK(c, "shopItem was created") ReplyOK(c, "shopItem was created")
} }
@@ -87,7 +124,7 @@ func (rc *shopItemController) Update(c *gin.Context) {
return return
} }
shopItem, err := models.NewShopItem(c) shopItem, err := rc.NewShopItemFromForm(c)
if err != nil { if err != nil {
ReplyError(c, err) ReplyError(c, err)
@@ -119,8 +156,20 @@ func (rc *shopItemController) Delete(c *gin.Context) {
func (rc *shopItemController) ShopItemView(c *gin.Context) { func (rc *shopItemController) ShopItemView(c *gin.Context) {
shopItem, err := repositories.ShopItems.GetById(c.Param("id")) shopItem, err := repositories.ShopItems.GetById(c.Param("id"))
if err != nil {
c.HTML(http.StatusBadRequest, "shopitem.html", gin.H{ "data": gin.H{ "error": err } })
}
//TODO: get tags by item
tags, err := repositories.Tags.GetAll()
if err != nil {
c.HTML(http.StatusBadRequest, "shopitem.html", gin.H{ "data": gin.H{ "error": err } })
}
data := CreateSessionData(c, gin.H{ data := CreateSessionData(c, gin.H{
"shopItem": shopItem, "shopItem": shopItem,
"tags": tags,
}) })
if err != nil { if err != nil {
@@ -132,9 +181,16 @@ func (rc *shopItemController) ShopItemView(c *gin.Context) {
func (rc *shopItemController) AddItemView(c *gin.Context) { func (rc *shopItemController) AddItemView(c *gin.Context) {
tags, err := repositories.Tags.GetAll()
if err != nil {
c.HTML(http.StatusBadRequest, "additem.html", gin.H{ "error": err })
}
data := CreateSessionData(c, gin.H{ data := CreateSessionData(c, gin.H{
"error": "", "error": "",
"success": "", "success": "",
"tags": tags,
}) })
c.HTML(http.StatusOK, "additem.html", data) c.HTML(http.StatusOK, "additem.html", data)
@@ -142,10 +198,18 @@ func (rc *shopItemController) AddItemView(c *gin.Context) {
func (rc *shopItemController) AddItemHandler(c *gin.Context) { func (rc *shopItemController) AddItemHandler(c *gin.Context) {
shopItem, err := models.NewShopItem(c) shopItem, err := rc.NewShopItemFromForm(c)
if err != nil { if err != nil {
ReplyError(c, err) c.HTML(http.StatusBadRequest, "additem.html", gin.H{ "error": err })
return
}
tags, err := repositories.Tags.GetAll()
if err != nil {
c.HTML(http.StatusBadRequest, "additem.html", gin.H{ "error": err })
return
} }
_, err = repositories.ShopItems.Create(shopItem) _, err = repositories.ShopItems.Create(shopItem)
@@ -153,6 +217,7 @@ func (rc *shopItemController) AddItemHandler(c *gin.Context) {
data := CreateSessionData(c, gin.H{ data := CreateSessionData(c, gin.H{
"error": err, "error": err,
"success": "", "success": "",
"tags": tags,
}) })
c.HTML(http.StatusOK, "additem.html", data) c.HTML(http.StatusOK, "additem.html", data)
@@ -162,11 +227,48 @@ func (rc *shopItemController) AddItemHandler(c *gin.Context) {
data := CreateSessionData(c, gin.H{ data := CreateSessionData(c, gin.H{
"error": "", "error": "",
"success": fmt.Sprintf("Item '%s' Registered", shopItem.Name), "success": fmt.Sprintf("Item '%s' Registered", shopItem.Name),
"tags": tags,
}) })
c.HTML(http.StatusOK, "additem.html", data) c.HTML(http.StatusOK, "additem.html", data)
} }
func (rc *shopItemController) CreateTag(c *gin.Context) {
tag, err := models.NewTagByJson(c)
if err != nil {
ReplyError(c, err)
}
_, err = repositories.Tags.Create(tag)
if err != nil {
ReplyError(c, fmt.Errorf("shopItem creation failed: %s", err))
return
}
//userID := user.(models.User).ID
//rc.DB.Model(&models.shopItem{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID})
//if result.Error != nil {
// ReplyError(c, fmt.Errorf("shopItem creation failed: %s", result.Error))
// return
//}
ReplyOK(c, fmt.Sprintf("tag '%s' was created", tag.Name))
}
func (rc *shopItemController) GetAllTags(c *gin.Context) {
tags, err := repositories.Tags.GetAll()
if err != nil {
ReplyError(c, fmt.Errorf("Could not query Tags"))
return
}
c.JSON(http.StatusOK, tags)
}
func ReplyError(ctx *gin.Context, err error) { func ReplyError(ctx *gin.Context, err error) {
ctx.JSON(http.StatusBadRequest, gin.H{ "error": err.Error() }) ctx.JSON(http.StatusBadRequest, gin.H{ "error": err.Error() })
} }

View File

@@ -57,6 +57,8 @@ func main() {
apiRoutes := server.Group("/api") apiRoutes := server.Group("/api")
//apiRoutes.Use(middlewares.BasicAuth()) //apiRoutes.Use(middlewares.BasicAuth())
{ {
apiRoutes.POST("/tags", authValidator.RequireAuth, shopItemController.CreateTag)
apiRoutes.GET("/tags", authValidator.OptionalAuth, shopItemController.GetAllTags)
apiRoutes.POST("/shopitems", authValidator.RequireAuth, shopItemController.Create) apiRoutes.POST("/shopitems", authValidator.RequireAuth, shopItemController.Create)
apiRoutes.GET("/shopitems", authValidator.OptionalAuth, shopItemController.GetAll) apiRoutes.GET("/shopitems", authValidator.OptionalAuth, shopItemController.GetAll)
apiRoutes.GET("/shopitems/:id", authValidator.OptionalAuth, shopItemController.GetById) apiRoutes.GET("/shopitems/:id", authValidator.OptionalAuth, shopItemController.GetById)

View File

@@ -1,42 +1,17 @@
package models package models
import ( import (
"fmt"
"strconv"
"gorm.io/gorm" "gorm.io/gorm"
"github.com/gin-gonic/gin"
) )
type ShopItem struct { type ShopItem struct {
gorm.Model gorm.Model
Name string `json:"name" binding:"required" gorm:"unique;not null"` Name string `json:"name" binding:"required" gorm:"unique;not null"`
Abstract string `json:"Abstract" binding:"required"`
Description string `json:"description" binding:"required"` Description string `json:"description" binding:"required"`
Price float64 `json:"price" binding:"required"` Price float64 `json:"price" binding:"required"`
IsPublic bool `json:"isPublic" gorm:"default:true"` IsPublic bool `json:"isPublic" gorm:"default:true"`
Tags []Tag `gorm:"many2many:item_tags;"`
//Images gin.multipart.FileHeader `` //Images gin.multipart.FileHeader ``
} }
func NewShopItem(ctx *gin.Context) (ShopItem, error) {
name := ctx.PostForm("name")
description := ctx.PostForm("description")
priceStr := ctx.PostForm("price")
// Convert the price string to float64
price, err := strconv.ParseFloat(priceStr, 64)
if err != nil {
return ShopItem{}, fmt.Errorf("Could not parse price")
}
shopItem := ShopItem{
Name: name,
Description: description,
Price: price,
IsPublic: true,
}
if name == "" || description == "" {
return ShopItem{}, fmt.Errorf("Name or description empty")
}
return shopItem, nil
}

View File

@@ -11,6 +11,7 @@ import(
var( var(
ShopItems ShopItemRepository ShopItems ShopItemRepository
Users UserRepository Users UserRepository
Tags TagRepository
) )
func InitRepositories() { func InitRepositories() {
@@ -19,11 +20,12 @@ func InitRepositories() {
panic("failed to connect to database") panic("failed to connect to database")
} }
err = db.AutoMigrate(&models.ShopItem{}, &models.User{}, &models.Booking{}) err = db.AutoMigrate(&models.ShopItem{}, &models.User{}, &models.Tag{})
if err != nil { if err != nil {
panic("failed to migrate database") panic("failed to migrate database")
} }
ShopItems = NewGORMShopItemRepository(db) ShopItems = NewGORMShopItemRepository(db)
Users = NewGORMUserRepository(db) Users = NewGORMUserRepository(db)
Tags = NewGORMTagRepository(db)
} }

View File

@@ -12,6 +12,7 @@ type ShopItemRepository interface {
GetAll() ([]models.ShopItem, error) GetAll() ([]models.ShopItem, error)
GetAllPublic() ([]models.ShopItem, error) GetAllPublic() ([]models.ShopItem, error)
GetById(string) (models.ShopItem, error) GetById(string) (models.ShopItem, error)
//GetByTagId(string) ([]models.ShopItem, error)
Update(models.ShopItem) (models.ShopItem, error) Update(models.ShopItem) (models.ShopItem, error)
DeleteById(string) error DeleteById(string) error
} }
@@ -37,14 +38,14 @@ func (r *GORMShopItemRepository) Create(shopItem models.ShopItem) (models.ShopIt
func (r *GORMShopItemRepository) GetAll() ([]models.ShopItem, error) { func (r *GORMShopItemRepository) GetAll() ([]models.ShopItem, error) {
var shopItems []models.ShopItem var shopItems []models.ShopItem
result := r.DB.Find(&shopItems) result := r.DB.Preload("Tags").Find(&shopItems)
return shopItems, result.Error return shopItems, result.Error
} }
func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) { func (r *GORMShopItemRepository) GetAllPublic() ([]models.ShopItem, error) {
var shopItems []models.ShopItem var shopItems []models.ShopItem
result := r.DB.Where("is_public = 1").Find(&shopItems) result := r.DB.Preload("Tags").Where("is_public = 1").Find(&shopItems)
return shopItems, result.Error return shopItems, result.Error
@@ -58,7 +59,7 @@ func (r *GORMShopItemRepository) GetById(id string) (models.ShopItem, error) {
} }
var shopItem models.ShopItem var shopItem models.ShopItem
result := r.DB.First(&shopItem, uint(shopItemId)) result := r.DB.Preload("Tags").First(&shopItem, uint(shopItemId))
if result.Error != nil { if result.Error != nil {
return models.ShopItem{}, result.Error return models.ShopItem{}, result.Error

View File

@@ -1,7 +1,7 @@
package services package services
import( import(
"golang.org/x/crypto/bcrypt" "fmt"
"example.com/gin/test/models" "example.com/gin/test/models"
"example.com/gin/test/repositories" "example.com/gin/test/repositories"
@@ -13,20 +13,24 @@ var(
type ShopItemService struct {} type ShopItemService struct {}
func (u *ShopItemService) Create(name string, email string, password string) (models.User, error) { func (u *ShopItemService) NewShopItem(name string, abstract string, description string, price float64, tagIds []string) (models.ShopItem, error) {
//hash pw shopItem := models.ShopItem{
hash, err := bcrypt.GenerateFromPassword([]byte(password), 10) Name: name,
Abstract: abstract,
if err != nil { Description: description,
return models.User{}, err Price: price,
IsPublic: true,
} }
user := models.User{Name: name, Email: email, Password: string(hash)} for _, tagId := range tagIds {
_, err = repositories.Users.Create(user) tag, err := repositories.Tags.GetById(tagId)
if err != nil { if err != nil {
return models.User{}, err return models.ShopItem{}, fmt.Errorf("Could not get tag by id")
}
shopItem.Tags = append(shopItem.Tags, tag)
} }
return user, nil return repositories.ShopItems.Create(shopItem)
} }

View File

@@ -31,22 +31,12 @@
<div class="mb-4"> <div class="mb-4">
<label class="block text-sm/6 text-gray-900">Select Categories</label> <label class="block text-sm/6 text-gray-900">Select Categories</label>
<div class="space-y-2"> <div class="space-y-2">
{{ range .data.tags }}
<label class="flex text-sm/6 items-center"> <label class="flex text-sm/6 items-center">
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="tag1"> <input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="{{ .ID }}" name="tags[]">
<span class="ml-2 text-sm/6 text-gray-900">Feminism</span> <span class="ml-2 text-sm/6 text-gray-900">{{ .Name }}</span>
</label>
<label class="flex text-sm/6 items-center">
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="tag2">
<span class="ml-2 text-sm/6 text-gray-900">Anarchism</span>
</label>
<label class="flex text-sm/6 items-center">
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="tag3">
<span class="ml-2 text-sm/6 text-gray-900">Nihilism</span>
</label>
<label class="flex text-sm/6 items-center">
<input type="checkbox" class="form-checkbox h-4 w-4 text-gray-900" value="tag4">
<span class="ml-2 text-sm/6 text-gray-900">Syndicalism</span>
</label> </label>
{{ end }}
</div> </div>
</div> </div>