From ee3fb56d54d6eb16be840d04a26a19e159ac1861 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Thu, 2 Mar 2023 17:00:16 +0800 Subject: [PATCH 1/3] feat(tag): Add create tag API --- i18n/en_US.yaml | 2 ++ internal/base/reason/reason.go | 1 + internal/controller/tag_controller.go | 36 +++++++++++++++++++++++ internal/router/answer_api_router.go | 1 + internal/schema/tag_schema.go | 24 +++++++++++++++ internal/service/tag_common/tag_common.go | 21 +++++++++++++ 6 files changed, 85 insertions(+) diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 69a39c12..85d01f54 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -98,6 +98,8 @@ backend: not_found: other: Report not found. tag: + already_exist: + other: Tag already exists. not_found: other: Tag not found. recommend_tag_not_found: diff --git a/internal/base/reason/reason.go b/internal/base/reason/reason.go index a33e33cc..13801cea 100644 --- a/internal/base/reason/reason.go +++ b/internal/base/reason/reason.go @@ -44,6 +44,7 @@ const ( TagNotContainSynonym = "error.tag.not_contain_synonym_tags" TagCannotUpdate = "error.tag.cannot_update" TagIsUsedCannotDelete = "error.tag.is_used_cannot_delete" + TagAlreadyExist = "error.tag.already_exist" RankFailToMeetTheCondition = "error.rank.fail_to_meet_the_condition" ThemeNotFound = "error.theme.not_found" LangNotFound = "error.lang.not_found" diff --git a/internal/controller/tag_controller.go b/internal/controller/tag_controller.go index bc2a9a5b..70e63d20 100644 --- a/internal/controller/tag_controller.go +++ b/internal/controller/tag_controller.go @@ -98,6 +98,42 @@ func (tc *TagController) RemoveTag(ctx *gin.Context) { handler.HandleResponse(ctx, err, nil) } +// AddTag add tag +// @Summary add tag +// @Description add tag +// @Tags Tag +// @Accept json +// @Produce json +// @Param data body schema.AddTagReq true "tag" +// @Success 200 {object} handler.RespBody +// @Router /answer/api/v1/tag [post] +func (tc *TagController) AddTag(ctx *gin.Context) { + req := &schema.AddTagReq{} + if handler.BindAndCheck(ctx, req) { + return + } + + req.UserID = middleware.GetLoginUserIDFromContext(ctx) + canList, err := tc.rankService.CheckOperationPermissions(ctx, req.UserID, []string{ + permission.TagAdd, + }) + if err != nil { + handler.HandleResponse(ctx, err, nil) + return + } + if !canList[0] { + handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil) + return + } + + err = tc.tagCommonService.AddTag(ctx, req) + if err != nil { + handler.HandleResponse(ctx, err, nil) + } else { + handler.HandleResponse(ctx, err, nil) + } +} + // UpdateTag update tag // @Summary update tag // @Description update tag diff --git a/internal/router/answer_api_router.go b/internal/router/answer_api_router.go index b2cb22ce..dc3c271d 100644 --- a/internal/router/answer_api_router.go +++ b/internal/router/answer_api_router.go @@ -175,6 +175,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) { // tag r.GET("/question/tags", a.tagController.SearchTagLike) + r.POST("/tag", a.tagController.AddTag) r.PUT("/tag", a.tagController.UpdateTag) r.DELETE("/tag", a.tagController.RemoveTag) r.PUT("/tag/synonym", a.tagController.UpdateTagSynonym) diff --git a/internal/schema/tag_schema.go b/internal/schema/tag_schema.go index cc046b37..c5d1c7c1 100644 --- a/internal/schema/tag_schema.go +++ b/internal/schema/tag_schema.go @@ -161,6 +161,30 @@ type RemoveTagReq struct { UserID string `json:"-"` } +// AddTagReq add tag request +type AddTagReq struct { + // slug_name + SlugName string `validate:"required,gt=0,lte=35" json:"slug_name"` + // display_name + DisplayName string `validate:"required,gt=0,lte=35" json:"display_name"` + // original text + OriginalText string `validate:"required" json:"original_text"` + // parsed text + ParsedText string `json:"-"` + // user id + UserID string `json:"-"` +} + +func (req *AddTagReq) Check() (errFields []*validator.FormErrorField, err error) { + req.ParsedText = converter.Markdown2HTML(req.OriginalText) + return nil, nil +} + +// AddTagResp add tag response +type AddTagResp struct { + TagID string `json:"tag_id"` +} + // UpdateTagReq update tag request type UpdateTagReq struct { // tag_id diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index da7ec466..82148b53 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -222,6 +222,27 @@ func (ts *TagCommonService) GetObjectTag(ctx context.Context, objectId string) ( return ts.TagFormat(ctx, tagsInfoList) } +// AddTag get object tag +func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) (err error) { + _, exist, err := ts.GetTagBySlugName(ctx, req.SlugName) + if err != nil { + return err + } + if exist { + return errors.BadRequest(reason.TagAlreadyExist) + } + tagInfo := &entity.Tag{ + SlugName: req.SlugName, + DisplayName: req.DisplayName, + OriginalText: req.OriginalText, + ParsedText: req.ParsedText, + Status: entity.TagStatusAvailable, + UserID: req.UserID, + } + tagList := []*entity.Tag{tagInfo} + return ts.tagCommonRepo.AddTagList(ctx, tagList) +} + // AddTagList get object tag func (ts *TagCommonService) AddTagList(ctx context.Context, tagList []*entity.Tag) (err error) { return ts.tagCommonRepo.AddTagList(ctx, tagList) From a90495c9f1a2b92f8378a01b77c73e9910b1a3ab Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 3 Mar 2023 14:40:30 +0800 Subject: [PATCH 2/3] feat(tag): Add tag response the tag slug name --- docs/docs.go | 59 +++++++++++++++++++++++ docs/swagger.json | 59 +++++++++++++++++++++++ docs/swagger.yaml | 41 ++++++++++++++++ internal/controller/tag_controller.go | 8 +-- internal/schema/tag_schema.go | 5 +- internal/service/tag_common/tag_common.go | 12 +++-- 6 files changed, 172 insertions(+), 12 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index 1dedea4d..9f73acfa 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -3932,6 +3932,38 @@ const docTemplate = `{ } } }, + "post": { + "description": "add tag", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Tag" + ], + "summary": "add tag", + "parameters": [ + { + "description": "tag", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddTagReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, "delete": { "description": "delete tag", "consumes": [ @@ -5545,6 +5577,30 @@ const docTemplate = `{ } } }, + "schema.AddTagReq": { + "type": "object", + "required": [ + "display_name", + "original_text", + "slug_name" + ], + "properties": { + "display_name": { + "description": "display_name", + "type": "string", + "maxLength": 35 + }, + "original_text": { + "description": "original text", + "type": "string" + }, + "slug_name": { + "description": "slug_name", + "type": "string", + "maxLength": 35 + } + } + }, "schema.AddUserReq": { "type": "object", "required": [ @@ -7173,6 +7229,9 @@ const docTemplate = `{ }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" + }, + "version": { + "type": "string" } } }, diff --git a/docs/swagger.json b/docs/swagger.json index ca8d737d..3ebb716e 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -3920,6 +3920,38 @@ } } }, + "post": { + "description": "add tag", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Tag" + ], + "summary": "add tag", + "parameters": [ + { + "description": "tag", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/schema.AddTagReq" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.RespBody" + } + } + } + }, "delete": { "description": "delete tag", "consumes": [ @@ -5533,6 +5565,30 @@ } } }, + "schema.AddTagReq": { + "type": "object", + "required": [ + "display_name", + "original_text", + "slug_name" + ], + "properties": { + "display_name": { + "description": "display_name", + "type": "string", + "maxLength": 35 + }, + "original_text": { + "description": "original text", + "type": "string" + }, + "slug_name": { + "description": "slug_name", + "type": "string", + "maxLength": 35 + } + } + }, "schema.AddUserReq": { "type": "object", "required": [ @@ -7161,6 +7217,9 @@ }, "theme": { "$ref": "#/definitions/schema.SiteThemeResp" + }, + "version": { + "type": "string" } } }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index da69a617..e0561059 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -174,6 +174,24 @@ definitions: - object_id - report_type type: object + schema.AddTagReq: + properties: + display_name: + description: display_name + maxLength: 35 + type: string + original_text: + description: original text + type: string + slug_name: + description: slug_name + maxLength: 35 + type: string + required: + - display_name + - original_text + - slug_name + type: object schema.AddUserReq: properties: display_name: @@ -1335,6 +1353,8 @@ definitions: $ref: '#/definitions/schema.SiteSeoReq' theme: $ref: '#/definitions/schema.SiteThemeResp' + version: + type: string type: object schema.SiteInterfaceReq: properties: @@ -4284,6 +4304,27 @@ paths: summary: get tag one tags: - Tag + post: + consumes: + - application/json + description: add tag + parameters: + - description: tag + in: body + name: data + required: true + schema: + $ref: '#/definitions/schema.AddTagReq' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.RespBody' + summary: add tag + tags: + - Tag put: consumes: - application/json diff --git a/internal/controller/tag_controller.go b/internal/controller/tag_controller.go index 70e63d20..55edc8ec 100644 --- a/internal/controller/tag_controller.go +++ b/internal/controller/tag_controller.go @@ -126,12 +126,8 @@ func (tc *TagController) AddTag(ctx *gin.Context) { return } - err = tc.tagCommonService.AddTag(ctx, req) - if err != nil { - handler.HandleResponse(ctx, err, nil) - } else { - handler.HandleResponse(ctx, err, nil) - } + resp, err := tc.tagCommonService.AddTag(ctx, req) + handler.HandleResponse(ctx, err, resp) } // UpdateTag update tag diff --git a/internal/schema/tag_schema.go b/internal/schema/tag_schema.go index c5d1c7c1..f4c61a74 100644 --- a/internal/schema/tag_schema.go +++ b/internal/schema/tag_schema.go @@ -168,7 +168,7 @@ type AddTagReq struct { // display_name DisplayName string `validate:"required,gt=0,lte=35" json:"display_name"` // original text - OriginalText string `validate:"required" json:"original_text"` + OriginalText string `validate:"required,gt=0,lte=65536" json:"original_text"` // parsed text ParsedText string `json:"-"` // user id @@ -177,12 +177,13 @@ type AddTagReq struct { func (req *AddTagReq) Check() (errFields []*validator.FormErrorField, err error) { req.ParsedText = converter.Markdown2HTML(req.OriginalText) + req.SlugName = strings.ToLower(req.SlugName) return nil, nil } // AddTagResp add tag response type AddTagResp struct { - TagID string `json:"tag_id"` + SlugName string `json:"slug_name"` } // UpdateTagReq update tag request diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 82148b53..094ce594 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -223,13 +223,13 @@ func (ts *TagCommonService) GetObjectTag(ctx context.Context, objectId string) ( } // AddTag get object tag -func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) (err error) { +func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) (resp *schema.AddTagResp, err error) { _, exist, err := ts.GetTagBySlugName(ctx, req.SlugName) if err != nil { - return err + return nil, err } if exist { - return errors.BadRequest(reason.TagAlreadyExist) + return nil, errors.BadRequest(reason.TagAlreadyExist) } tagInfo := &entity.Tag{ SlugName: req.SlugName, @@ -240,7 +240,11 @@ func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) ( UserID: req.UserID, } tagList := []*entity.Tag{tagInfo} - return ts.tagCommonRepo.AddTagList(ctx, tagList) + err = ts.tagCommonRepo.AddTagList(ctx, tagList) + if err != nil { + return nil, err + } + return &schema.AddTagResp{SlugName: tagInfo.SlugName}, nil } // AddTagList get object tag From 4759e8778f71eff4d044aa72a8056e80c8a92f99 Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Fri, 3 Mar 2023 16:59:34 +0800 Subject: [PATCH 3/3] feat(tag): Add revision when add tag --- cmd/answer/wire_gen.go | 2 +- docs/docs.go | 27 ++++++++-------------- docs/swagger.json | 27 ++++++++-------------- docs/swagger.yaml | 19 ++++++--------- internal/base/middleware/auth.go | 3 ++- internal/controller/activity_controller.go | 3 ++- internal/controller/answer_controller.go | 9 +++++--- internal/entity/auth_user_entity.go | 2 +- internal/schema/answer_schema.go | 5 ++-- internal/schema/user_schema.go | 10 +++----- internal/service/answer_service.go | 10 +++++++- internal/service/auth/auth.go | 2 +- internal/service/tag_common/tag_common.go | 11 +++++++++ internal/service/user_service.go | 20 ++++++++-------- 14 files changed, 76 insertions(+), 74 deletions(-) diff --git a/cmd/answer/wire_gen.go b/cmd/answer/wire_gen.go index 515efa46..807fd0ef 100644 --- a/cmd/answer/wire_gen.go +++ b/cmd/answer/wire_gen.go @@ -166,7 +166,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, questionActivityRepo) questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, revisionService, metaService, collectionCommon, answerActivityService, dataData) 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) answerController := controller.NewAnswerController(answerService, rankService, dashboardService) searchParser := search_parser.NewSearchParser(tagCommonService, userCommon) diff --git a/docs/docs.go b/docs/docs.go index 9f73acfa..b9186b54 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -5592,7 +5592,8 @@ const docTemplate = `{ }, "original_text": { "description": "original text", - "type": "string" + "type": "string", + "maxLength": 65536 }, "slug_name": { "description": "slug_name", @@ -5993,14 +5994,6 @@ const docTemplate = `{ "description": "user id", "type": "string" }, - "ip_info": { - "description": "ip info", - "type": "string" - }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "last_login_date": { "description": "last login date", "type": "integer" @@ -6484,10 +6477,6 @@ const docTemplate = `{ "description": "ip info", "type": "string" }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "language": { "description": "language", "type": "string" @@ -6520,6 +6509,10 @@ const docTemplate = `{ "description": "rank", "type": "integer" }, + "role_id": { + "description": "role id", + "type": "integer" + }, "status": { "description": "user status", "type": "string" @@ -6584,10 +6577,6 @@ const docTemplate = `{ "description": "ip info", "type": "string" }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "language": { "description": "language", "type": "string" @@ -6620,6 +6609,10 @@ const docTemplate = `{ "description": "rank", "type": "integer" }, + "role_id": { + "description": "role id", + "type": "integer" + }, "status": { "description": "user status", "type": "string" diff --git a/docs/swagger.json b/docs/swagger.json index 3ebb716e..00170a0a 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -5580,7 +5580,8 @@ }, "original_text": { "description": "original text", - "type": "string" + "type": "string", + "maxLength": 65536 }, "slug_name": { "description": "slug_name", @@ -5981,14 +5982,6 @@ "description": "user id", "type": "string" }, - "ip_info": { - "description": "ip info", - "type": "string" - }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "last_login_date": { "description": "last login date", "type": "integer" @@ -6472,10 +6465,6 @@ "description": "ip info", "type": "string" }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "language": { "description": "language", "type": "string" @@ -6508,6 +6497,10 @@ "description": "rank", "type": "integer" }, + "role_id": { + "description": "role id", + "type": "integer" + }, "status": { "description": "user status", "type": "string" @@ -6572,10 +6565,6 @@ "description": "ip info", "type": "string" }, - "is_admin": { - "description": "is admin", - "type": "boolean" - }, "language": { "description": "language", "type": "string" @@ -6608,6 +6597,10 @@ "description": "rank", "type": "integer" }, + "role_id": { + "description": "role id", + "type": "integer" + }, "status": { "description": "user status", "type": "string" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e0561059..b64361ca 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -182,6 +182,7 @@ definitions: type: string original_text: description: original text + maxLength: 65536 type: string slug_name: description: slug_name @@ -472,12 +473,6 @@ definitions: id: description: user id type: string - ip_info: - description: ip info - type: string - is_admin: - description: is admin - type: boolean last_login_date: description: last login date type: integer @@ -824,9 +819,6 @@ definitions: ip_info: description: ip info type: string - is_admin: - description: is admin - type: boolean language: description: language type: string @@ -851,6 +843,9 @@ definitions: rank: description: rank type: integer + role_id: + description: role id + type: integer status: description: user status type: string @@ -898,9 +893,6 @@ definitions: ip_info: description: ip info type: string - is_admin: - description: is admin - type: boolean language: description: language type: string @@ -925,6 +917,9 @@ definitions: rank: description: rank type: integer + role_id: + description: role id + type: integer status: description: user status type: string diff --git a/internal/base/middleware/auth.go b/internal/base/middleware/auth.go index a7796c87..b2150e38 100644 --- a/internal/base/middleware/auth.go +++ b/internal/base/middleware/auth.go @@ -4,6 +4,7 @@ import ( "strings" "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/base/handler" @@ -154,7 +155,7 @@ func GetIsAdminFromContext(ctx *gin.Context) (isAdmin bool) { if userInfo == nil { return false } - return userInfo.IsAdmin + return userInfo.RoleID == role.RoleAdminID } // GetUserInfoFromContext get user info from context diff --git a/internal/controller/activity_controller.go b/internal/controller/activity_controller.go index 917e1634..78140b67 100644 --- a/internal/controller/activity_controller.go +++ b/internal/controller/activity_controller.go @@ -6,6 +6,7 @@ import ( "github.com/answerdev/answer/internal/schema" "github.com/answerdev/answer/internal/service/activity" "github.com/answerdev/answer/internal/service/activity_common" + "github.com/answerdev/answer/internal/service/role" "github.com/gin-gonic/gin" ) @@ -40,7 +41,7 @@ func (ac *ActivityController) GetObjectTimeline(ctx *gin.Context) { req.UserID = middleware.GetLoginUserIDFromContext(ctx) if userInfo := middleware.GetUserInfoFromContext(ctx); userInfo != nil { - req.IsAdmin = userInfo.IsAdmin + req.IsAdmin = userInfo.RoleID == role.RoleAdminID } resp, err := ac.activityService.GetObjectTimeline(ctx, req) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 684988ef..28b61141 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -51,13 +51,16 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) { } req.UserID = middleware.GetLoginUserIDFromContext(ctx) - req.IsAdmin = middleware.GetIsAdminFromContext(ctx) - can, err := ac.rankService.CheckOperationPermission(ctx, req.UserID, permission.AnswerDelete, req.ID) + objectOwner := ac.rankService.CheckOperationObjectOwner(ctx, req.UserID, req.ID) + canList, err := ac.rankService.CheckOperationPermissions(ctx, req.UserID, []string{ + permission.AnswerDelete, + }) if err != nil { handler.HandleResponse(ctx, err, nil) return } - if !can { + req.CanDelete = canList[0] || objectOwner + if !req.CanDelete { handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), nil) return } diff --git a/internal/entity/auth_user_entity.go b/internal/entity/auth_user_entity.go index f71d79df..a417cd2a 100644 --- a/internal/entity/auth_user_entity.go +++ b/internal/entity/auth_user_entity.go @@ -5,5 +5,5 @@ type UserCacheInfo struct { UserID string `json:"user_id"` UserStatus int `json:"user_status"` EmailStatus int `json:"email_status"` - IsAdmin bool `json:"is_admin"` + RoleID int `json:"role_id"` } diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 7fc6a12d..7efd6e67 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -10,8 +10,9 @@ type RemoveAnswerReq struct { // answer id ID string `validate:"required" json:"id"` // user id - UserID string `json:"-"` - IsAdmin bool `json:"-"` + UserID string `json:"-"` + // whether user can delete it + CanDelete bool `json:"-"` } const ( diff --git a/internal/schema/user_schema.go b/internal/schema/user_schema.go index 308568c8..cb356584 100644 --- a/internal/schema/user_schema.go +++ b/internal/schema/user_schema.go @@ -66,8 +66,8 @@ type GetUserResp struct { Language string `json:"language"` // access token AccessToken string `json:"access_token"` - // is admin - IsAdmin bool `json:"is_admin"` + // role id + RoleID int `json:"role_id"` // user status Status string `json:"status"` } @@ -159,11 +159,7 @@ type GetOtherUserInfoByUsernameResp struct { // website Website string `json:"website"` // location - Location string `json:"location"` - // ip info - IPInfo string `json:"ip_info"` - // is admin - IsAdmin bool `json:"is_admin"` + Location string `json:"location"` Status string `json:"status"` StatusMsg string `json:"status_msg,omitempty"` } diff --git a/internal/service/answer_service.go b/internal/service/answer_service.go index 974482c9..738e4a55 100644 --- a/internal/service/answer_service.go +++ b/internal/service/answer_service.go @@ -20,6 +20,7 @@ import ( "github.com/answerdev/answer/internal/service/permission" questioncommon "github.com/answerdev/answer/internal/service/question_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" "github.com/answerdev/answer/pkg/encryption" "github.com/segmentfault/pacman/errors" @@ -39,6 +40,7 @@ type AnswerService struct { AnswerCommon *answercommon.AnswerCommon voteRepo activity_common.VoteRepo emailService *export.EmailService + roleService *role.UserRoleRelService } func NewAnswerService( @@ -53,6 +55,7 @@ func NewAnswerService( answerCommon *answercommon.AnswerCommon, voteRepo activity_common.VoteRepo, emailService *export.EmailService, + roleService *role.UserRoleRelService, ) *AnswerService { return &AnswerService{ answerRepo: answerRepo, @@ -66,6 +69,7 @@ func NewAnswerService( AnswerCommon: answerCommon, voteRepo: voteRepo, emailService: emailService, + roleService: roleService, } } @@ -82,7 +86,11 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns if answerInfo.Status == entity.AnswerStatusDeleted { 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 { return errors.BadRequest(reason.AnswerCannotDeleted) } diff --git a/internal/service/auth/auth.go b/internal/service/auth/auth.go index e500f0b9..75f67944 100644 --- a/internal/service/auth/auth.go +++ b/internal/service/auth/auth.go @@ -45,7 +45,7 @@ func (as *AuthService) GetUserCacheInfo(ctx context.Context, accessToken string) log.Debugf("user status updated: %+v", cacheInfo) userCacheInfo.UserStatus = cacheInfo.UserStatus userCacheInfo.EmailStatus = cacheInfo.EmailStatus - userCacheInfo.IsAdmin = cacheInfo.IsAdmin + userCacheInfo.RoleID = cacheInfo.RoleID // update current user cache info err := as.authRepo.SetUserCacheInfo(ctx, accessToken, userCacheInfo) if err != nil { diff --git a/internal/service/tag_common/tag_common.go b/internal/service/tag_common/tag_common.go index 094ce594..6a390a0f 100644 --- a/internal/service/tag_common/tag_common.go +++ b/internal/service/tag_common/tag_common.go @@ -244,6 +244,17 @@ func (ts *TagCommonService) AddTag(ctx context.Context, req *schema.AddTagReq) ( if err != nil { 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 } diff --git a/internal/service/user_service.go b/internal/service/user_service.go index e7bd4374..a578f456 100644 --- a/internal/service/user_service.go +++ b/internal/service/user_service.go @@ -81,7 +81,7 @@ func (us *UserService) GetUserInfoByUserID(ctx context.Context, token, userID st resp = &schema.GetUserToSetShowResp{} resp.GetFromUserEntity(userInfo) resp.AccessToken = token - resp.IsAdmin = roleID == role.RoleAdminID + resp.RoleID = roleID return resp, nil } @@ -131,14 +131,14 @@ func (us *UserService) EmailLogin(ctx context.Context, req *schema.UserEmailLogi UserID: userInfo.ID, EmailStatus: userInfo.MailStatus, UserStatus: userInfo.Status, - IsAdmin: roleID == role.RoleAdminID, + RoleID: roleID, } resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) if err != nil { return nil, err } - resp.IsAdmin = userCacheInfo.IsAdmin - if resp.IsAdmin { + resp.RoleID = userCacheInfo.RoleID + if resp.RoleID == role.RoleAdminID { err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, userCacheInfo) if err != nil { return nil, err @@ -365,14 +365,14 @@ func (us *UserService) UserRegisterByEmail(ctx context.Context, registerUserInfo UserID: userInfo.ID, EmailStatus: userInfo.MailStatus, UserStatus: userInfo.Status, - IsAdmin: roleID == role.RoleAdminID, + RoleID: roleID, } resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) if err != nil { return nil, nil, err } - resp.IsAdmin = userCacheInfo.IsAdmin - if resp.IsAdmin { + resp.RoleID = userCacheInfo.RoleID + if resp.RoleID == role.RoleAdminID { err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID}) if err != nil { return nil, nil, err @@ -457,7 +457,7 @@ func (us *UserService) UserVerifyEmail(ctx context.Context, req *schema.UserVeri UserID: userInfo.ID, EmailStatus: userInfo.MailStatus, UserStatus: userInfo.Status, - IsAdmin: roleID == role.RoleAdminID, + RoleID: roleID, } resp.AccessToken, err = us.authService.SetUserCacheInfo(ctx, userCacheInfo) 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 { return nil, err } - resp.IsAdmin = userCacheInfo.IsAdmin - if resp.IsAdmin { + resp.RoleID = userCacheInfo.RoleID + if resp.RoleID == role.RoleAdminID { err = us.authService.SetAdminUserCacheInfo(ctx, resp.AccessToken, &entity.UserCacheInfo{UserID: userInfo.ID}) if err != nil { return nil, err