feat(tag): Add revision when add tag

This commit is contained in:
LinkinStars 2023-03-03 16:59:34 +08:00
parent a90495c9f1
commit 4759e8778f
14 changed files with 76 additions and 74 deletions

View File

@ -166,7 +166,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, questionActivityRepo) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, questionActivityRepo)
questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, revisionService, metaService, collectionCommon, answerActivityService, dataData) questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, revisionService, metaService, collectionCommon, answerActivityService, dataData)
questionController := controller.NewQuestionController(questionService, rankService) questionController := controller.NewQuestionController(questionService, rankService)
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService) answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService)
dashboardService := dashboard.NewDashboardService(questionRepo, answerRepo, commentCommonRepo, voteRepo, userRepo, reportRepo, configRepo, siteInfoCommonService, serviceConf, dataData) dashboardService := dashboard.NewDashboardService(questionRepo, answerRepo, commentCommonRepo, voteRepo, userRepo, reportRepo, configRepo, siteInfoCommonService, serviceConf, dataData)
answerController := controller.NewAnswerController(answerService, rankService, dashboardService) answerController := controller.NewAnswerController(answerService, rankService, dashboardService)
searchParser := search_parser.NewSearchParser(tagCommonService, userCommon) searchParser := search_parser.NewSearchParser(tagCommonService, userCommon)

View File

@ -5592,7 +5592,8 @@ const docTemplate = `{
}, },
"original_text": { "original_text": {
"description": "original text", "description": "original text",
"type": "string" "type": "string",
"maxLength": 65536
}, },
"slug_name": { "slug_name": {
"description": "slug_name", "description": "slug_name",
@ -5993,14 +5994,6 @@ const docTemplate = `{
"description": "user id", "description": "user id",
"type": "string" "type": "string"
}, },
"ip_info": {
"description": "ip info",
"type": "string"
},
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"last_login_date": { "last_login_date": {
"description": "last login date", "description": "last login date",
"type": "integer" "type": "integer"
@ -6484,10 +6477,6 @@ const docTemplate = `{
"description": "ip info", "description": "ip info",
"type": "string" "type": "string"
}, },
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"language": { "language": {
"description": "language", "description": "language",
"type": "string" "type": "string"
@ -6520,6 +6509,10 @@ const docTemplate = `{
"description": "rank", "description": "rank",
"type": "integer" "type": "integer"
}, },
"role_id": {
"description": "role id",
"type": "integer"
},
"status": { "status": {
"description": "user status", "description": "user status",
"type": "string" "type": "string"
@ -6584,10 +6577,6 @@ const docTemplate = `{
"description": "ip info", "description": "ip info",
"type": "string" "type": "string"
}, },
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"language": { "language": {
"description": "language", "description": "language",
"type": "string" "type": "string"
@ -6620,6 +6609,10 @@ const docTemplate = `{
"description": "rank", "description": "rank",
"type": "integer" "type": "integer"
}, },
"role_id": {
"description": "role id",
"type": "integer"
},
"status": { "status": {
"description": "user status", "description": "user status",
"type": "string" "type": "string"

View File

@ -5580,7 +5580,8 @@
}, },
"original_text": { "original_text": {
"description": "original text", "description": "original text",
"type": "string" "type": "string",
"maxLength": 65536
}, },
"slug_name": { "slug_name": {
"description": "slug_name", "description": "slug_name",
@ -5981,14 +5982,6 @@
"description": "user id", "description": "user id",
"type": "string" "type": "string"
}, },
"ip_info": {
"description": "ip info",
"type": "string"
},
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"last_login_date": { "last_login_date": {
"description": "last login date", "description": "last login date",
"type": "integer" "type": "integer"
@ -6472,10 +6465,6 @@
"description": "ip info", "description": "ip info",
"type": "string" "type": "string"
}, },
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"language": { "language": {
"description": "language", "description": "language",
"type": "string" "type": "string"
@ -6508,6 +6497,10 @@
"description": "rank", "description": "rank",
"type": "integer" "type": "integer"
}, },
"role_id": {
"description": "role id",
"type": "integer"
},
"status": { "status": {
"description": "user status", "description": "user status",
"type": "string" "type": "string"
@ -6572,10 +6565,6 @@
"description": "ip info", "description": "ip info",
"type": "string" "type": "string"
}, },
"is_admin": {
"description": "is admin",
"type": "boolean"
},
"language": { "language": {
"description": "language", "description": "language",
"type": "string" "type": "string"
@ -6608,6 +6597,10 @@
"description": "rank", "description": "rank",
"type": "integer" "type": "integer"
}, },
"role_id": {
"description": "role id",
"type": "integer"
},
"status": { "status": {
"description": "user status", "description": "user status",
"type": "string" "type": "string"

View File

@ -182,6 +182,7 @@ definitions:
type: string type: string
original_text: original_text:
description: original text description: original text
maxLength: 65536
type: string type: string
slug_name: slug_name:
description: slug_name description: slug_name
@ -472,12 +473,6 @@ definitions:
id: id:
description: user id description: user id
type: string type: string
ip_info:
description: ip info
type: string
is_admin:
description: is admin
type: boolean
last_login_date: last_login_date:
description: last login date description: last login date
type: integer type: integer
@ -824,9 +819,6 @@ definitions:
ip_info: ip_info:
description: ip info description: ip info
type: string type: string
is_admin:
description: is admin
type: boolean
language: language:
description: language description: language
type: string type: string
@ -851,6 +843,9 @@ definitions:
rank: rank:
description: rank description: rank
type: integer type: integer
role_id:
description: role id
type: integer
status: status:
description: user status description: user status
type: string type: string
@ -898,9 +893,6 @@ definitions:
ip_info: ip_info:
description: ip info description: ip info
type: string type: string
is_admin:
description: is admin
type: boolean
language: language:
description: language description: language
type: string type: string
@ -925,6 +917,9 @@ definitions:
rank: rank:
description: rank description: rank
type: integer type: integer
role_id:
description: role id
type: integer
status: status:
description: user status description: user status
type: string type: string

View File

@ -4,6 +4,7 @@ import (
"strings" "strings"
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/role"
"github.com/answerdev/answer/internal/service/siteinfo_common" "github.com/answerdev/answer/internal/service/siteinfo_common"
"github.com/answerdev/answer/internal/base/handler" "github.com/answerdev/answer/internal/base/handler"
@ -154,7 +155,7 @@ func GetIsAdminFromContext(ctx *gin.Context) (isAdmin bool) {
if userInfo == nil { if userInfo == nil {
return false return false
} }
return userInfo.IsAdmin return userInfo.RoleID == role.RoleAdminID
} }
// GetUserInfoFromContext get user info from context // GetUserInfoFromContext get user info from context

View File

@ -6,6 +6,7 @@ import (
"github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/schema"
"github.com/answerdev/answer/internal/service/activity" "github.com/answerdev/answer/internal/service/activity"
"github.com/answerdev/answer/internal/service/activity_common" "github.com/answerdev/answer/internal/service/activity_common"
"github.com/answerdev/answer/internal/service/role"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@ -40,7 +41,7 @@ func (ac *ActivityController) GetObjectTimeline(ctx *gin.Context) {
req.UserID = middleware.GetLoginUserIDFromContext(ctx) req.UserID = middleware.GetLoginUserIDFromContext(ctx)
if userInfo := middleware.GetUserInfoFromContext(ctx); userInfo != nil { if userInfo := middleware.GetUserInfoFromContext(ctx); userInfo != nil {
req.IsAdmin = userInfo.IsAdmin req.IsAdmin = userInfo.RoleID == role.RoleAdminID
} }
resp, err := ac.activityService.GetObjectTimeline(ctx, req) resp, err := ac.activityService.GetObjectTimeline(ctx, req)

View File

@ -51,13 +51,16 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
} }
req.UserID = middleware.GetLoginUserIDFromContext(ctx) req.UserID = middleware.GetLoginUserIDFromContext(ctx)
req.IsAdmin = middleware.GetIsAdminFromContext(ctx) objectOwner := ac.rankService.CheckOperationObjectOwner(ctx, req.UserID, req.ID)
can, err := ac.rankService.CheckOperationPermission(ctx, req.UserID, permission.AnswerDelete, req.ID) canList, err := ac.rankService.CheckOperationPermissions(ctx, req.UserID, []string{
permission.AnswerDelete,
})
if err != nil { if err != nil {
handler.HandleResponse(ctx, err, nil) handler.HandleResponse(ctx, err, nil)
return return
} }
if !can { req.CanDelete = canList[0] || objectOwner
if !req.CanDelete {
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil) handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil)
return return
} }

View File

@ -5,5 +5,5 @@ type UserCacheInfo struct {
UserID string `json:"user_id"` UserID string `json:"user_id"`
UserStatus int `json:"user_status"` UserStatus int `json:"user_status"`
EmailStatus int `json:"email_status"` EmailStatus int `json:"email_status"`
IsAdmin bool `json:"is_admin"` RoleID int `json:"role_id"`
} }

View File

@ -10,8 +10,9 @@ type RemoveAnswerReq struct {
// answer id // answer id
ID string `validate:"required" json:"id"` ID string `validate:"required" json:"id"`
// user id // user id
UserID string `json:"-"` UserID string `json:"-"`
IsAdmin bool `json:"-"` // whether user can delete it
CanDelete bool `json:"-"`
} }
const ( const (

View File

@ -66,8 +66,8 @@ type GetUserResp struct {
Language string `json:"language"` Language string `json:"language"`
// access token // access token
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
// is admin // role id
IsAdmin bool `json:"is_admin"` RoleID int `json:"role_id"`
// user status // user status
Status string `json:"status"` Status string `json:"status"`
} }
@ -159,11 +159,7 @@ type GetOtherUserInfoByUsernameResp struct {
// website // website
Website string `json:"website"` Website string `json:"website"`
// location // location
Location string `json:"location"` Location string `json:"location"`
// ip info
IPInfo string `json:"ip_info"`
// is admin
IsAdmin bool `json:"is_admin"`
Status string `json:"status"` Status string `json:"status"`
StatusMsg string `json:"status_msg,omitempty"` StatusMsg string `json:"status_msg,omitempty"`
} }

View File

@ -20,6 +20,7 @@ import (
"github.com/answerdev/answer/internal/service/permission" "github.com/answerdev/answer/internal/service/permission"
questioncommon "github.com/answerdev/answer/internal/service/question_common" questioncommon "github.com/answerdev/answer/internal/service/question_common"
"github.com/answerdev/answer/internal/service/revision_common" "github.com/answerdev/answer/internal/service/revision_common"
"github.com/answerdev/answer/internal/service/role"
usercommon "github.com/answerdev/answer/internal/service/user_common" usercommon "github.com/answerdev/answer/internal/service/user_common"
"github.com/answerdev/answer/pkg/encryption" "github.com/answerdev/answer/pkg/encryption"
"github.com/segmentfault/pacman/errors" "github.com/segmentfault/pacman/errors"
@ -39,6 +40,7 @@ type AnswerService struct {
AnswerCommon *answercommon.AnswerCommon AnswerCommon *answercommon.AnswerCommon
voteRepo activity_common.VoteRepo voteRepo activity_common.VoteRepo
emailService *export.EmailService emailService *export.EmailService
roleService *role.UserRoleRelService
} }
func NewAnswerService( func NewAnswerService(
@ -53,6 +55,7 @@ func NewAnswerService(
answerCommon *answercommon.AnswerCommon, answerCommon *answercommon.AnswerCommon,
voteRepo activity_common.VoteRepo, voteRepo activity_common.VoteRepo,
emailService *export.EmailService, emailService *export.EmailService,
roleService *role.UserRoleRelService,
) *AnswerService { ) *AnswerService {
return &AnswerService{ return &AnswerService{
answerRepo: answerRepo, answerRepo: answerRepo,
@ -66,6 +69,7 @@ func NewAnswerService(
AnswerCommon: answerCommon, AnswerCommon: answerCommon,
voteRepo: voteRepo, voteRepo: voteRepo,
emailService: emailService, emailService: emailService,
roleService: roleService,
} }
} }
@ -82,7 +86,11 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns
if answerInfo.Status == entity.AnswerStatusDeleted { if answerInfo.Status == entity.AnswerStatusDeleted {
return nil return nil
} }
if !req.IsAdmin { roleID, err := as.roleService.GetUserRole(ctx, req.UserID)
if err != nil {
return err
}
if roleID != role.RoleAdminID && roleID != role.RoleModeratorID {
if answerInfo.UserID != req.UserID { if answerInfo.UserID != req.UserID {
return errors.BadRequest(reason.AnswerCannotDeleted) return errors.BadRequest(reason.AnswerCannotDeleted)
} }

View File

@ -45,7 +45,7 @@ func (as *AuthService) GetUserCacheInfo(ctx context.Context, accessToken string)
log.Debugf("user status updated: %+v", cacheInfo) log.Debugf("user status updated: %+v", cacheInfo)
userCacheInfo.UserStatus = cacheInfo.UserStatus userCacheInfo.UserStatus = cacheInfo.UserStatus
userCacheInfo.EmailStatus = cacheInfo.EmailStatus userCacheInfo.EmailStatus = cacheInfo.EmailStatus
userCacheInfo.IsAdmin = cacheInfo.IsAdmin userCacheInfo.RoleID = cacheInfo.RoleID
// update current user cache info // update current user cache info
err := as.authRepo.SetUserCacheInfo(ctx, accessToken, userCacheInfo) err := as.authRepo.SetUserCacheInfo(ctx, accessToken, userCacheInfo)
if err != nil { if err != nil {

View File

@ -244,6 +244,17 @@ func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
revisionDTO := &schema.AddRevisionDTO{
UserID: req.UserID,
ObjectID: tagInfo.ID,
Title: tagInfo.SlugName,
}
tagInfoJson, _ := json.Marshal(tagInfo)
revisionDTO.Content = string(tagInfoJson)
_, err = ts.revisionService.AddRevision(ctx, revisionDTO, true)
if err != nil {
return nil, err
}
return &schema.AddTagResp{SlugName: tagInfo.SlugName}, nil return &schema.AddTagResp{SlugName: tagInfo.SlugName}, nil
} }

View File

@ -81,7 +81,7 @@ func (us *UserService) GetUserInfoByUserID(ctx context.Context, token, userID st
resp = &schema.GetUserToSetShowResp{} resp = &schema.GetUserToSetShowResp{}
resp.GetFromUserEntity(userInfo) resp.GetFromUserEntity(userInfo)
resp.AccessToken = token resp.AccessToken = token
resp.IsAdmin = roleID == role.RoleAdminID resp.RoleID = roleID
return resp, nil return resp, nil
} }
@ -131,14 +131,14 @@ func (us *UserService) EmailLogin(ctx context.Context, req *schema.UserEmailLogi
UserID: userInfo.ID, UserID: userInfo.ID,
EmailStatus: userInfo.MailStatus, EmailStatus: userInfo.MailStatus,
UserStatus: userInfo.Status, UserStatus: userInfo.Status,
IsAdmin: roleID == role.RoleAdminID, RoleID: roleID,
} }
resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp.IsAdmin = userCacheInfo.IsAdmin resp.RoleID = userCacheInfo.RoleID
if resp.IsAdmin { if resp.RoleID == role.RoleAdminID {
err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, userCacheInfo) err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, userCacheInfo)
if err != nil { if err != nil {
return nil, err return nil, err
@ -365,14 +365,14 @@ func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo
UserID: userInfo.ID, UserID: userInfo.ID,
EmailStatus: userInfo.MailStatus, EmailStatus: userInfo.MailStatus,
UserStatus: userInfo.Status, UserStatus: userInfo.Status,
IsAdmin: roleID == role.RoleAdminID, RoleID: roleID,
} }
resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
resp.IsAdmin = userCacheInfo.IsAdmin resp.RoleID = userCacheInfo.RoleID
if resp.IsAdmin { if resp.RoleID == role.RoleAdminID {
err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID}) err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID})
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -457,7 +457,7 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri
UserID: userInfo.ID, UserID: userInfo.ID,
EmailStatus: userInfo.MailStatus, EmailStatus: userInfo.MailStatus,
UserStatus: userInfo.Status, UserStatus: userInfo.Status,
IsAdmin: roleID == role.RoleAdminID, RoleID: roleID,
} }
resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo)
if err != nil { if err != nil {
@ -467,8 +467,8 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri
if err = us.authService.SetUserStatus(ctx, userCacheInfo); err != nil { if err = us.authService.SetUserStatus(ctx, userCacheInfo); err != nil {
return nil, err return nil, err
} }
resp.IsAdmin = userCacheInfo.IsAdmin resp.RoleID = userCacheInfo.RoleID
if resp.IsAdmin { if resp.RoleID == role.RoleAdminID {
err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID}) err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID})
if err != nil { if err != nil {
return nil, err return nil, err