package admin import ( "quyun/app/model" "quyun/app/requests" "quyun/database/fields" "github.com/gofiber/fiber/v3" "github.com/samber/lo" ) 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 := []model.Cond{ // conds.Post_NotDeleted(), // conds.Post_Status(fields.PostStatusPublished), model.PostsModel().CondLike(query.Keyword), } pager, err := model.PostsModel().List(ctx.Context(), pagination, conds...) if err != nil { return nil, err } postIds := lo.Map(pager.Items.([]model.Posts), func(item model.Posts, _ int) int64 { return item.ID }) if len(postIds) > 0 { postCntMap, err := model.PostsModel().BoughtStatistics(ctx.Context(), postIds) if err != nil { return pager, err } items := lo.Map(pager.Items.([]model.Posts), func(item model.Posts, _ int) PostItem { cnt := int64(0) if v, ok := postCntMap[item.ID]; ok { cnt = v } return PostItem{Posts: &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 := model.Posts{ Title: form.Title, HeadImages: fields.ToJson(form.HeadImages), Price: form.Price, Discount: form.Discount, Description: form.Introduction, Status: form.Status, Content: form.Content, Tags: fields.Json[[]string]{}, Assets: fields.Json[[]fields.MediaAsset]{}, } if form.Medias != nil { medias, err := model.MediasModel().GetByIds(ctx.Context(), form.Medias) if err != nil { return err } assets := lo.Map(medias, func(media *model.Medias, _ int) fields.MediaAsset { return fields.MediaAsset{ Type: media.MimeType, Media: media.ID, Metas: &media.Metas.Data, } }) post.Assets = fields.ToJson(assets) } if err := post.Create(ctx.Context()); 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 := model.PostsModel().GetByID(ctx.Context(), id) if err != nil { return err } post.Title = form.Title post.HeadImages = fields.ToJson(form.HeadImages) post.Price = form.Price post.Discount = form.Discount post.Description = form.Introduction post.Status = form.Status post.Content = form.Content post.Tags = fields.Json[[]string]{} if form.Medias != nil { medias, err := model.MediasModel().GetByIds(ctx.Context(), form.Medias) if err != nil { return err } assets := lo.Map(medias, func(media *model.Medias, _ int) fields.MediaAsset { return fields.MediaAsset{ Type: media.MimeType, Media: media.ID, Metas: &media.Metas.Data, } }) post.Assets = fields.ToJson(assets) } if err := post.Update(ctx.Context()); 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 := model.PostsModel().GetByID(ctx.Context(), id) if err != nil { return err } if post == nil { return fiber.ErrNotFound } if err := post.ForceDelete(ctx.Context()); err != nil { return err } return nil } type PostItem struct { *model.Posts Medias []*model.Medias `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 := model.PostsModel().GetByID(ctx.Context(), id) if err != nil { return nil, err } medias, err := model.MediasModel().GetByIds(ctx.Context(), lo.Map(post.Assets.Data, func(asset fields.MediaAsset, _ int) int64 { return asset.Media })) if err != nil { return nil, err } return &PostItem{ Posts: 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 := model.PostsModel().GetByID(ctx.Context(), id) if err != nil { return err } user, err := model.UsersModel().GetByID(ctx.Context(), userId) if err != nil { return err } if err := post.SendTo(ctx.Context(), user.ID); err != nil { return err } return nil }