♻️ Use the universal post api replace some duplicated apis
This commit is contained in:
@ -9,81 +9,18 @@ import (
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/services"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func contextArticle() *services.PostTypeContext[*models.Article] {
|
||||
return &services.PostTypeContext[*models.Article]{
|
||||
Tx: database.C,
|
||||
TypeName: "Article",
|
||||
CanReply: false,
|
||||
CanRepost: false,
|
||||
func contextArticle() *services.PostTypeContext {
|
||||
return &services.PostTypeContext{
|
||||
Tx: database.C,
|
||||
TableName: "articles",
|
||||
ColumnName: "article",
|
||||
CanReply: false,
|
||||
CanRepost: false,
|
||||
}
|
||||
}
|
||||
|
||||
func getArticle(c *fiber.Ctx) error {
|
||||
alias := c.Params("articleId")
|
||||
|
||||
mx := contextArticle().FilterPublishedAt(time.Now())
|
||||
|
||||
item, err := mx.GetViaAlias(alias)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
item.ReactionList, err = mx.CountReactions(item.ID)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func listArticle(c *fiber.Ctx) error {
|
||||
take := c.QueryInt("take", 0)
|
||||
offset := c.QueryInt("offset", 0)
|
||||
realmId := c.QueryInt("realmId", 0)
|
||||
|
||||
mx := contextArticle().
|
||||
FilterPublishedAt(time.Now()).
|
||||
FilterRealm(uint(realmId)).
|
||||
SortCreatedAt("desc")
|
||||
|
||||
var author models.Account
|
||||
if len(c.Query("authorId")) > 0 {
|
||||
if err := database.C.Where(&models.Account{Name: c.Query("authorId")}).First(&author).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
mx = mx.FilterAuthor(author.ID)
|
||||
}
|
||||
|
||||
if len(c.Query("category")) > 0 {
|
||||
mx = mx.FilterWithCategory(c.Query("category"))
|
||||
}
|
||||
if len(c.Query("tag")) > 0 {
|
||||
mx = mx.FilterWithTag(c.Query("tag"))
|
||||
}
|
||||
|
||||
if !c.QueryBool("reply", true) {
|
||||
mx = mx.FilterReply(true)
|
||||
}
|
||||
|
||||
count, err := mx.Count()
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
items, err := mx.List(take, offset)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"count": count,
|
||||
"data": items,
|
||||
})
|
||||
}
|
||||
|
||||
func createArticle(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
|
||||
@ -105,8 +42,6 @@ func createArticle(c *fiber.Ctx) error {
|
||||
data.Alias = strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
}
|
||||
|
||||
mx := contextArticle()
|
||||
|
||||
item := &models.Article{
|
||||
PostBase: models.PostBase{
|
||||
Alias: data.Alias,
|
||||
@ -131,12 +66,11 @@ func createArticle(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
item, err := mx.New(item)
|
||||
if err != nil {
|
||||
if item, err := services.NewPost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func editArticle(c *fiber.Ctx) error {
|
||||
@ -158,10 +92,13 @@ func editArticle(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextArticle().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id))
|
||||
if err != nil {
|
||||
var item *models.Article
|
||||
if err := database.C.Where(models.Article{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
@ -174,61 +111,28 @@ func editArticle(c *fiber.Ctx) error {
|
||||
item.Categories = data.Categories
|
||||
item.Attachments = data.Attachments
|
||||
|
||||
item, err = mx.Edit(item)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func reactArticle(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("articleId", 0)
|
||||
|
||||
var data struct {
|
||||
Symbol string `json:"symbol" validate:"required"`
|
||||
Attitude models.ReactionAttitude `json:"attitude" validate:"required"`
|
||||
}
|
||||
|
||||
if err := BindAndValidate(c, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextArticle()
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
reaction := models.Reaction{
|
||||
Symbol: data.Symbol,
|
||||
Attitude: data.Attitude,
|
||||
AccountID: user.ID,
|
||||
ArticleID: &item.ID,
|
||||
}
|
||||
|
||||
if positive, reaction, err := mx.React(reaction); err != nil {
|
||||
if item, err := services.EditPost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
return c.Status(lo.Ternary(positive, fiber.StatusCreated, fiber.StatusNoContent)).JSON(reaction)
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func deleteArticle(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("articleId", 0)
|
||||
|
||||
mx := contextArticle().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
var item *models.Article
|
||||
if err := database.C.Where(models.Article{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
if err := mx.Delete(item); err != nil {
|
||||
if err := services.DeletePost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
|
@ -10,81 +10,18 @@ import (
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/services"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func contextComment() *services.PostTypeContext[*models.Comment] {
|
||||
return &services.PostTypeContext[*models.Comment]{
|
||||
Tx: database.C,
|
||||
TypeName: "Comment",
|
||||
CanReply: false,
|
||||
CanRepost: true,
|
||||
func contextComment() *services.PostTypeContext {
|
||||
return &services.PostTypeContext{
|
||||
Tx: database.C,
|
||||
TableName: "comments",
|
||||
ColumnName: "comment",
|
||||
CanReply: false,
|
||||
CanRepost: true,
|
||||
}
|
||||
}
|
||||
|
||||
func getComment(c *fiber.Ctx) error {
|
||||
alias := c.Params("commentId")
|
||||
|
||||
mx := contextComment().FilterPublishedAt(time.Now())
|
||||
|
||||
item, err := mx.GetViaAlias(alias)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
item.ReactionList, err = mx.CountReactions(item.ID)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func listComment(c *fiber.Ctx) error {
|
||||
take := c.QueryInt("take", 0)
|
||||
offset := c.QueryInt("offset", 0)
|
||||
realmId := c.QueryInt("realmId", 0)
|
||||
|
||||
mx := contextComment().
|
||||
FilterPublishedAt(time.Now()).
|
||||
FilterRealm(uint(realmId)).
|
||||
SortCreatedAt("desc")
|
||||
|
||||
var author models.Account
|
||||
if len(c.Query("authorId")) > 0 {
|
||||
if err := database.C.Where(&models.Account{Name: c.Query("authorId")}).First(&author).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
mx = mx.FilterAuthor(author.ID)
|
||||
}
|
||||
|
||||
if len(c.Query("category")) > 0 {
|
||||
mx = mx.FilterWithCategory(c.Query("category"))
|
||||
}
|
||||
if len(c.Query("tag")) > 0 {
|
||||
mx = mx.FilterWithTag(c.Query("tag"))
|
||||
}
|
||||
|
||||
if !c.QueryBool("reply", true) {
|
||||
mx = mx.FilterReply(true)
|
||||
}
|
||||
|
||||
count, err := mx.Count()
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
items, err := mx.List(take, offset)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"count": count,
|
||||
"data": items,
|
||||
})
|
||||
}
|
||||
|
||||
func createComment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
|
||||
@ -106,8 +43,6 @@ func createComment(c *fiber.Ctx) error {
|
||||
data.Alias = strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
}
|
||||
|
||||
mx := contextComment()
|
||||
|
||||
item := &models.Comment{
|
||||
PostBase: models.PostBase{
|
||||
Alias: data.Alias,
|
||||
@ -142,7 +77,7 @@ func createComment(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
item, err := mx.New(item)
|
||||
item, err := services.NewPost(item)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
@ -167,10 +102,13 @@ func editComment(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextComment().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id))
|
||||
if err != nil {
|
||||
var item *models.Comment
|
||||
if err := database.C.Where(models.Comment{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
@ -181,61 +119,28 @@ func editComment(c *fiber.Ctx) error {
|
||||
item.Categories = data.Categories
|
||||
item.Attachments = data.Attachments
|
||||
|
||||
item, err = mx.Edit(item)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func reactComment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("commentId", 0)
|
||||
|
||||
var data struct {
|
||||
Symbol string `json:"symbol" validate:"required"`
|
||||
Attitude models.ReactionAttitude `json:"attitude" validate:"required"`
|
||||
}
|
||||
|
||||
if err := BindAndValidate(c, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextComment()
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
reaction := models.Reaction{
|
||||
Symbol: data.Symbol,
|
||||
Attitude: data.Attitude,
|
||||
AccountID: user.ID,
|
||||
CommentID: &item.ID,
|
||||
}
|
||||
|
||||
if positive, reaction, err := mx.React(reaction); err != nil {
|
||||
if item, err := services.EditPost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
return c.Status(lo.Ternary(positive, fiber.StatusCreated, fiber.StatusNoContent)).JSON(reaction)
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func deleteComment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("commentId", 0)
|
||||
|
||||
mx := contextComment().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
var item *models.Comment
|
||||
if err := database.C.Where(models.Comment{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
if err := mx.Delete(item); err != nil {
|
||||
if err := services.DeletePost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package server
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/database"
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/models"
|
||||
@ -10,23 +9,6 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type FeedItem struct {
|
||||
models.BaseModel
|
||||
|
||||
Alias string `json:"alias"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
ModelType string `json:"model_type"`
|
||||
CommentCount int64 `json:"comment_count"`
|
||||
ReactionCount int64 `json:"reaction_count"`
|
||||
AuthorID uint `json:"author_id"`
|
||||
RealmID *uint `json:"realm_id"`
|
||||
|
||||
Author models.Account `json:"author" gorm:"embedded"`
|
||||
ReactionList map[string]int64 `json:"reaction_list"`
|
||||
}
|
||||
|
||||
const (
|
||||
queryArticle = "id, created_at, updated_at, alias, title, NULL as content, description, realm_id, author_id, 'article' as model_type"
|
||||
queryMoment = "id, created_at, updated_at, alias, NULL as title, content, NULL as description, realm_id, author_id, 'moment' as model_type"
|
||||
@ -58,7 +40,7 @@ func listFeed(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
var result []*FeedItem
|
||||
var result []*models.Feed
|
||||
|
||||
userTable := viper.GetString("database.prefix") + "accounts"
|
||||
commentTable := viper.GetString("database.prefix") + "comments"
|
||||
@ -94,15 +76,15 @@ func listFeed(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
revertReaction := func(dataset string) error {
|
||||
itemMap := lo.SliceToMap(lo.FilterMap(result, func(item *FeedItem, index int) (*FeedItem, bool) {
|
||||
itemMap := lo.SliceToMap(lo.FilterMap(result, func(item *models.Feed, index int) (*models.Feed, bool) {
|
||||
return item, item.ModelType == dataset
|
||||
}), func(item *FeedItem) (uint, *FeedItem) {
|
||||
}), func(item *models.Feed) (uint, *models.Feed) {
|
||||
return item.ID, item
|
||||
})
|
||||
|
||||
idx := lo.Map(lo.Filter(result, func(item *FeedItem, index int) bool {
|
||||
idx := lo.Map(lo.Filter(result, func(item *models.Feed, index int) bool {
|
||||
return item.ModelType == dataset
|
||||
}), func(item *FeedItem, index int) uint {
|
||||
}), func(item *models.Feed, index int) uint {
|
||||
return item.ID
|
||||
})
|
||||
|
||||
|
@ -9,81 +9,18 @@ import (
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/services"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func contextMoment() *services.PostTypeContext[*models.Moment] {
|
||||
return &services.PostTypeContext[*models.Moment]{
|
||||
Tx: database.C,
|
||||
TypeName: "Moment",
|
||||
CanReply: false,
|
||||
CanRepost: true,
|
||||
func contextMoment() *services.PostTypeContext {
|
||||
return &services.PostTypeContext{
|
||||
Tx: database.C,
|
||||
TableName: "moments",
|
||||
ColumnName: "moment",
|
||||
CanReply: false,
|
||||
CanRepost: true,
|
||||
}
|
||||
}
|
||||
|
||||
func getMoment(c *fiber.Ctx) error {
|
||||
alias := c.Params("momentId")
|
||||
|
||||
mx := contextMoment().FilterPublishedAt(time.Now())
|
||||
|
||||
item, err := mx.GetViaAlias(alias)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
item.ReactionList, err = mx.CountReactions(item.ID)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func listMoment(c *fiber.Ctx) error {
|
||||
take := c.QueryInt("take", 0)
|
||||
offset := c.QueryInt("offset", 0)
|
||||
realmId := c.QueryInt("realmId", 0)
|
||||
|
||||
mx := contextMoment().
|
||||
FilterPublishedAt(time.Now()).
|
||||
FilterRealm(uint(realmId)).
|
||||
SortCreatedAt("desc")
|
||||
|
||||
var author models.Account
|
||||
if len(c.Query("authorId")) > 0 {
|
||||
if err := database.C.Where(&models.Account{Name: c.Query("authorId")}).First(&author).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
mx = mx.FilterAuthor(author.ID)
|
||||
}
|
||||
|
||||
if len(c.Query("category")) > 0 {
|
||||
mx = mx.FilterWithCategory(c.Query("category"))
|
||||
}
|
||||
if len(c.Query("tag")) > 0 {
|
||||
mx = mx.FilterWithTag(c.Query("tag"))
|
||||
}
|
||||
|
||||
if !c.QueryBool("reply", true) {
|
||||
mx = mx.FilterReply(true)
|
||||
}
|
||||
|
||||
count, err := mx.Count()
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
items, err := mx.List(take, offset)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"count": count,
|
||||
"data": items,
|
||||
})
|
||||
}
|
||||
|
||||
func createMoment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
|
||||
@ -104,8 +41,6 @@ func createMoment(c *fiber.Ctx) error {
|
||||
data.Alias = strings.ReplaceAll(uuid.NewString(), "-", "")
|
||||
}
|
||||
|
||||
mx := contextMoment()
|
||||
|
||||
item := &models.Moment{
|
||||
PostBase: models.PostBase{
|
||||
Alias: data.Alias,
|
||||
@ -140,7 +75,7 @@ func createMoment(c *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
item, err := mx.New(item)
|
||||
item, err := services.NewPost(item)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
@ -165,10 +100,13 @@ func editMoment(c *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextMoment().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id))
|
||||
if err != nil {
|
||||
var item *models.Moment
|
||||
if err := database.C.Where(models.Comment{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
@ -179,61 +117,28 @@ func editMoment(c *fiber.Ctx) error {
|
||||
item.Categories = data.Categories
|
||||
item.Attachments = data.Attachments
|
||||
|
||||
item, err = mx.Edit(item)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func reactMoment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("momentId", 0)
|
||||
|
||||
var data struct {
|
||||
Symbol string `json:"symbol" validate:"required"`
|
||||
Attitude models.ReactionAttitude `json:"attitude" validate:"required"`
|
||||
}
|
||||
|
||||
if err := BindAndValidate(c, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := contextMoment()
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
reaction := models.Reaction{
|
||||
Symbol: data.Symbol,
|
||||
Attitude: data.Attitude,
|
||||
AccountID: user.ID,
|
||||
MomentID: &item.ID,
|
||||
}
|
||||
|
||||
if positive, reaction, err := mx.React(reaction); err != nil {
|
||||
if item, err := services.EditPost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
return c.Status(lo.Ternary(positive, fiber.StatusCreated, fiber.StatusNoContent)).JSON(reaction)
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func deleteMoment(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("momentId", 0)
|
||||
|
||||
mx := contextMoment().FilterAuthor(user.ID)
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
var item *models.Moment
|
||||
if err := database.C.Where(models.Comment{
|
||||
PostBase: models.PostBase{
|
||||
BaseModel: models.BaseModel{ID: uint(id)},
|
||||
AuthorID: user.ID,
|
||||
},
|
||||
}).First(&item).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
if err := mx.Delete(item); err != nil {
|
||||
if err := services.DeletePost(item); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
|
126
pkg/server/posts_api.go
Normal file
126
pkg/server/posts_api.go
Normal file
@ -0,0 +1,126 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/database"
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/models"
|
||||
"code.smartsheep.studio/hydrogen/interactive/pkg/services"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
var postContextKey = "ptx"
|
||||
|
||||
func useDynamicContext(c *fiber.Ctx) error {
|
||||
postType := c.Params("postType")
|
||||
switch postType {
|
||||
case "articles":
|
||||
c.Locals(postContextKey, contextArticle())
|
||||
case "moments":
|
||||
c.Locals(postContextKey, contextMoment())
|
||||
case "comments":
|
||||
c.Locals(postContextKey, contextComment())
|
||||
default:
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid dataset")
|
||||
}
|
||||
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
func getPost(c *fiber.Ctx) error {
|
||||
alias := c.Params("postId")
|
||||
|
||||
mx := c.Locals(postContextKey).(*services.PostTypeContext)
|
||||
|
||||
item, err := mx.GetViaAlias(alias)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
item.ReactionList, err = mx.CountReactions(item.ID)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(item)
|
||||
}
|
||||
|
||||
func listPost(c *fiber.Ctx) error {
|
||||
take := c.QueryInt("take", 0)
|
||||
offset := c.QueryInt("offset", 0)
|
||||
realmId := c.QueryInt("realmId", 0)
|
||||
|
||||
mx := c.Locals(postContextKey).(*services.PostTypeContext).
|
||||
FilterPublishedAt(time.Now()).
|
||||
FilterRealm(uint(realmId)).
|
||||
SortCreatedAt("desc")
|
||||
|
||||
var author models.Account
|
||||
if len(c.Query("authorId")) > 0 {
|
||||
if err := database.C.Where(&models.Account{Name: c.Query("authorId")}).First(&author).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
mx = mx.FilterAuthor(author.ID)
|
||||
}
|
||||
|
||||
if len(c.Query("category")) > 0 {
|
||||
mx = mx.FilterWithCategory(c.Query("category"))
|
||||
}
|
||||
if len(c.Query("tag")) > 0 {
|
||||
mx = mx.FilterWithTag(c.Query("tag"))
|
||||
}
|
||||
|
||||
if !c.QueryBool("reply", true) {
|
||||
mx = mx.FilterReply(true)
|
||||
}
|
||||
|
||||
count, err := mx.Count()
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
items, err := mx.List(take, offset)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"count": count,
|
||||
"data": items,
|
||||
})
|
||||
}
|
||||
|
||||
func reactPost(c *fiber.Ctx) error {
|
||||
user := c.Locals("principal").(models.Account)
|
||||
id, _ := c.ParamsInt("articleId", 0)
|
||||
|
||||
var data struct {
|
||||
Symbol string `json:"symbol" validate:"required"`
|
||||
Attitude models.ReactionAttitude `json:"attitude" validate:"required"`
|
||||
}
|
||||
|
||||
if err := BindAndValidate(c, &data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mx := c.Locals(postContextKey).(*services.PostTypeContext)
|
||||
|
||||
item, err := mx.Get(uint(id), true)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||
}
|
||||
|
||||
reaction := models.Reaction{
|
||||
Symbol: data.Symbol,
|
||||
Attitude: data.Attitude,
|
||||
AccountID: user.ID,
|
||||
ArticleID: &item.ID,
|
||||
}
|
||||
|
||||
if positive, reaction, err := mx.React(reaction); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
return c.Status(lo.Ternary(positive, fiber.StatusCreated, fiber.StatusNoContent)).JSON(reaction)
|
||||
}
|
||||
}
|
@ -71,32 +71,30 @@ func NewServer() {
|
||||
|
||||
api.Get("/feed", listFeed)
|
||||
|
||||
posts := api.Group("/p/:postType").Use(useDynamicContext).Name("Dataset Universal API")
|
||||
{
|
||||
posts.Get("/", listPost)
|
||||
posts.Get("/:postId", getPost)
|
||||
posts.Post("/:postId/react", authMiddleware, reactPost)
|
||||
}
|
||||
|
||||
moments := api.Group("/moments").Name("Moments API")
|
||||
{
|
||||
moments.Get("/", listMoment)
|
||||
moments.Get("/:momentId", getMoment)
|
||||
moments.Post("/", authMiddleware, createMoment)
|
||||
moments.Post("/:momentId/react", authMiddleware, reactMoment)
|
||||
moments.Put("/:momentId", authMiddleware, editMoment)
|
||||
moments.Delete("/:momentId", authMiddleware, deleteMoment)
|
||||
}
|
||||
|
||||
articles := api.Group("/articles").Name("Articles API")
|
||||
articles := api.Group("/p/articles").Name("Articles API")
|
||||
{
|
||||
articles.Get("/", listArticle)
|
||||
articles.Get("/:articleId", getArticle)
|
||||
articles.Post("/", authMiddleware, createArticle)
|
||||
articles.Post("/:articleId/react", authMiddleware, reactArticle)
|
||||
articles.Put("/:articleId", authMiddleware, editArticle)
|
||||
articles.Delete("/:articleId", authMiddleware, deleteArticle)
|
||||
}
|
||||
|
||||
comments := api.Group("/comments").Name("Comments API")
|
||||
comments := api.Group("/p/comments").Name("Comments API")
|
||||
{
|
||||
comments.Get("/", listComment)
|
||||
comments.Get("/:commentId", getComment)
|
||||
comments.Post("/", authMiddleware, createComment)
|
||||
comments.Post("/:commentId/react", authMiddleware, reactComment)
|
||||
comments.Put("/:commentId", authMiddleware, editComment)
|
||||
comments.Delete("/:commentId", authMiddleware, deleteComment)
|
||||
}
|
||||
|
Reference in New Issue
Block a user