Files

143 lines
3.8 KiB
Go

package handler
import (
"strings"
"github.com/ArtalkJS/Artalk/internal/core"
"github.com/ArtalkJS/Artalk/internal/entity"
"github.com/ArtalkJS/Artalk/internal/i18n"
"github.com/ArtalkJS/Artalk/server/common"
"github.com/gofiber/fiber/v2"
)
type ParamsVote struct {
TargetID uint `form:"target_id" validate:"required"`
FullType string `form:"type" validate:"required"`
Name string `form:"name"`
Email string `form:"email"`
SiteName string
SiteID uint
SiteAll bool
}
type ResponseVote struct {
Up int `json:"up"`
Down int `json:"down"`
}
// @Summary Vote
// @Description Vote for a specific comment or page
// @Tags Vote
// @Param target_id formData int true "target comment or page ID you want to vote for"
// @Param type formData string true "the type of vote target" Enums(comment_up, comment_down, page_up, page_down)
// @Param name formData string false "the username"
// @Param email formData string false "the user email"
// @Param site_name formData string false "the site name of your content scope"
// @Success 200 {object} common.JSONResult{data=ResponseVote}
// @Router /vote [post]
func Vote(app *core.App, router fiber.Router) {
router.Post("/vote", func(c *fiber.Ctx) error {
var p ParamsVote
if isOK, resp := common.ParamsDecode(c, &p); !isOK {
return resp
}
// use site
common.UseSite(c, &p.SiteName, &p.SiteID, &p.SiteAll)
// find user
var user entity.User
if p.Name != "" && p.Email != "" {
user = app.Dao().FindCreateUser(p.Name, p.Email, "")
}
ip := c.IP()
// check type
isVoteComment := strings.HasPrefix(p.FullType, "comment_")
isVotePage := strings.HasPrefix(p.FullType, "page_")
isUp := strings.HasSuffix(p.FullType, "_up")
isDown := strings.HasSuffix(p.FullType, "_down")
voteTo := strings.TrimSuffix(strings.TrimSuffix(p.FullType, "_up"), "_down")
voteType := strings.TrimPrefix(strings.TrimPrefix(p.FullType, "comment_"), "page_")
if !isUp && !isDown {
return common.RespError(c, "unknown type")
}
var comment entity.Comment
var page entity.Page
switch {
case isVoteComment:
comment = app.Dao().FindComment(p.TargetID)
if comment.IsEmpty() {
return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Comment")}))
}
case isVotePage:
page = app.Dao().FindPageByID(p.TargetID)
if page.IsEmpty() {
return common.RespError(c, i18n.T("{{name}} not found", Map{"name": i18n.T("Page")}))
}
default:
return common.RespError(c, "unknown type")
}
// sync target model field value
save := func(up int, down int) {
switch {
case isVoteComment:
comment.VoteUp = up
comment.VoteDown = down
app.Dao().UpdateComment(&comment)
case isVotePage:
page.VoteUp = up
page.VoteDown = down
app.Dao().UpdatePage(&page)
}
}
createNew := func(t string) error {
// create new vote record
_, err := app.Dao().NewVote(p.TargetID, entity.VoteType(t), user.ID, string(c.Request().Header.UserAgent()), ip)
return err
}
// un-vote
var availableVotes []entity.Vote
app.Dao().DB().Where("target_id = ? AND type LIKE ? AND ip = ?", p.TargetID, voteTo+"%", ip).Find(&availableVotes)
if len(availableVotes) > 0 {
for _, v := range availableVotes {
app.Dao().DB().Unscoped().Delete(&v)
}
avaVoteType := strings.TrimPrefix(strings.TrimPrefix(string(availableVotes[0].Type), "comment_"), "page_")
if voteType != avaVoteType {
createNew(p.FullType)
}
up, down := app.Dao().GetVoteNumUpDown(p.TargetID, voteTo)
save(up, down)
return common.RespData(c, ResponseVote{
Up: up,
Down: down,
})
}
createNew(p.FullType)
// sync
up, down := app.Dao().GetVoteNumUpDown(p.TargetID, voteTo)
save(up, down)
return common.RespData(c, ResponseVote{
Up: up,
Down: down,
})
})
}