init: 初始化 AssetX 项目仓库
包含 webapp(Next.js 用户端)、webapp-back(Go 后端)、 antdesign(管理后台)、landingpage(营销落地页)、 数据库 SQL 和配置文件。
This commit is contained in:
251
webapp-back/articles/routers.go
Normal file
251
webapp-back/articles/routers.go
Normal file
@@ -0,0 +1,251 @@
|
||||
package articles
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gothinkster/golang-gin-realworld-example-app/common"
|
||||
"github.com/gothinkster/golang-gin-realworld-example-app/users"
|
||||
"gorm.io/gorm"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ArticlesRegister(router *gin.RouterGroup) {
|
||||
router.GET("/feed", ArticleFeed)
|
||||
router.POST("", ArticleCreate)
|
||||
router.POST("/", ArticleCreate)
|
||||
router.PUT("/:slug", ArticleUpdate)
|
||||
router.PUT("/:slug/", ArticleUpdate)
|
||||
router.DELETE("/:slug", ArticleDelete)
|
||||
router.POST("/:slug/favorite", ArticleFavorite)
|
||||
router.DELETE("/:slug/favorite", ArticleUnfavorite)
|
||||
router.POST("/:slug/comments", ArticleCommentCreate)
|
||||
router.DELETE("/:slug/comments/:id", ArticleCommentDelete)
|
||||
}
|
||||
|
||||
func ArticlesAnonymousRegister(router *gin.RouterGroup) {
|
||||
router.GET("", ArticleList)
|
||||
router.GET("/", ArticleList)
|
||||
router.GET("/:slug", ArticleRetrieve)
|
||||
router.GET("/:slug/comments", ArticleCommentList)
|
||||
}
|
||||
|
||||
func TagsAnonymousRegister(router *gin.RouterGroup) {
|
||||
router.GET("", TagList)
|
||||
router.GET("/", TagList)
|
||||
}
|
||||
|
||||
func ArticleCreate(c *gin.Context) {
|
||||
articleModelValidator := NewArticleModelValidator()
|
||||
if err := articleModelValidator.Bind(c); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
|
||||
return
|
||||
}
|
||||
//fmt.Println(articleModelValidator.articleModel.Author.UserModel)
|
||||
|
||||
if err := SaveOne(&articleModelValidator.articleModel); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
serializer := ArticleSerializer{c, articleModelValidator.articleModel}
|
||||
c.JSON(http.StatusCreated, gin.H{"article": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleList(c *gin.Context) {
|
||||
//condition := ArticleModel{}
|
||||
tag := c.Query("tag")
|
||||
author := c.Query("author")
|
||||
favorited := c.Query("favorited")
|
||||
limit := c.Query("limit")
|
||||
offset := c.Query("offset")
|
||||
articleModels, modelCount, err := FindManyArticle(tag, author, limit, offset, favorited)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
|
||||
return
|
||||
}
|
||||
serializer := ArticlesSerializer{c, articleModels}
|
||||
c.JSON(http.StatusOK, gin.H{"articles": serializer.Response(), "articlesCount": modelCount})
|
||||
}
|
||||
|
||||
func ArticleFeed(c *gin.Context) {
|
||||
limit := c.Query("limit")
|
||||
offset := c.Query("offset")
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
if myUserModel.ID == 0 {
|
||||
c.AbortWithError(http.StatusUnauthorized, errors.New("{error : \"Require auth!\"}"))
|
||||
return
|
||||
}
|
||||
articleUserModel := GetArticleUserModel(myUserModel)
|
||||
articleModels, modelCount, err := articleUserModel.GetArticleFeed(limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
|
||||
return
|
||||
}
|
||||
serializer := ArticlesSerializer{c, articleModels}
|
||||
c.JSON(http.StatusOK, gin.H{"articles": serializer.Response(), "articlesCount": modelCount})
|
||||
}
|
||||
|
||||
func ArticleRetrieve(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
serializer := ArticleSerializer{c, articleModel}
|
||||
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleUpdate(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
// Check if current user is the author
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
articleUserModel := GetArticleUserModel(myUserModel)
|
||||
if articleModel.AuthorID != articleUserModel.ID {
|
||||
c.JSON(http.StatusForbidden, common.NewError("article", errors.New("you are not the author")))
|
||||
return
|
||||
}
|
||||
|
||||
articleModelValidator := NewArticleModelValidatorFillWith(articleModel)
|
||||
if err := articleModelValidator.Bind(c); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
|
||||
return
|
||||
}
|
||||
|
||||
articleModelValidator.articleModel.ID = articleModel.ID
|
||||
if err := articleModel.Update(articleModelValidator.articleModel); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
serializer := ArticleSerializer{c, articleModel}
|
||||
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleDelete(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err == nil {
|
||||
// Article exists, check authorization
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
articleUserModel := GetArticleUserModel(myUserModel)
|
||||
if articleModel.AuthorID != articleUserModel.ID {
|
||||
c.JSON(http.StatusForbidden, common.NewError("article", errors.New("you are not the author")))
|
||||
return
|
||||
}
|
||||
}
|
||||
// Delete regardless of existence (idempotent)
|
||||
if err := DeleteArticleModel(&ArticleModel{Slug: slug}); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"article": "delete success"})
|
||||
}
|
||||
|
||||
func ArticleFavorite(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
if err = articleModel.favoriteBy(GetArticleUserModel(myUserModel)); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
serializer := ArticleSerializer{c, articleModel}
|
||||
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleUnfavorite(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
if err = articleModel.unFavoriteBy(GetArticleUserModel(myUserModel)); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
serializer := ArticleSerializer{c, articleModel}
|
||||
c.JSON(http.StatusOK, gin.H{"article": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleCommentCreate(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("comment", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
commentModelValidator := NewCommentModelValidator()
|
||||
if err := commentModelValidator.Bind(c); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewValidatorError(err))
|
||||
return
|
||||
}
|
||||
commentModelValidator.commentModel.Article = articleModel
|
||||
|
||||
if err := SaveOne(&commentModelValidator.commentModel); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
serializer := CommentSerializer{c, commentModelValidator.commentModel}
|
||||
c.JSON(http.StatusCreated, gin.H{"comment": serializer.Response()})
|
||||
}
|
||||
|
||||
func ArticleCommentDelete(c *gin.Context) {
|
||||
id64, err := strconv.ParseUint(c.Param("id"), 10, 32)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("comment", errors.New("Invalid id")))
|
||||
return
|
||||
}
|
||||
id := uint(id64)
|
||||
commentModel, err := FindOneComment(&CommentModel{Model: gorm.Model{ID: id}})
|
||||
if err == nil {
|
||||
// Comment exists, check authorization
|
||||
myUserModel := c.MustGet("my_user_model").(users.UserModel)
|
||||
articleUserModel := GetArticleUserModel(myUserModel)
|
||||
if commentModel.AuthorID != articleUserModel.ID {
|
||||
c.JSON(http.StatusForbidden, common.NewError("comment", errors.New("you are not the author")))
|
||||
return
|
||||
}
|
||||
}
|
||||
// Delete regardless of existence (idempotent)
|
||||
if err := DeleteCommentModel([]uint{id}); err != nil {
|
||||
c.JSON(http.StatusUnprocessableEntity, common.NewError("database", err))
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"comment": "delete success"})
|
||||
}
|
||||
|
||||
func ArticleCommentList(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
articleModel, err := FindOneArticle(&ArticleModel{Slug: slug})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("comments", errors.New("Invalid slug")))
|
||||
return
|
||||
}
|
||||
err = articleModel.getComments()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("comments", errors.New("Database error")))
|
||||
return
|
||||
}
|
||||
serializer := CommentsSerializer{c, articleModel.Comments}
|
||||
c.JSON(http.StatusOK, gin.H{"comments": serializer.Response()})
|
||||
}
|
||||
func TagList(c *gin.Context) {
|
||||
tagModels, err := getAllTags()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, common.NewError("articles", errors.New("Invalid param")))
|
||||
return
|
||||
}
|
||||
serializer := TagsSerializer{c, tagModels}
|
||||
c.JSON(http.StatusOK, gin.H{"tags": serializer.Response()})
|
||||
}
|
||||
Reference in New Issue
Block a user