feat: add some api for wordpress

pull/351/head
textworld 1 year ago
parent a314f691a8
commit 013b939ac7

@ -46,3 +46,7 @@ var (
BuildTime string
BuildCommit string
)
const (
LocalDateTimeFormat = "2006-01-02T15:04:05"
)

@ -27,7 +27,7 @@ func (c *CategoryHandler) List(ctx *gin.Context) (interface{}, error) {
return nil, err
}
categoryDTOList := make([]*wp.CategoryDTO, len(categoryEntities))
categoryDTOList := make([]*wp.CategoryDTO, 0, len(categoryEntities))
for _, categoryEntity := range categoryEntities {
categoryDTOList = append(categoryDTOList, convertToCategoryDTO(categoryEntity))
}

@ -7,5 +7,6 @@ func init() {
NewPostHandler,
NewUserHandler,
NewCategoryHandler,
NewTagHandler,
)
}

@ -3,13 +3,15 @@ package wp
import (
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/go-sonic/sonic/consts"
sonicconst "github.com/go-sonic/sonic/consts"
"github.com/go-sonic/sonic/log"
"github.com/go-sonic/sonic/model/dto/wp"
"github.com/go-sonic/sonic/model/entity"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util"
"github.com/go-sonic/sonic/util/xerr"
"strconv"
"strings"
"time"
)
@ -24,7 +26,81 @@ func NewPostHandler(postService service.PostService) *PostHandler {
}
}
func (handler *PostHandler) List(ctx *gin.Context) (interface{}, error) {
var wpPostQuery param.WpPostQuery
if err := ctx.ShouldBind(&wpPostQuery); err != nil {
return nil, util.WrapJsonBindErr(err)
}
var postQuery param.PostQuery
postQuery.PageSize = wpPostQuery.Page
postQuery.PageNum = wpPostQuery.PerPage
entities, _, err := handler.PostService.Page(ctx, postQuery)
if err != nil {
return nil, err
}
wpPostList := make([]*wp.PostDTO, 0, len(entities))
for _, postEntity := range entities {
wpPostList = append(wpPostList, convertToWpPost(postEntity))
}
return wpPostList, nil
}
func (handler *PostHandler) Create(ctx *gin.Context) (interface{}, error) {
postParam, err := parsePostParam(ctx)
if err != nil {
return nil, util.WrapJsonBindErr(err)
}
create, err := handler.PostService.Create(ctx, postParam)
if err != nil {
return nil, err
}
return convertToWpPost(create), nil
}
func (handler *PostHandler) Update(ctx *gin.Context) (interface{}, error) {
postParam, err := parsePostParam(ctx)
if err != nil {
return nil, util.WrapJsonBindErr(err)
}
postIDStr := ctx.Param("postID")
postID, err := strconv.ParseInt(postIDStr, 10, 32)
if err != nil {
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("Parameter error")
}
postDetail, err := handler.PostService.Update(ctx, int32(postID), postParam)
if err != nil {
return nil, err
}
return convertToWpPost(postDetail), nil
}
func (handler *PostHandler) Delete(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")
}
postEntity, err := handler.PostService.GetByPostID(ctx, int32(postID))
if err != nil {
return nil, err
}
if err = handler.PostService.Delete(ctx, int32(postID)); err != nil {
return nil, err
}
return convertToWpPost(postEntity), nil
}
func parsePostParam(ctx *gin.Context) (*param.Post, error) {
var wpPost param.WpPost
err := ctx.ShouldBindJSON(&wpPost)
if err != nil {
@ -37,37 +113,46 @@ func (handler *PostHandler) Create(ctx *gin.Context) (interface{}, error) {
}
log.CtxInfo(ctx, "wpPost: "+string(bytes))
postParam := convertToPostParam(&wpPost)
return convertToPostParam(&wpPost)
create, err := handler.PostService.Create(ctx, postParam)
if err != nil {
return nil, err
}
return convertToWpPost(create), nil
func convertToPostParam(wpPost *param.WpPost) (*param.Post, error) {
var paramPostStatus = sonicconst.PostStatusPublished
if strings.ToLower(wpPost.Status) == "draft" {
paramPostStatus = sonicconst.PostStatusDraft
}
func convertToPostParam(wpPost *param.WpPost) *param.Post {
var paramPostStatus = consts.PostStatusPublished
if strings.ToLower(wpPost.Content) == "draft" {
paramPostStatus = consts.PostStatusDraft
editorType := sonicconst.EditorTypeRichText
disallowComment := false
if strings.ToLower(wpPost.CommentStatus) == "closed" {
disallowComment = true
}
createTime := time.Now().Unix()
var createTime *int64
if strings.TrimSpace(wpPost.Date) != "" {
datetime, err := time.Parse(sonicconst.LocalDateTimeFormat, wpPost.Date)
if err != nil {
return nil, err
}
dateTimeMills := datetime.UnixMilli()
createTime = &dateTimeMills
}
return &param.Post{
Title: wpPost.Title,
Status: paramPostStatus,
Slug: wpPost.Slug,
EditorType: nil,
EditorType: &editorType,
OriginalContent: wpPost.Content,
Summary: "",
Thumbnail: "",
DisallowComment: false,
DisallowComment: disallowComment,
Password: wpPost.Password,
Template: "",
TopPriority: 0,
CreateTime: &createTime,
CreateTime: createTime,
MetaKeywords: "",
MetaDescription: "",
TagIDs: make([]int32, 0),
@ -76,7 +161,7 @@ func convertToPostParam(wpPost *param.WpPost) *param.Post {
Content: wpPost.Content,
EditTime: nil,
UpdateTime: nil,
}
}, nil
}
func convertToWpPost(postEntity *entity.Post) *wp.PostDTO {
@ -85,7 +170,7 @@ func convertToWpPost(postEntity *entity.Post) *wp.PostDTO {
var wpCommentStatus = "open"
var wpContent = make(map[string]interface{})
if postEntity.Status == consts.PostStatusDraft {
if postEntity.Status == sonicconst.PostStatusDraft {
wpStatus = "draft"
}
@ -102,15 +187,15 @@ func convertToWpPost(postEntity *entity.Post) *wp.PostDTO {
Guid: nil,
Id: postEntity.ID,
Link: "",
Modified: postEntity.UpdateTime.Format(timeFormat),
ModifiedGmt: postEntity.UpdateTime.UTC().Format(timeFormat),
Modified: "",
ModifiedGmt: "",
Slug: "",
Status: wpStatus,
Type: "post",
Password: "standard",
PermalinkTemplate: "",
GeneratedSlug: "",
Title: "",
Title: postEntity.Title,
Content: wpContent,
Author: 0,
Excerpt: nil,
@ -124,5 +209,10 @@ func convertToWpPost(postEntity *entity.Post) *wp.PostDTO {
Categories: make([]int32, 0),
Tags: make([]int32, 0),
}
if postEntity.UpdateTime != nil {
postDTO.Modified = postEntity.UpdateTime.Format(timeFormat)
postDTO.ModifiedGmt = postEntity.UpdateTime.UTC().Format(timeFormat)
}
return postDTO
}

@ -0,0 +1,53 @@
package wp
import (
"github.com/gin-gonic/gin"
"github.com/go-sonic/sonic/model/dto/wp"
"github.com/go-sonic/sonic/model/entity"
"github.com/go-sonic/sonic/model/param"
"github.com/go-sonic/sonic/service"
)
type TagHandler struct {
TagService service.TagService
}
func NewTagHandler(tagService service.TagService) *TagHandler {
return &TagHandler{
TagService: tagService,
}
}
func (handler *TagHandler) List(ctx *gin.Context) (interface{}, error) {
var err error
var listParam param.TagListParam
if err = ctx.ShouldBindJSON(&listParam); err != nil {
return nil, err
}
entities, err := handler.TagService.ListByOption(ctx, &listParam)
if err != nil {
return nil, err
}
tagDTOList := make([]*wp.TagDTO, 0, len(entities))
for _, tagEntity := range entities {
tagDTOList = append(tagDTOList, convertToWpTag(tagEntity))
}
return tagDTOList, nil
}
func convertToWpTag(tagEntity *entity.Tag) *wp.TagDTO {
tagDTO := &wp.TagDTO{
ID: tagEntity.ID,
Count: 0,
Description: "",
Link: "",
Name: tagEntity.Name,
Slug: tagEntity.Slug,
Taxonomy: "",
Meta: nil,
}
return tagDTO
}

@ -22,7 +22,7 @@ func (u *UserHandler) List(ctx *gin.Context) (interface{}, error) {
return nil, err
}
userDTOList := make([]*dto.User, len(allUser))
userDTOList := make([]*dto.User, 0, len(allUser))
for _, user := range allUser {
userDTO := u.UserService.ConvertToDTO(ctx, user)
userDTOList = append(userDTOList, userDTO)

@ -47,9 +47,21 @@ func (s *Server) RegisterRouters() {
{
wpCompatibleRouter := router.Group("/wp-json/wp/v2")
wpCompatibleRouter.Use(s.ApplicationPasswordMiddleware.GetWrapHandler())
wpCompatibleRouter.POST("/posts", s.wrapHandler(s.WpPostHandler.Create))
wpCompatibleRouter.GET("/users", s.wrapHandler(s.WpUserHandler.List))
wpCompatibleRouter.GET("/categories", s.wrapHandler(s.WpCategoryHandler.List))
{
wpCompatibleRouter.GET("/posts", s.wrapWpHandler(s.WpPostHandler.List))
wpCompatibleRouter.POST("/posts", s.wrapWpHandler(s.WpPostHandler.Create))
wpCompatibleRouter.POST("/posts/:postID", s.wrapWpHandler(s.WpPostHandler.Update))
wpCompatibleRouter.DELETE("/posts/:postID", s.wrapWpHandler(s.WpPostHandler.Delete))
}
{
wpCompatibleRouter.GET("/tags", s.wrapWpHandler(s.WpTagHandler.List))
}
{
wpCompatibleRouter.GET("/users", s.wrapWpHandler(s.WpUserHandler.List))
}
{
wpCompatibleRouter.GET("/categories", s.wrapWpHandler(s.WpCategoryHandler.List))
}
}
{
adminAPIRouter := router.Group("/api/admin")

@ -83,6 +83,7 @@ type Server struct {
WpPostHandler *wp.PostHandler
WpUserHandler *wp.UserHandler
WpCategoryHandler *wp.CategoryHandler
WpTagHandler *wp.TagHandler
}
type ServerParams struct {
@ -143,6 +144,7 @@ type ServerParams struct {
WpPostHandler *wp.PostHandler
WpUserHandler *wp.UserHandler
WpCategoryHandler *wp.CategoryHandler
WpTagHandler *wp.TagHandler
}
func NewServer(param ServerParams, lifecycle fx.Lifecycle) *Server {
@ -213,6 +215,7 @@ func NewServer(param ServerParams, lifecycle fx.Lifecycle) *Server {
WpPostHandler: param.WpPostHandler,
WpUserHandler: param.WpUserHandler,
WpCategoryHandler: param.WpCategoryHandler,
WpTagHandler: param.WpTagHandler,
}
lifecycle.Append(fx.Hook{
OnStop: httpServer.Shutdown,
@ -256,6 +259,21 @@ func (s *Server) wrapHandler(handler wrapperHandler) gin.HandlerFunc {
}
}
func (s *Server) wrapWpHandler(handler wrapperHandler) gin.HandlerFunc {
return func(ctx *gin.Context) {
data, err := handler(ctx)
if err != nil {
s.logger.Error("handler error", zap.Error(err))
status := xerr.GetHTTPStatus(err)
ctx.JSON(status, &dto.BaseWpDTO{Code: status, Message: xerr.GetMessage(err), Data: map[string]interface{}{"status": status}})
return
}
ctx.JSON(http.StatusOK, data)
return
}
}
type wrapperHTMLHandler func(ctx *gin.Context, model template.Model) (templateName string, err error)
var (

@ -14,6 +14,12 @@ type BaseDTO struct {
Data interface{} `json:"data"`
}
type BaseWpDTO struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
type Page struct {
Content interface{} `json:"content"`
Pages int `json:"pages"`

@ -0,0 +1,12 @@
package wp
type TagDTO struct {
ID int32 `json:"id"`
Count int32 `json:"count"`
Description string `json:"description"`
Link string `json:"link"`
Name string `json:"name"`
Slug string `json:"slug"`
Taxonomy string `json:"taxonomy"`
Meta map[string]interface{} `json:"meta"`
}

@ -28,3 +28,8 @@ type WpPost struct {
Categories []int32 `json:"categories"`
Tags []int32 `json:"tags"`
}
type WpPostQuery struct {
Page int `form:"page" default:"1"`
PerPage int `form:"per_page" default:"10"`
}

@ -0,0 +1,5 @@
package param
type TagListParam struct {
Search string `json:"search"`
}

@ -230,3 +230,19 @@ func (t tagServiceImpl) GetByName(ctx context.Context, name string) (*entity.Tag
tag, err := tagDAL.WithContext(ctx).Where(tagDAL.Name.Eq(name)).First()
return tag, WrapDBErr(err)
}
func (t tagServiceImpl) ListByOption(ctx context.Context, option *param.TagListParam) ([]*entity.Tag, error) {
tagDAL := dal.GetQueryByCtx(ctx).Tag
if option == nil {
return tagDAL.WithContext(ctx).Where().Find()
}
query := tagDAL.WithContext(ctx)
search := strings.TrimSpace(option.Search)
if search != "" {
query.Where(tagDAL.Name.Like("%" + search + "%"))
}
return query.Find()
}

@ -20,4 +20,5 @@ type TagService interface {
Update(ctx context.Context, id int32, tagParam *param.Tag) (*entity.Tag, error)
Delete(ctx context.Context, id int32) error
CountAllTag(ctx context.Context) (int64, error)
ListByOption(ctx context.Context, option *param.TagListParam) ([]*entity.Tag, error)
}

Loading…
Cancel
Save