200 lines
5.8 KiB
Go
200 lines
5.8 KiB
Go
|
package application_v1
|
||
|
|
||
|
import (
|
||
|
"github.com/gin-gonic/gin"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/base/logger"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/base/redis"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/handler/http/request"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/handler/http/response"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/service/application"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/service/auth"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/service/post"
|
||
|
"leafdev.top/Ecosystem/recommender/internal/service/user"
|
||
|
"leafdev.top/Ecosystem/recommender/pkg/consts"
|
||
|
"net/http"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
const TaskProcessing = "user_likes"
|
||
|
|
||
|
var LockTTL = time.Minute * 10
|
||
|
|
||
|
type UserController struct {
|
||
|
authService *auth.Service
|
||
|
applicationService *application.Service
|
||
|
userService *user.Service
|
||
|
postService *post.Service
|
||
|
logger *logger.Logger
|
||
|
redis *redis.Redis
|
||
|
}
|
||
|
|
||
|
func NewUserController(
|
||
|
authService *auth.Service,
|
||
|
applicationService *application.Service,
|
||
|
userService *user.Service,
|
||
|
postService *post.Service,
|
||
|
logger *logger.Logger,
|
||
|
redis *redis.Redis,
|
||
|
|
||
|
) *UserController {
|
||
|
return &UserController{
|
||
|
authService: authService,
|
||
|
applicationService: applicationService,
|
||
|
userService: userService,
|
||
|
postService: postService,
|
||
|
logger: logger,
|
||
|
redis: redis,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Like godoc
|
||
|
// @Summary Like
|
||
|
// @Description 将标签附加到用户名
|
||
|
// @Tags application_api
|
||
|
// @Accept json
|
||
|
// @Produce json
|
||
|
// @Security ApiKeyAuth
|
||
|
// @Param UserLikePost body request.UserLikePost true "UserLikePost"
|
||
|
// @Success 200 {object} response.ResponseBody{data=entity.Category}
|
||
|
// @Failure 400 {object} response.ResponseBody
|
||
|
// @Router /applications/v1/users/_like [post]
|
||
|
func (uc *UserController) Like(c *gin.Context) {
|
||
|
app, err := uc.authService.GetApplication(c)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var userLikePostRequest = &request.UserLikePost{}
|
||
|
|
||
|
if err := c.ShouldBindJSON(userLikePostRequest); err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
externalUser, err := uc.userService.GetOrCreateExternalUser(c, userLikePostRequest.ExternalUserId, app)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// posts
|
||
|
postEntity, err := uc.postService.GetPostById(c, userLikePostRequest.PostId)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if postEntity.ApplicationId != app.Id {
|
||
|
response.Ctx(c).Status(http.StatusNotFound).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 检测是否有
|
||
|
var cacheKey = uc.redis.Prefix(TaskProcessing + ":" + userLikePostRequest.PostId.String())
|
||
|
// if exists
|
||
|
exists, err := uc.redis.Client.Exists(c, cacheKey).Result()
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if exists > 0 {
|
||
|
response.Ctx(c).Status(http.StatusTooEarly).Error(consts.ErrAnotherOperationInProgress).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
_, err = uc.redis.Client.Set(c, cacheKey, userLikePostRequest.ExternalUserId, LockTTL).Result()
|
||
|
|
||
|
go func(prefix string) {
|
||
|
err = uc.userService.LikePost(c, externalUser, app, postEntity)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
_, err := uc.redis.Client.Del(c, prefix).Result()
|
||
|
if err != nil {
|
||
|
uc.logger.Sugar.Error(err)
|
||
|
}
|
||
|
}(cacheKey)
|
||
|
|
||
|
response.Ctx(c).Status(http.StatusNoContent).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Dislike godoc
|
||
|
// @Summary Dislike
|
||
|
// @Description 从用户的标签喜好中移除内容
|
||
|
// @Tags application_api
|
||
|
// @Accept json
|
||
|
// @Produce json
|
||
|
// @Security ApiKeyAuth
|
||
|
// @Param UserLikePost body request.UserLikePost true "UserLikePost"
|
||
|
// @Success 200 {object} response.ResponseBody{data=entity.Category}
|
||
|
// @Failure 400 {object} response.ResponseBody
|
||
|
// @Router /applications/v1/users/_dislike [post]
|
||
|
func (uc *UserController) Dislike(c *gin.Context) {
|
||
|
app, err := uc.authService.GetApplication(c)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var userDislikePostRequest = &request.UserDislikePost{}
|
||
|
|
||
|
if err := c.ShouldBindJSON(userDislikePostRequest); err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusBadRequest).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
externalUser, err := uc.userService.GetOrCreateExternalUser(c, userDislikePostRequest.ExternalUserId, app)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// posts
|
||
|
postEntity, err := uc.postService.GetPostById(c, userDislikePostRequest.PostId)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if postEntity.ApplicationId != app.Id {
|
||
|
response.Ctx(c).Status(http.StatusNotFound).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// 检测是否有
|
||
|
var cacheKey = uc.redis.Prefix(TaskProcessing + ":" + userDislikePostRequest.PostId.String())
|
||
|
exists, err := uc.redis.Client.Exists(c, cacheKey).Result()
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if exists > 0 {
|
||
|
response.Ctx(c).Status(http.StatusTooEarly).Error(consts.ErrAnotherOperationInProgress).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
_, err = uc.redis.Client.Set(c, cacheKey, userDislikePostRequest.ExternalUserId, LockTTL).Result()
|
||
|
|
||
|
go func(prefix string) {
|
||
|
err = uc.userService.DislikePost(c, externalUser, app, postEntity)
|
||
|
if err != nil {
|
||
|
response.Ctx(c).Error(err).Status(http.StatusInternalServerError).Send()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
_, err := uc.redis.Client.Del(c, prefix).Result()
|
||
|
if err != nil {
|
||
|
uc.logger.Sugar.Error(err)
|
||
|
}
|
||
|
}(cacheKey)
|
||
|
|
||
|
response.Ctx(c).Status(http.StatusNoContent).Send()
|
||
|
return
|
||
|
}
|