diff --git a/.golangci.yml b/.golangci.yml index d1eabb7..b10f451 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,7 +5,7 @@ run: - .pb.go issues: - new: true + new: false linters: enable: diff --git a/handler/admin/post.go b/handler/admin/post.go index 5d8f883..c2e0c29 100644 --- a/handler/admin/post.go +++ b/handler/admin/post.go @@ -2,6 +2,7 @@ package admin import ( "errors" + "net/http" "strconv" "github.com/gin-gonic/gin" @@ -271,10 +272,18 @@ func (p *PostHandler) DeletePostBatch(ctx *gin.Context) (interface{}, error) { return nil, p.PostService.DeleteBatch(ctx, postIDs) } -func (p *PostHandler) PreviewPost(ctx *gin.Context) (interface{}, error) { +func (p *PostHandler) PreviewPost(ctx *gin.Context) { postID, err := util.ParamInt32(ctx, "postID") if err != nil { - return nil, err + 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 } - return p.PostService.Preview(ctx, postID) + ctx.String(http.StatusOK, previewPath) } diff --git a/handler/content/archive.go b/handler/content/archive.go index ef3ddd8..c394c56 100644 --- a/handler/content/archive.go +++ b/handler/content/archive.go @@ -5,6 +5,7 @@ import ( "github.com/gin-gonic/gin" + "github.com/go-sonic/sonic/cache" "github.com/go-sonic/sonic/consts" "github.com/go-sonic/sonic/handler/content/model" "github.com/go-sonic/sonic/model/entity" @@ -12,6 +13,7 @@ import ( "github.com/go-sonic/sonic/service/assembler" "github.com/go-sonic/sonic/template" "github.com/go-sonic/sonic/util" + "github.com/go-sonic/sonic/util/xerr" ) type ArchiveHandler struct { @@ -21,6 +23,7 @@ type ArchiveHandler struct { CategoryService service.CategoryService PostAssembler assembler.PostAssembler PostModel *model.PostModel + Cache cache.Cache } func NewArchiveHandler( @@ -30,6 +33,7 @@ func NewArchiveHandler( postCategoryService service.PostCategoryService, postAssembler assembler.PostAssembler, postModel *model.PostModel, + cache cache.Cache, ) *ArchiveHandler { return &ArchiveHandler{ OptionService: optionService, @@ -38,6 +42,7 @@ func NewArchiveHandler( CategoryService: categoryService, PostAssembler: postAssembler, PostModel: postModel, + Cache: cache, } } @@ -82,3 +87,44 @@ func (a *ArchiveHandler) ArchivesBySlug(ctx *gin.Context, model template.Model) token, _ := ctx.Cookie("authentication") return a.PostModel.Content(ctx, post, token, model) } + +// AdminArchivesBySlug It can only be used in the console to preview articles +func (a *ArchiveHandler) AdminArchivesBySlug(ctx *gin.Context, model template.Model) (string, error) { + slug, err := util.ParamString(ctx, "slug") + if err != nil { + return "", err + } + token, err := util.MustGetQueryString(ctx, "token") + if err != nil { + return "", err + } + if token == "" { + return "", nil + } + _, ok := a.Cache.Get(token) + if !ok { + return "", xerr.WithStatus(nil, xerr.StatusBadRequest).WithMsg("token已过期或者不存在") + } + + postPermalinkType, err := a.OptionService.GetPostPermalinkType(ctx) + if err != nil { + return "", err + } + var post *entity.Post + if postPermalinkType == consts.PostPermalinkTypeDefault { + post, err = a.PostService.GetBySlug(ctx, slug) + if err != nil { + return "", err + } + } else if postPermalinkType == consts.PostPermalinkTypeID { + postID, err := strconv.ParseInt(slug, 10, 32) + if err != nil { + return "", err + } + post, err = a.PostService.GetByPostID(ctx, int32(postID)) + if err != nil { + return "", err + } + } + return a.PostModel.AdminPreview(ctx, post, "", model) +} diff --git a/handler/content/model/post.go b/handler/content/model/post.go index 8c77a1c..f61d747 100644 --- a/handler/content/model/post.go +++ b/handler/content/model/post.go @@ -214,3 +214,78 @@ func (p *PostModel) Archives(ctx context.Context, page int, model template.Model model["meta_description"] = seoDescription return p.ThemeService.Render(ctx, "archives") } + +func (p *PostModel) AdminPreview(ctx context.Context, post *entity.Post, token string, model template.Model) (string, error) { + if post == nil { + return "", xerr.WithStatus(nil, int(xerr.StatusBadRequest)).WithMsg("查询不到文章信息") + } + + postVO, err := p.PostAssembler.ConvertToDetailVO(ctx, post) + if err != nil { + return "", err + } + model["post"] = postVO + + prevPosts, err := p.PostService.GetPrevPosts(ctx, post, 1) + if err != nil { + return "", err + } + nextPosts, err := p.PostService.GetNextPosts(ctx, post, 1) + if err != nil { + return "", err + } + if len(prevPosts) > 0 { + prePost, err := p.PostAssembler.ConvertToDetailVO(ctx, prevPosts[0]) + if err != nil { + return "", err + } + model["prevPost"] = prePost + } + if len(nextPosts) > 0 { + nextPost, err := p.PostAssembler.ConvertToDetailVO(ctx, nextPosts[0]) + if err != nil { + return "", err + } + model["nextPost"] = nextPost + } + + categories, err := p.PostCategoryService.ListCategoryByPostID(ctx, post.ID) + if err != nil { + return "", err + } + model["categories"], _ = p.CategoryService.ConvertToCategoryDTOs(ctx, categories) + + tags, err := p.PostTagService.ListTagByPostID(ctx, post.ID) + if err != nil { + return "", err + } + model["tags"], _ = p.TagService.ConvertToDTOs(ctx, tags) + + metas, err := p.MetaService.GetPostMeta(ctx, post.ID) + if err != nil { + return "", err + } + model["metas"] = p.MetaService.ConvertToMetaDTOs(metas) + + if post.MetaDescription != "" { + model["meta_description"] = post.MetaDescription + } else { + model["meta_description"] = post.Summary + } + if post.MetaKeywords != "" { + model["meta_keywords"] = post.MetaKeywords + } else if len(tags) > 0 { + metaKeywords := strings.Builder{} + metaKeywords.Write([]byte(tags[0].Name)) + for _, tag := range tags[1:] { + metaKeywords.Write([]byte(",")) + metaKeywords.Write([]byte(tag.Name)) + } + model["meta_keywords"] = metaKeywords.String() + } + model["is_post"] = true + + model["target"] = postVO + model["type"] = "post" + return p.ThemeService.Render(ctx, "post") +} diff --git a/handler/router.go b/handler/router.go index 7290319..c2fe279 100644 --- a/handler/router.go +++ b/handler/router.go @@ -110,7 +110,7 @@ func (s *Server) RegisterRouters() { postRouter.PUT("/:postID/status/draft/content", s.wrapHandler(s.PostHandler.UpdatePostDraft)) postRouter.DELETE("/:postID", s.wrapHandler(s.PostHandler.DeletePost)) postRouter.DELETE("", s.wrapHandler(s.PostHandler.DeletePostBatch)) - postRouter.GET("/:postID/preview", s.wrapHandler(s.PostHandler.PreviewPost)) + postRouter.GET("/:postID/preview", s.PostHandler.PreviewPost) { postCommentRouter := postRouter.Group("/comments") postCommentRouter.GET("", s.wrapHandler(s.PostCommentHandler.ListPostComment)) @@ -406,7 +406,7 @@ func (s *Server) registerDynamicRouters(contentRouter *gin.RouterGroup) error { contentRouter.GET(journalPath, s.wrapHTMLHandler(s.ContentJournalHandler.Journals)) contentRouter.GET(journalPath+"/page/:page", s.wrapHTMLHandler(s.ContentJournalHandler.JournalsPage)) - + contentRouter.GET("admin_preview/"+archivePath+"/:slug", s.wrapHTMLHandler(s.ArchiveHandler.AdminArchivesBySlug)) if sheetPermaLinkType == consts.SheetPermaLinkTypeRoot { contentRouter.GET("/:slug") } else { diff --git a/service/impl/log.go b/service/impl/log.go index 281d30d..3b5cd73 100644 --- a/service/impl/log.go +++ b/service/impl/log.go @@ -2,6 +2,7 @@ package impl import ( "context" + "gorm.io/gorm" "github.com/go-sonic/sonic/dal" diff --git a/service/impl/post.go b/service/impl/post.go index a16d369..3fe7b8f 100644 --- a/service/impl/post.go +++ b/service/impl/post.go @@ -231,7 +231,7 @@ func (p postServiceImpl) Preview(ctx context.Context, postID int32) (string, err if err != nil { return "", err } - previewURL.WriteString("/") + previewURL.WriteString("/admin_preview") previewURL.WriteString(fullPath) previewURL.WriteString("?token=") previewURL.WriteString(token)