You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sonic/handler/admin/post.go

290 lines
8.4 KiB
Go

package admin
import (
"errors"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/go-sonic/sonic/consts"
"github.com/go-sonic/sonic/handler/binding"
"github.com/go-sonic/sonic/handler/trans"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/service/assembler"
"github.com/go-sonic/sonic/util"
"github.com/go-sonic/sonic/util/xerr"
)
type PostHandler struct {
PostService service.PostService
PostAssembler assembler.PostAssembler
}
func NewPostHandler(postService service.PostService, postAssembler assembler.PostAssembler) *PostHandler {
return &PostHandler{
PostService: postService,
PostAssembler: postAssembler,
}
}
func (p *PostHandler) ListPosts(ctx *gin.Context) (interface{}, error) {
postQuery := param.PostQuery{}
err := ctx.ShouldBindWith(&postQuery, binding.CustomFormBinding)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
if postQuery.Sort == nil {
postQuery.Sort = &param.Sort{Fields: []string{"topPriority,desc", "createTime,desc"}}
}
posts, totalCount, err := p.PostService.Page(ctx, postQuery)
if err != nil {
return nil, err
}
if postQuery.More == nil || *postQuery.More {
postVOs, err := p.PostAssembler.ConvertToListVO(ctx, posts)
return dto.NewPage(postVOs, totalCount, postQuery.Page), err
}
postDTOs := make([]*dto.Post, 0)
for _, post := range posts {
postDTO, err := p.PostAssembler.ConvertToSimpleDTO(ctx, post)
if err != nil {
return nil, err
}
postDTOs = append(postDTOs, postDTO)
}
return dto.NewPage(postDTOs, totalCount, postQuery.Page), nil
}
func (p *PostHandler) ListLatestPosts(ctx *gin.Context) (interface{}, error) {
top, err := util.MustGetQueryInt32(ctx, "top")
if err != nil {
top = 10
}
postQuery := param.PostQuery{
Page: param.Page{
PageSize: int(top),
PageNum: 0,
},
Sort: &param.Sort{
Fields: []string{"createTime,desc"},
},
Keyword: nil,
CategoryID: nil,
More: util.BoolPtr(false),
}
posts, _, err := p.PostService.Page(ctx, postQuery)
if err != nil {
return nil, err
}
postMinimals := make([]*dto.PostMinimal, 0, len(posts))
for _, post := range posts {
postMinimal, err := p.PostAssembler.ConvertToMinimalDTO(ctx, post)
if err != nil {
return nil, err
}
postMinimals = append(postMinimals, postMinimal)
}
return postMinimals, nil
}
func (p *PostHandler) ListPostsByStatus(ctx *gin.Context) (interface{}, error) {
var postQuery param.PostQuery
err := ctx.ShouldBindWith(&postQuery, binding.CustomFormBinding)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
if postQuery.Sort == nil {
postQuery.Sort = &param.Sort{Fields: []string{"createTime,desc"}}
}
status, err := util.ParamInt32(ctx, "status")
if err != nil {
return nil, err
}
postQuery.Statuses = make([]*consts.PostStatus, 0)
statusType := consts.PostStatus(status)
postQuery.Statuses = append(postQuery.Statuses, &statusType)
posts, totalCount, err := p.PostService.Page(ctx, postQuery)
if err != nil {
return nil, err
}
if postQuery.More == nil {
*postQuery.More = false
}
if postQuery.More == nil {
postVOs, err := p.PostAssembler.ConvertToListVO(ctx, posts)
return dto.NewPage(postVOs, totalCount, postQuery.Page), err
}
postDTOs := make([]*dto.Post, 0)
for _, post := range posts {
postDTO, err := p.PostAssembler.ConvertToSimpleDTO(ctx, post)
if err != nil {
return nil, err
}
postDTOs = append(postDTOs, postDTO)
}
return dto.NewPage(postDTOs, totalCount, postQuery.Page), nil
}
func (p *PostHandler) GetByPostID(ctx *gin.Context) (interface{}, error) {
postIDStr := ctx.Param("postID")
postID, err := strconv.ParseInt(postIDStr, 10, 32)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
post, err := p.PostService.GetByPostID(ctx, int32(postID))
if err != nil {
return nil, err
}
postDetailVO, err := p.PostAssembler.ConvertToDetailVO(ctx, post)
if err != nil {
return nil, err
}
return postDetailVO, nil
}
func (p *PostHandler) CreatePost(ctx *gin.Context) (interface{}, error) {
var postParam param.Post
err := ctx.ShouldBindJSON(&postParam)
if err != nil {
e := validator.ValidationErrors{}
if errors.As(err, &e) {
return nil, xerr.WithStatus(e, xerr.StatusBadRequest).WithMsg(trans.Translate(e))
}
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("parameter error")
}
post, err := p.PostService.Create(ctx, &postParam)
if err != nil {
return nil, err
}
return p.PostAssembler.ConvertToDetailVO(ctx, post)
}
func (p *PostHandler) UpdatePost(ctx *gin.Context) (interface{}, error) {
var postParam param.Post
err := ctx.ShouldBindJSON(&postParam)
if err != nil {
e := validator.ValidationErrors{}
if errors.As(err, &e) {
return nil, xerr.WithStatus(e, xerr.StatusBadRequest).WithMsg(trans.Translate(e))
}
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("parameter error")
}
postIDStr := ctx.Param("postID")
postID, err := strconv.ParseInt(postIDStr, 10, 32)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
postDetailVO, err := p.PostService.Update(ctx, int32(postID), &postParam)
if err != nil {
return nil, err
}
return postDetailVO, nil
}
func (p *PostHandler) UpdatePostStatus(ctx *gin.Context) (interface{}, error) {
postIDStr := ctx.Param("postID")
postID, err := strconv.ParseInt(postIDStr, 10, 32)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
statusStr, err := util.ParamString(ctx, "status")
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
status, err := consts.PostStatusFromString(statusStr)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
if int32(status) < int32(consts.PostStatusPublished) || int32(status) > int32(consts.PostStatusIntimate) {
return nil, xerr.WithStatus(nil, xerr.StatusBadRequest).WithMsg("status error")
}
post, err := p.PostService.UpdateStatus(ctx, int32(postID), status)
if err != nil {
return nil, err
}
return p.PostAssembler.ConvertToMinimalDTO(ctx, post)
}
func (p *PostHandler) UpdatePostStatusBatch(ctx *gin.Context) (interface{}, error) {
statusStr, err := util.ParamString(ctx, "status")
if err != nil {
return nil, err
}
status, err := consts.PostStatusFromString(statusStr)
if err != nil {
return nil, err
}
if int32(status) < int32(consts.PostStatusPublished) || int32(status) > int32(consts.PostStatusIntimate) {
return nil, xerr.WithStatus(nil, xerr.StatusBadRequest).WithMsg("status error")
}
ids := make([]int32, 0)
err = ctx.ShouldBind(&ids)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("post ids error")
}
return p.PostService.UpdateStatusBatch(ctx, status, ids)
}
func (p *PostHandler) UpdatePostDraft(ctx *gin.Context) (interface{}, error) {
postID, err := util.ParamInt32(ctx, "postID")
if err != nil {
return nil, err
}
var postContentParam param.PostContent
err = ctx.ShouldBindJSON(&postContentParam)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("content param error")
}
post, err := p.PostService.UpdateDraftContent(ctx, postID, postContentParam.Content, postContentParam.OriginalContent)
if err != nil {
return nil, err
}
return p.PostAssembler.ConvertToDetailDTO(ctx, post)
}
func (p *PostHandler) DeletePost(ctx *gin.Context) (interface{}, error) {
postID, err := util.ParamInt32(ctx, "postID")
if err != nil {
return nil, err
}
return nil, p.PostService.Delete(ctx, postID)
}
func (p *PostHandler) DeletePostBatch(ctx *gin.Context) (interface{}, error) {
postIDs := make([]int32, 0)
err := ctx.ShouldBind(&postIDs)
if err != nil {
return nil, xerr.WithMsg(err, "postIDs error").WithStatus(xerr.StatusBadRequest)
}
return nil, p.PostService.DeleteBatch(ctx, postIDs)
}
func (p *PostHandler) PreviewPost(ctx *gin.Context) {
postID, err := util.ParamInt32(ctx, "postID")
if err != nil {
ctx.Status(http.StatusBadRequest)
_ = ctx.Error(err)
return
}
previewPath, err := p.PostService.Preview(ctx, postID)
if err != nil {
ctx.Status(http.StatusInternalServerError)
_ = ctx.Error(err)
return
}
ctx.String(http.StatusOK, previewPath)
}