Merge branch 'feat/0.5.0/timeline_ai' into test

This commit is contained in:
LinkinStar 2022-11-25 18:38:30 +08:00
commit f1e48196db
6 changed files with 87 additions and 8 deletions

View File

@ -135,7 +135,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
reportController := controller.NewReportController(reportService, rankService) reportController := controller.NewReportController(reportService, rankService)
serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configRepo, activityRepo, userRankRepo, voteRepo) serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configRepo, activityRepo, userRankRepo, voteRepo)
voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configRepo, questionRepo, answerRepo, commentCommonRepo, objService) voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configRepo, questionRepo, answerRepo, commentCommonRepo, objService)
voteController := controller.NewVoteController(voteService) voteController := controller.NewVoteController(voteService, rankService)
followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo) followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService) tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService)
tagController := controller.NewTagController(tagService, tagCommonService, rankService) tagController := controller.NewTagController(tagService, tagCommonService, rankService)

2
go.mod
View File

@ -65,6 +65,7 @@ require (
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/subcommands v1.0.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect
@ -105,6 +106,7 @@ require (
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.23.0 // indirect go.uber.org/zap v1.23.0 // indirect
golang.org/x/image v0.1.0 // indirect golang.org/x/image v0.1.0 // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/sys v0.1.0 // indirect golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect golang.org/x/text v0.4.0 // indirect
golang.org/x/tools v0.2.0 // indirect golang.org/x/tools v0.2.0 // indirect

2
go.sum
View File

@ -284,6 +284,7 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -779,6 +780,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View File

@ -3,20 +3,24 @@ package controller
import ( import (
"github.com/answerdev/answer/internal/base/handler" "github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/middleware" "github.com/answerdev/answer/internal/base/middleware"
"github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service" "github.com/answerdev/answer/internal/service"
"github.com/answerdev/answer/internal/service/rank"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
"github.com/segmentfault/pacman/errors"
) )
// VoteController activity controller // VoteController activity controller
type VoteController struct { type VoteController struct {
VoteService *service.VoteService VoteService *service.VoteService
rankService *rank.RankService
} }
// NewVoteController new controller // NewVoteController new controller
func NewVoteController(voteService *service.VoteService) *VoteController { func NewVoteController(voteService *service.VoteService, rankService *rank.RankService) *VoteController {
return &VoteController{VoteService: voteService} return &VoteController{VoteService: voteService, rankService: rankService}
} }
// VoteUp godoc // VoteUp godoc
@ -34,9 +38,19 @@ func (vc *VoteController) VoteUp(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) { if handler.BindAndCheck(ctx, req) {
return return
} }
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
can, err := vc.rankService.CheckVotePermission(ctx, req.UserID, req.ObjectID, true)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
}
if !can {
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
return
}
dto := &schema.VoteDTO{} dto := &schema.VoteDTO{}
_ = copier.Copy(dto, req) _ = copier.Copy(dto, req)
dto.UserID = middleware.GetLoginUserIDFromContext(ctx)
resp, err := vc.VoteService.VoteUp(ctx, dto) resp, err := vc.VoteService.VoteUp(ctx, dto)
if err != nil { if err != nil {
handler.HandleResponse(ctx, err, schema.ErrTypeToast) handler.HandleResponse(ctx, err, schema.ErrTypeToast)
@ -60,10 +74,20 @@ func (vc *VoteController) VoteDown(ctx *gin.Context) {
if handler.BindAndCheck(ctx, req) { if handler.BindAndCheck(ctx, req) {
return return
} }
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
can, err := vc.rankService.CheckVotePermission(ctx, req.UserID, req.ObjectID, false)
if err != nil {
handler.HandleResponse(ctx, err, nil)
return
}
if !can {
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
return
}
dto := &schema.VoteDTO{} dto := &schema.VoteDTO{}
_ = copier.Copy(dto, req) _ = copier.Copy(dto, req)
dto.UserID = middleware.GetLoginUserIDFromContext(ctx)
resp, err := vc.VoteService.VoteDown(ctx, dto) resp, err := vc.VoteService.VoteDown(ctx, dto)
if err != nil { if err != nil {
handler.HandleResponse(ctx, err, schema.ErrTypeToast) handler.HandleResponse(ctx, err, schema.ErrTypeToast)

View File

@ -3,6 +3,7 @@ package schema
type VoteReq struct { type VoteReq struct {
ObjectID string `validate:"required" form:"object_id" json:"object_id"` // id ObjectID string `validate:"required" form:"object_id" json:"object_id"` // id
IsCancel bool `validate:"omitempty" form:"is_cancel" json:"is_cancel"` // is cancel IsCancel bool `validate:"omitempty" form:"is_cancel" json:"is_cancel"` // is cancel
UserID string `json:"-"`
} }
type VoteDTO struct { type VoteDTO struct {

View File

@ -3,6 +3,7 @@ package rank
import ( import (
"context" "context"
"github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/pager" "github.com/answerdev/answer/internal/base/pager"
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
@ -75,7 +76,7 @@ func NewRankService(
} }
} }
// CheckOperationPermission verify that the user has operation // CheckOperationPermission verify that the user has permission
func (rs *RankService) CheckOperationPermission(ctx context.Context, userID string, action string, objectID string) ( func (rs *RankService) CheckOperationPermission(ctx context.Context, userID string, action string, objectID string) (
can bool, err error) { can bool, err error) {
if len(userID) == 0 { if len(userID) == 0 {
@ -110,7 +111,7 @@ func (rs *RankService) CheckOperationPermission(ctx context.Context, userID stri
return rs.checkUserRank(ctx, userInfo.ID, userInfo.Rank, action) return rs.checkUserRank(ctx, userInfo.ID, userInfo.Rank, action)
} }
// CheckOperationPermissions verify that the user has operation // CheckOperationPermissions verify that the user has permission
func (rs *RankService) CheckOperationPermissions(ctx context.Context, userID string, actions []string, objectID string) ( func (rs *RankService) CheckOperationPermissions(ctx context.Context, userID string, actions []string, objectID string) (
can []bool, err error) { can []bool, err error) {
can = make([]bool, len(actions)) can = make([]bool, len(actions))
@ -154,6 +155,55 @@ func (rs *RankService) CheckOperationPermissions(ctx context.Context, userID str
return can, nil return can, nil
} }
// CheckVotePermission verify that the user has vote permission
func (rs *RankService) CheckVotePermission(ctx context.Context, userID, objectID string, voteUp bool) (
can bool, err error) {
if len(userID) == 0 || len(objectID) == 0 {
return false, nil
}
// get the rank of the current user
userInfo, exist, err := rs.userCommon.GetUserBasicInfoByID(ctx, userID)
if err != nil {
return can, err
}
if !exist {
return can, nil
}
objectInfo, err := rs.objectInfoService.GetInfo(ctx, objectID)
if err != nil {
return can, err
}
action := ""
switch objectInfo.ObjectType {
case constant.QuestionObjectType:
if voteUp {
action = QuestionVoteUpRank
} else {
action = QuestionVoteDownRank
}
case constant.AnswerObjectType:
if voteUp {
action = AnswerVoteUpRank
} else {
action = AnswerVoteDownRank
}
case constant.CommentObjectType:
if voteUp {
action = CommentVoteUpRank
} else {
action = CommentVoteDownRank
}
}
meetRank, err := rs.checkUserRank(ctx, userInfo.ID, userInfo.Rank, action)
if err != nil {
log.Error(err)
}
return meetRank, nil
}
// CheckRankPermission verify that the user meets the prestige criteria // CheckRankPermission verify that the user meets the prestige criteria
func (rs *RankService) checkUserRank(ctx context.Context, userID string, userRank int, action string) ( func (rs *RankService) checkUserRank(ctx context.Context, userID string, userRank int, action string) (
can bool, err error) { can bool, err error) {