This commit is contained in:
215
backend_v1/app/http/admin/posts.go
Normal file
215
backend_v1/app/http/admin/posts.go
Normal file
@@ -0,0 +1,215 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"quyun/v2/app/requests"
|
||||
"quyun/v2/app/services"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/fields"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/samber/lo"
|
||||
"go.ipao.vip/gen"
|
||||
"go.ipao.vip/gen/types"
|
||||
)
|
||||
|
||||
type ListQuery struct {
|
||||
Keyword *string `query:"keyword"`
|
||||
}
|
||||
|
||||
// @provider
|
||||
type posts struct{}
|
||||
|
||||
// List posts
|
||||
//
|
||||
// @Router /admin/posts [get]
|
||||
// @Bind pagination query
|
||||
// @Bind query query
|
||||
func (ctl *posts) List(ctx fiber.Ctx, pagination *requests.Pagination, query *ListQuery) (*requests.Pager, error) {
|
||||
conds := []gen.Condition{
|
||||
models.PostQuery.Title.Like(*query.Keyword),
|
||||
}
|
||||
pager, err := services.Posts.List(ctx, pagination, conds...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
postIds := lo.Map(pager.Items.([]models.Post), func(item models.Post, _ int) int64 {
|
||||
return item.ID
|
||||
})
|
||||
if len(postIds) > 0 {
|
||||
postCntMap, err := services.Posts.BoughtStatistics(ctx, postIds)
|
||||
if err != nil {
|
||||
return pager, err
|
||||
}
|
||||
|
||||
items := lo.Map(pager.Items.([]models.Post), func(item models.Post, _ int) PostItem {
|
||||
cnt := int64(0)
|
||||
if v, ok := postCntMap[item.ID]; ok {
|
||||
cnt = v
|
||||
}
|
||||
|
||||
return PostItem{Post: &item, BoughtCount: cnt}
|
||||
})
|
||||
|
||||
pager.Items = items
|
||||
}
|
||||
return pager, err
|
||||
}
|
||||
|
||||
type PostForm struct {
|
||||
Title string `json:"title"`
|
||||
HeadImages []int64 `json:"head_images"`
|
||||
Price int64 `json:"price"`
|
||||
Discount int16 `json:"discount"`
|
||||
Introduction string `json:"introduction"`
|
||||
Medias []int64 `json:"medias"`
|
||||
Status fields.PostStatus `json:"status"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// Create
|
||||
//
|
||||
// @Router /admin/posts [post]
|
||||
// @Bind form body
|
||||
func (ctl *posts) Create(ctx fiber.Ctx, form *PostForm) error {
|
||||
post := models.Post{
|
||||
Title: form.Title,
|
||||
HeadImages: types.NewJSONType(form.HeadImages),
|
||||
Price: form.Price,
|
||||
Discount: form.Discount,
|
||||
Description: form.Introduction,
|
||||
Status: form.Status,
|
||||
Content: form.Content,
|
||||
Tags: types.NewJSONType([]string{}),
|
||||
Assets: types.NewJSONType([]fields.MediaAsset{}),
|
||||
}
|
||||
|
||||
if form.Medias != nil {
|
||||
medias, err := services.Medias.GetByIds(ctx, form.Medias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assets := lo.Map(medias, func(media *models.Media, _ int) fields.MediaAsset {
|
||||
return fields.MediaAsset{
|
||||
Type: media.MimeType,
|
||||
Media: media.ID,
|
||||
Metas: lo.ToPtr(media.Metas.Data()),
|
||||
}
|
||||
})
|
||||
post.Assets = types.NewJSONType(assets)
|
||||
}
|
||||
|
||||
if err := post.Create(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update posts
|
||||
//
|
||||
// @Router /admin/posts/:id [put]
|
||||
// @Bind id path
|
||||
// @Bind form body
|
||||
func (ctl *posts) Update(ctx fiber.Ctx, id int64, form *PostForm) error {
|
||||
post, err := services.Posts.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
post.Title = form.Title
|
||||
post.HeadImages = types.NewJSONType(form.HeadImages)
|
||||
post.Price = form.Price
|
||||
post.Discount = form.Discount
|
||||
post.Description = form.Introduction
|
||||
post.Status = form.Status
|
||||
post.Content = form.Content
|
||||
post.Tags = types.NewJSONType([]string{})
|
||||
|
||||
if form.Medias != nil {
|
||||
medias, err := services.Medias.GetByIds(ctx, form.Medias)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assets := lo.Map(medias, func(media *models.Media, _ int) fields.MediaAsset {
|
||||
return fields.MediaAsset{
|
||||
Type: media.MimeType,
|
||||
Media: media.ID,
|
||||
Metas: lo.ToPtr(media.Metas.Data()),
|
||||
}
|
||||
})
|
||||
post.Assets = types.NewJSONType(assets)
|
||||
}
|
||||
|
||||
if _, err := post.Update(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete posts
|
||||
//
|
||||
// @Router /admin/posts/:id [delete]
|
||||
// @Bind id path
|
||||
func (ctl *posts) Delete(ctx fiber.Ctx, id int64) error {
|
||||
post, err := services.Posts.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if post == nil {
|
||||
return fiber.ErrNotFound
|
||||
}
|
||||
|
||||
if _, err := post.ForceDelete(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PostItem struct {
|
||||
*models.Post
|
||||
Medias []*models.Media `json:"medias"`
|
||||
BoughtCount int64 `json:"bought_count"`
|
||||
}
|
||||
|
||||
// Show posts by id
|
||||
//
|
||||
// @Router /admin/posts/:id [get]
|
||||
// @Bind id path
|
||||
func (ctl *posts) Show(ctx fiber.Ctx, id int64) (*PostItem, error) {
|
||||
post, err := services.Posts.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
medias, err := services.Medias.GetByIds(ctx, lo.Map(post.Assets.Data(), func(asset fields.MediaAsset, _ int) int64 {
|
||||
return asset.Media
|
||||
}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PostItem{
|
||||
Post: post,
|
||||
Medias: medias,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SendTo
|
||||
//
|
||||
// @Router /admin/posts/:id/send-to/:userId [post]
|
||||
// @Bind id path
|
||||
// @Bind userId path
|
||||
func (ctl *posts) SendTo(ctx fiber.Ctx, id, userId int64) error {
|
||||
post, err := services.Posts.FindByID(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
user, err := services.Users.FindByID(ctx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := services.Posts.SendTo(ctx, post.ID, user.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user