mirror of https://gitee.com/answerdev/answer.git
Merge branch 'feat/0.5.0/timeline_ai' into test
This commit is contained in:
commit
a7f9d999cc
|
@ -121,9 +121,10 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
questionRepo := question.NewQuestionRepo(dataData, uniqueIDRepo)
|
||||
tagCommonRepo := tag_common.NewTagCommonRepo(dataData, uniqueIDRepo)
|
||||
tagRelRepo := tag.NewTagRelRepo(dataData)
|
||||
tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo)
|
||||
revisionRepo := revision.NewRevisionRepo(dataData, uniqueIDRepo)
|
||||
revisionService := revision_common.NewRevisionService(revisionRepo, userRepo)
|
||||
tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, revisionService, siteInfoCommonService)
|
||||
tagCommonService := tag_common2.NewTagCommonService(tagCommonRepo, tagRelRepo, tagRepo, revisionService, siteInfoCommonService)
|
||||
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService)
|
||||
voteRepo := activity_common.NewVoteRepo(dataData, activityRepo)
|
||||
commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo)
|
||||
|
@ -135,7 +136,6 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
serviceVoteRepo := activity.NewVoteRepo(dataData, uniqueIDRepo, configRepo, activityRepo, userRankRepo, voteRepo)
|
||||
voteService := service.NewVoteService(serviceVoteRepo, uniqueIDRepo, configRepo, questionRepo, answerRepo, commentCommonRepo, objService)
|
||||
voteController := controller.NewVoteController(voteService)
|
||||
tagRepo := tag.NewTagRepo(dataData, uniqueIDRepo)
|
||||
followRepo := activity_common.NewFollowRepo(dataData, uniqueIDRepo, activityRepo)
|
||||
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService)
|
||||
tagController := controller.NewTagController(tagService, tagCommonService, rankService)
|
||||
|
@ -163,7 +163,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
|||
searchRepo := search_common.NewSearchRepo(dataData, uniqueIDRepo, userCommon)
|
||||
searchService := service.NewSearchService(searchParser, searchRepo)
|
||||
searchController := controller.NewSearchController(searchService)
|
||||
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService)
|
||||
serviceRevisionService := service.NewRevisionService(revisionRepo, userCommon, questionCommon, answerService, objService, questionRepo, answerRepo, tagRepo, tagCommonService)
|
||||
revisionController := controller.NewRevisionController(serviceRevisionService, rankService)
|
||||
rankController := controller.NewRankController(rankService)
|
||||
commonRepo := common.NewCommonRepo(dataData, uniqueIDRepo)
|
||||
|
|
|
@ -90,6 +90,8 @@ backend:
|
|||
other: "Please enter at least one required tag."
|
||||
not_contain_synonym_tags:
|
||||
other: "Should not contain synonym tags."
|
||||
cannot_update:
|
||||
other: "No permission to update."
|
||||
theme:
|
||||
not_found:
|
||||
other: "Theme not found."
|
||||
|
|
|
@ -113,15 +113,20 @@ func (am *AuthUserMiddleware) CmsAuth() gin.HandlerFunc {
|
|||
|
||||
// GetLoginUserIDFromContext get user id from context
|
||||
func GetLoginUserIDFromContext(ctx *gin.Context) (userID string) {
|
||||
userInfo, exist := ctx.Get(ctxUUIDKey)
|
||||
if !exist {
|
||||
userInfo := GetUserInfoFromContext(ctx)
|
||||
if userInfo == nil {
|
||||
return ""
|
||||
}
|
||||
u, ok := userInfo.(*entity.UserCacheInfo)
|
||||
if !ok {
|
||||
return ""
|
||||
return userInfo.UserID
|
||||
}
|
||||
|
||||
// GetIsAdminFromContext get user is admin from context
|
||||
func GetIsAdminFromContext(ctx *gin.Context) (isAdmin bool) {
|
||||
userInfo := GetUserInfoFromContext(ctx)
|
||||
if userInfo == nil {
|
||||
return false
|
||||
}
|
||||
return u.UserID
|
||||
return userInfo.IsAdmin
|
||||
}
|
||||
|
||||
// GetUserInfoFromContext get user info from context
|
||||
|
|
|
@ -41,6 +41,7 @@ const (
|
|||
ObjectNotFound = "error.object.not_found"
|
||||
TagNotFound = "error.tag.not_found"
|
||||
TagNotContainSynonym = "error.tag.not_contain_synonym_tags"
|
||||
TagCannotUpdate = "error.tag.cannot_update"
|
||||
RankFailToMeetTheCondition = "error.rank.fail_to_meet_the_condition"
|
||||
ThemeNotFound = "error.theme.not_found"
|
||||
LangNotFound = "error.lang.not_found"
|
||||
|
|
|
@ -50,12 +50,12 @@ func (ac *AnswerController) RemoveAnswer(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerDeleteRank); err != nil || !can {
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerDeleteRank, req.ID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
|
||||
err := ac.answerService.RemoveAnswer(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ func (ac *AnswerController) Add(ctx *gin.Context) {
|
|||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerAddRank); err != nil || !can {
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerAddRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -147,10 +147,9 @@ func (ac *AnswerController) Update(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerEditRank); err != nil || !can {
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerEditRank, req.ID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -192,10 +191,7 @@ func (ac *AnswerController) AnswerList(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.LoginUserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
if userinfo != nil {
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
}
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
list, count, err := ac.answerService.SearchList(ctx, req)
|
||||
if err != nil {
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
|
@ -224,7 +220,7 @@ func (ac *AnswerController) Adopted(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerAcceptRank); err != nil || !can {
|
||||
if can, err := ac.rankService.CheckRankPermission(ctx, req.UserID, rank.AnswerAcceptRank, req.QuestionID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ func (cc *CommentController) AddComment(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentAddRank); err != nil || !can {
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentAddRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func (cc *CommentController) RemoveComment(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentDeleteRank); err != nil || !can {
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentDeleteRank, req.CommentID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func (cc *CommentController) UpdateComment(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentEditRank); err != nil || !can {
|
||||
if can, err := cc.rankService.CheckRankPermission(ctx, req.UserID, rank.CommentEditRank, req.UserID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -42,12 +42,11 @@ func (qc *QuestionController) RemoveQuestion(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionDeleteRank); err != nil || !can {
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionDeleteRank, req.ID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, errors.Forbidden(reason.RankFailToMeetTheCondition), errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
|
||||
err := qc.questionService.RemoveQuestion(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
|
@ -69,8 +68,7 @@ func (qc *QuestionController) CloseQuestion(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
err := qc.questionService.CloseQuestion(ctx, req)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
}
|
||||
|
@ -85,17 +83,16 @@ func (qc *QuestionController) CloseQuestion(ctx *gin.Context) {
|
|||
// @Param id query string true "Question TagID" default(1)
|
||||
// @Success 200 {string} string ""
|
||||
// @Router /answer/api/v1/question/info [get]
|
||||
func (qc *QuestionController) GetQuestion(c *gin.Context) {
|
||||
id := c.Query("id")
|
||||
ctx := context.Background()
|
||||
userID := middleware.GetLoginUserIDFromContext(c)
|
||||
userinfo := middleware.GetUserInfoFromContext(c)
|
||||
info, err := qc.questionService.GetQuestion(ctx, id, userID, true, userinfo.IsAdmin)
|
||||
func (qc *QuestionController) GetQuestion(ctx *gin.Context) {
|
||||
id := ctx.Query("id")
|
||||
userID := middleware.GetLoginUserIDFromContext(ctx)
|
||||
isAdmin := middleware.GetIsAdminFromContext(ctx)
|
||||
info, err := qc.questionService.GetQuestion(ctx, id, userID, true, isAdmin)
|
||||
if err != nil {
|
||||
handler.HandleResponse(c, err, nil)
|
||||
handler.HandleResponse(ctx, err, nil)
|
||||
return
|
||||
}
|
||||
handler.HandleResponse(c, nil, info)
|
||||
handler.HandleResponse(ctx, nil, info)
|
||||
}
|
||||
|
||||
// SimilarQuestion godoc
|
||||
|
@ -193,7 +190,7 @@ func (qc *QuestionController) AddQuestion(ctx *gin.Context) {
|
|||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionAddRank); err != nil || !can {
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionAddRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -218,9 +215,8 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionEditRank); err != nil || !can {
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionEditRank, req.ID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -238,20 +234,20 @@ func (qc *QuestionController) UpdateQuestion(ctx *gin.Context) {
|
|||
// @Security ApiKeyAuth
|
||||
// @Param id query string true "id" default(string)
|
||||
// @Success 200 {object} handler.RespBody
|
||||
// @Router /answer/api/v1/question/edit/check [get]
|
||||
// @Router /answer/api/v1/revisions/edit/check [get]
|
||||
func (qc *QuestionController) CheckCanUpdateQuestion(ctx *gin.Context) {
|
||||
id := ctx.Query("id")
|
||||
req := &schema.CheckCanQuestionUpdate{}
|
||||
req.ID = id
|
||||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionEditRank); err != nil || !can {
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
if can, err := qc.rankService.CheckRankPermission(ctx, req.UserID, rank.QuestionEditRank, req.ID); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := qc.questionService.CheckCanUpdateQuestion(ctx, req)
|
||||
resp, err := qc.questionService.CheckCanUpdate(ctx, req)
|
||||
handler.HandleResponse(ctx, err, gin.H{
|
||||
"unreviewed": resp,
|
||||
})
|
||||
|
|
|
@ -40,7 +40,7 @@ func (rc *ReportController) AddReport(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, req.UserID, rank.ReportAddRank); err != nil || !can {
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, req.UserID, rank.ReportAddRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ func (rc *RevisionController) GetUnreviewedRevisionList(ctx *gin.Context) {
|
|||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
if !userinfo.IsAdmin {
|
||||
userID := middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, userID, rank.UnreviewedRevisionListRank); err != nil || !can {
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, userID, rank.UnreviewedRevisionListRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func (rc *RevisionController) RevisionAudit(ctx *gin.Context) {
|
|||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
if !userinfo.IsAdmin {
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, req.UserID, rank.RevisionAuditRank); err != nil || !can {
|
||||
if can, err := rc.rankService.CheckRankPermission(ctx, req.UserID, rank.RevisionAuditRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -42,8 +42,7 @@ func (tc *TagController) SearchTagLike(ctx *gin.Context) {
|
|||
if handler.BindAndCheck(ctx, req) {
|
||||
return
|
||||
}
|
||||
userinfo := middleware.GetUserInfoFromContext(ctx)
|
||||
req.IsAdmin = userinfo.IsAdmin
|
||||
req.IsAdmin = middleware.GetIsAdminFromContext(ctx)
|
||||
resp, err := tc.tagCommonService.SearchTagLike(ctx, req)
|
||||
handler.HandleResponse(ctx, err, resp)
|
||||
}
|
||||
|
@ -64,7 +63,7 @@ func (tc *TagController) RemoveTag(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagDeleteRank); err != nil || !can {
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagDeleteRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -89,7 +88,7 @@ func (tc *TagController) UpdateTag(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagEditRank); err != nil || !can {
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagEditRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
@ -191,7 +190,7 @@ func (tc *TagController) UpdateTagSynonym(ctx *gin.Context) {
|
|||
}
|
||||
|
||||
req.UserID = middleware.GetLoginUserIDFromContext(ctx)
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagSynonymRank); err != nil || !can {
|
||||
if can, err := tc.rankService.CheckRankPermission(ctx, req.UserID, rank.TagSynonymRank, ""); err != nil || !can {
|
||||
handler.HandleResponse(ctx, err, errors.Forbidden(reason.RankFailToMeetTheCondition))
|
||||
return
|
||||
}
|
||||
|
|
|
@ -471,20 +471,6 @@ func (sr *searchRepo) parseResult(ctx context.Context, res []map[string][]byte)
|
|||
return
|
||||
}
|
||||
|
||||
// userBasicInfoFormat
|
||||
func (sr *searchRepo) userBasicInfoFormat(ctx context.Context, dbinfo *entity.User) *schema.UserBasicInfo {
|
||||
return &schema.UserBasicInfo{
|
||||
ID: dbinfo.ID,
|
||||
Username: dbinfo.Username,
|
||||
Rank: dbinfo.Rank,
|
||||
DisplayName: dbinfo.DisplayName,
|
||||
Avatar: dbinfo.Avatar,
|
||||
Website: dbinfo.Website,
|
||||
Location: dbinfo.Location,
|
||||
IPInfo: dbinfo.IPInfo,
|
||||
}
|
||||
}
|
||||
|
||||
func addRelevanceField(searchFields, words, fields []string) (res []string, args []interface{}) {
|
||||
relevanceRes := []string{}
|
||||
args = []interface{}{}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/service/tag"
|
||||
"github.com/answerdev/answer/internal/service/tag_common"
|
||||
"github.com/answerdev/answer/internal/service/unique"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"xorm.io/builder"
|
||||
|
@ -22,7 +22,7 @@ type tagRepo struct {
|
|||
func NewTagRepo(
|
||||
data *data.Data,
|
||||
uniqueIDRepo unique.UniqueIDRepo,
|
||||
) tag.TagRepo {
|
||||
) tag_common.TagRepo {
|
||||
return &tagRepo{
|
||||
data: data,
|
||||
uniqueIDRepo: uniqueIDRepo,
|
||||
|
|
|
@ -147,6 +147,7 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
//revisions
|
||||
r.GET("/revisions/unreviewed", a.revisionController.GetUnreviewedRevisionList)
|
||||
r.PUT("/revisions/audit", a.revisionController.RevisionAudit)
|
||||
r.GET("/revisions/edit/check", a.questionController.CheckCanUpdateQuestion)
|
||||
|
||||
// comment
|
||||
r.POST("/comment", a.commentController.AddComment)
|
||||
|
@ -177,7 +178,6 @@ func (a *AnswerAPIRouter) RegisterAnswerAPIRouter(r *gin.RouterGroup) {
|
|||
// question
|
||||
r.POST("/question", a.questionController.AddQuestion)
|
||||
r.PUT("/question", a.questionController.UpdateQuestion)
|
||||
r.GET("/question/edit/check", a.questionController.CheckCanUpdateQuestion)
|
||||
r.DELETE("/question", a.questionController.RemoveQuestion)
|
||||
r.PUT("/question/status", a.questionController.CloseQuestion)
|
||||
r.GET("/question/similar", a.questionController.SearchByTitleLike)
|
||||
|
|
|
@ -2,15 +2,15 @@ package schema
|
|||
|
||||
// SimpleObjectInfo simple object info
|
||||
type SimpleObjectInfo struct {
|
||||
ObjectID string `json:"object_id"`
|
||||
ObjectCreator string `json:"object_creator"`
|
||||
QuestionID string `json:"question_id"`
|
||||
AnswerID string `json:"answer_id"`
|
||||
CommentID string `json:"comment_id"`
|
||||
TagID string `json:"tag_id"`
|
||||
ObjectType string `json:"object_type"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
ObjectID string `json:"object_id"`
|
||||
ObjectCreatorUserID string `json:"object_creator_user_id"`
|
||||
QuestionID string `json:"question_id"`
|
||||
AnswerID string `json:"answer_id"`
|
||||
CommentID string `json:"comment_id"`
|
||||
TagID string `json:"tag_id"`
|
||||
ObjectType string `json:"object_type"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type UnreviewedRevisionInfoInfo struct {
|
||||
|
|
|
@ -152,7 +152,8 @@ type UpdateTagReq struct {
|
|||
// edit summary
|
||||
EditSummary string `validate:"omitempty" json:"edit_summary"`
|
||||
// user id
|
||||
UserID string `json:"-"`
|
||||
UserID string `json:"-"`
|
||||
IsAdmin bool `json:"-"`
|
||||
}
|
||||
|
||||
func (r *UpdateTagReq) Check() (errFields []*validator.FormErrorField, err error) {
|
||||
|
|
|
@ -368,7 +368,8 @@ type ActionRecordResp struct {
|
|||
}
|
||||
|
||||
type UserBasicInfo struct {
|
||||
ID string `json:"-" ` // user_id
|
||||
ID string `json:"-"` // user_id
|
||||
IsAdmin bool `json:"-"`
|
||||
Username string `json:"username" ` // name
|
||||
Rank int `json:"rank" ` // rank
|
||||
DisplayName string `json:"display_name"` // display_name
|
||||
|
|
|
@ -195,6 +195,16 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
|||
}
|
||||
|
||||
func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq) (string, error) {
|
||||
var canUpdate bool
|
||||
_, existUnreviewed, err := as.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if existUnreviewed {
|
||||
err = errors.BadRequest(reason.AnswerCannotUpdate)
|
||||
return "", err
|
||||
}
|
||||
|
||||
questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -202,17 +212,13 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
|||
if !exist {
|
||||
return "", errors.BadRequest(reason.QuestionNotFound)
|
||||
}
|
||||
if !req.IsAdmin {
|
||||
answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !exist {
|
||||
return "", nil
|
||||
}
|
||||
if answerInfo.UserID != req.UserID {
|
||||
return "", errors.BadRequest(reason.AnswerCannotUpdate)
|
||||
}
|
||||
|
||||
answerInfo, exist, err := as.answerRepo.GetByID(ctx, req.ID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !exist {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
@ -223,34 +229,45 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
|||
insertData.OriginalText = req.Content
|
||||
insertData.ParsedText = req.HTML
|
||||
insertData.UpdatedAt = now
|
||||
if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "update_time"}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
|
||||
revisionDTO := &schema.AddRevisionDTO{
|
||||
UserID: req.UserID,
|
||||
ObjectID: req.ID,
|
||||
Title: "",
|
||||
Log: req.EditSummary,
|
||||
}
|
||||
|
||||
if answerInfo.UserID != req.UserID && !req.IsAdmin {
|
||||
revisionDTO.Status = entity.RevisionUnreviewedStatus
|
||||
} else {
|
||||
canUpdate = true
|
||||
if err = as.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "update_time"}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = as.questionCommon.UpdataPostTime(ctx, req.QuestionID)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
as.notificationUpdateAnswer(ctx, questionInfo.UserID, insertData.ID, req.UserID)
|
||||
revisionDTO.Status = entity.RevisionReviewPassStatus
|
||||
}
|
||||
|
||||
infoJSON, _ := json.Marshal(insertData)
|
||||
revisionDTO.Content = string(infoJSON)
|
||||
revisionID, err := as.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return insertData.ID, err
|
||||
}
|
||||
as.notificationUpdateAnswer(ctx, questionInfo.UserID, insertData.ID, req.UserID)
|
||||
if canUpdate {
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: insertData.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: insertData.ID,
|
||||
ActivityTypeKey: constant.ActAnswerEdited,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
}
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: insertData.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: insertData.ID,
|
||||
ActivityTypeKey: constant.ActAnswerEdited,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
return insertData.ID, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
|
|||
}
|
||||
|
||||
if objInfo.ObjectType == constant.QuestionObjectType {
|
||||
cs.notificationQuestionComment(ctx, objInfo.ObjectCreator, comment.ID, req.UserID)
|
||||
cs.notificationQuestionComment(ctx, objInfo.ObjectCreatorUserID, comment.ID, req.UserID)
|
||||
} else if objInfo.ObjectType == constant.AnswerObjectType {
|
||||
cs.notificationAnswerComment(ctx, objInfo.ObjectCreator, comment.ID, req.UserID)
|
||||
cs.notificationAnswerComment(ctx, objInfo.ObjectCreatorUserID, comment.ID, req.UserID)
|
||||
}
|
||||
if len(req.MentionUsernameList) > 0 {
|
||||
cs.notificationMention(ctx, req.MentionUsernameList, comment.ID, req.UserID)
|
||||
|
|
|
@ -131,12 +131,12 @@ func (os *ObjService) GetInfo(ctx context.Context, objectID string) (objInfo *sc
|
|||
break
|
||||
}
|
||||
objInfo = &schema.SimpleObjectInfo{
|
||||
ObjectID: questionInfo.ID,
|
||||
ObjectCreator: questionInfo.UserID,
|
||||
QuestionID: questionInfo.ID,
|
||||
ObjectType: objectType,
|
||||
Title: questionInfo.Title,
|
||||
Content: questionInfo.ParsedText, // todo trim
|
||||
ObjectID: questionInfo.ID,
|
||||
ObjectCreatorUserID: questionInfo.UserID,
|
||||
QuestionID: questionInfo.ID,
|
||||
ObjectType: objectType,
|
||||
Title: questionInfo.Title,
|
||||
Content: questionInfo.ParsedText, // todo trim
|
||||
}
|
||||
case constant.AnswerObjectType:
|
||||
answerInfo, exist, err := os.answerRepo.GetAnswer(ctx, objectID)
|
||||
|
@ -151,13 +151,13 @@ func (os *ObjService) GetInfo(ctx context.Context, objectID string) (objInfo *sc
|
|||
return nil, err
|
||||
}
|
||||
objInfo = &schema.SimpleObjectInfo{
|
||||
ObjectID: answerInfo.ID,
|
||||
ObjectCreator: answerInfo.UserID,
|
||||
QuestionID: answerInfo.QuestionID,
|
||||
AnswerID: answerInfo.ID,
|
||||
ObjectType: objectType,
|
||||
Title: questionInfo.Title, // this should be question title
|
||||
Content: answerInfo.ParsedText, // todo trim
|
||||
ObjectID: answerInfo.ID,
|
||||
ObjectCreatorUserID: answerInfo.UserID,
|
||||
QuestionID: answerInfo.QuestionID,
|
||||
AnswerID: answerInfo.ID,
|
||||
ObjectType: objectType,
|
||||
Title: questionInfo.Title, // this should be question title
|
||||
Content: answerInfo.ParsedText, // todo trim
|
||||
}
|
||||
case constant.CommentObjectType:
|
||||
commentInfo, exist, err := os.commentRepo.GetComment(ctx, objectID)
|
||||
|
@ -168,11 +168,11 @@ func (os *ObjService) GetInfo(ctx context.Context, objectID string) (objInfo *sc
|
|||
break
|
||||
}
|
||||
objInfo = &schema.SimpleObjectInfo{
|
||||
ObjectID: commentInfo.ID,
|
||||
ObjectCreator: commentInfo.UserID,
|
||||
ObjectType: objectType,
|
||||
Content: commentInfo.ParsedText, // todo trim
|
||||
CommentID: commentInfo.ID,
|
||||
ObjectID: commentInfo.ID,
|
||||
ObjectCreatorUserID: commentInfo.UserID,
|
||||
ObjectType: objectType,
|
||||
Content: commentInfo.ParsedText, // todo trim
|
||||
CommentID: commentInfo.ID,
|
||||
}
|
||||
if len(commentInfo.QuestionID) > 0 {
|
||||
questionInfo, exist, err := os.questionRepo.GetQuestion(ctx, commentInfo.QuestionID)
|
||||
|
|
|
@ -262,14 +262,6 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov
|
|||
return nil
|
||||
}
|
||||
|
||||
func (qs *QuestionService) CheckCanUpdateQuestion(ctx context.Context, req *schema.CheckCanQuestionUpdate) (exist bool, err error) {
|
||||
_, existUnreviewed, err := qs.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return existUnreviewed, nil
|
||||
}
|
||||
|
||||
// UpdateQuestion update question
|
||||
func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.QuestionUpdate) (questionInfo any, err error) {
|
||||
var canUpdateQuestion bool
|
||||
|
@ -843,3 +835,12 @@ func (qs *QuestionService) changeQuestionToRevision(ctx context.Context, questio
|
|||
}
|
||||
return questionRevision, nil
|
||||
}
|
||||
|
||||
// CheckCanUpdate can check question answer
|
||||
func (qs *QuestionService) CheckCanUpdate(ctx context.Context, req *schema.CheckCanQuestionUpdate) (exist bool, err error) {
|
||||
_, existUnreviewed, err := qs.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return existUnreviewed, nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package rank
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
|
@ -70,7 +71,8 @@ func NewRankService(
|
|||
}
|
||||
|
||||
// CheckRankPermission check whether the user reputation meets the permission
|
||||
func (rs *RankService) CheckRankPermission(ctx context.Context, userID string, action string) (can bool, err error) {
|
||||
func (rs *RankService) CheckRankPermission(ctx context.Context, userID string, action string, objectID string) (
|
||||
can bool, err error) {
|
||||
if len(userID) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
@ -83,14 +85,29 @@ func (rs *RankService) CheckRankPermission(ctx context.Context, userID string, a
|
|||
if !exist {
|
||||
return false, nil
|
||||
}
|
||||
currentUserRank := userInfo.Rank
|
||||
// administrator have all permissions
|
||||
if userInfo.IsAdmin {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if len(objectID) > 0 {
|
||||
objectInfo, err := rs.objectInfoService.GetInfo(ctx, objectID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// if the user is this object creator, the user can operate this object.
|
||||
// but if this object is tag, only users who have reached the rank level can operate.
|
||||
if objectInfo.ObjectCreatorUserID == userID && objectInfo.ObjectType != constant.TagObjectType {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// get the amount of rank required for the current operation
|
||||
requireRank, err := rs.configRepo.GetInt(action)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
currentUserRank := userInfo.Rank
|
||||
if currentUserRank < requireRank {
|
||||
log.Debugf("user %s want to do action %s, but rank %d < %d",
|
||||
userInfo.DisplayName, action, currentUserRank, requireRank)
|
||||
|
|
|
@ -47,7 +47,7 @@ func (rs *ReportService) AddReport(ctx context.Context, req *schema.AddReportReq
|
|||
|
||||
report := &entity.Report{
|
||||
UserID: req.UserID,
|
||||
ReportedUserID: objInfo.ObjectCreator,
|
||||
ReportedUserID: objInfo.ObjectCreatorUserID,
|
||||
ObjectID: req.ObjectID,
|
||||
ObjectType: objectTypeNumber,
|
||||
ReportType: req.ReportType,
|
||||
|
|
|
@ -3,15 +3,26 @@ package service
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/internal/base/reason"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"github.com/answerdev/answer/internal/schema"
|
||||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
answercommon "github.com/answerdev/answer/internal/service/answer_common"
|
||||
"github.com/answerdev/answer/internal/service/notice_queue"
|
||||
"github.com/answerdev/answer/internal/service/object_info"
|
||||
questioncommon "github.com/answerdev/answer/internal/service/question_common"
|
||||
"github.com/answerdev/answer/internal/service/revision"
|
||||
"github.com/answerdev/answer/internal/service/tag_common"
|
||||
tagcommon "github.com/answerdev/answer/internal/service/tag_common"
|
||||
usercommon "github.com/answerdev/answer/internal/service/user_common"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"github.com/answerdev/answer/pkg/obj"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
// RevisionService user service
|
||||
|
@ -21,6 +32,10 @@ type RevisionService struct {
|
|||
questionCommon *questioncommon.QuestionCommon
|
||||
answerService *AnswerService
|
||||
objectInfoService *object_info.ObjService
|
||||
questionRepo questioncommon.QuestionRepo
|
||||
answerRepo answercommon.AnswerRepo
|
||||
tagRepo tag_common.TagRepo
|
||||
tagCommon *tagcommon.TagCommonService
|
||||
}
|
||||
|
||||
func NewRevisionService(
|
||||
|
@ -29,6 +44,11 @@ func NewRevisionService(
|
|||
questionCommon *questioncommon.QuestionCommon,
|
||||
answerService *AnswerService,
|
||||
objectInfoService *object_info.ObjService,
|
||||
questionRepo questioncommon.QuestionRepo,
|
||||
answerRepo answercommon.AnswerRepo,
|
||||
tagRepo tag_common.TagRepo,
|
||||
tagCommon *tagcommon.TagCommonService,
|
||||
|
||||
) *RevisionService {
|
||||
return &RevisionService{
|
||||
revisionRepo: revisionRepo,
|
||||
|
@ -36,6 +56,10 @@ func NewRevisionService(
|
|||
questionCommon: questionCommon,
|
||||
answerService: answerService,
|
||||
objectInfoService: objectInfoService,
|
||||
questionRepo: questionRepo,
|
||||
answerRepo: answerRepo,
|
||||
tagRepo: tagRepo,
|
||||
tagCommon: tagCommon,
|
||||
}
|
||||
}
|
||||
func (rs *RevisionService) RevisionAudit(ctx context.Context, req *schema.RevisionAuditReq) (err error) {
|
||||
|
@ -50,13 +74,145 @@ func (rs *RevisionService) RevisionAudit(ctx context.Context, req *schema.Revisi
|
|||
return
|
||||
}
|
||||
if req.Operation == schema.RevisionAuditReject {
|
||||
revisioninfo.Status = entity.RevisionReviewRejectStatus
|
||||
err = rs.revisionRepo.UpdateStatus(ctx, req.ID, entity.RevisionReviewRejectStatus)
|
||||
return
|
||||
}
|
||||
if req.Operation == schema.RevisionAuditApprove {
|
||||
// revisioninfo.Status = entity.RevisionReviewRejectStatus
|
||||
// err = rs.revisionRepo.UpdateStatus(ctx, req.ID, entity.RevisionReviewRejectStatus)
|
||||
objectType, objectTypeerr := obj.GetObjectTypeStrByObjectID(revisioninfo.ObjectID)
|
||||
if objectTypeerr != nil {
|
||||
return objectTypeerr
|
||||
}
|
||||
revisionitem := &schema.GetRevisionResp{}
|
||||
_ = copier.Copy(revisionitem, revisioninfo)
|
||||
rs.parseItem(ctx, revisionitem)
|
||||
switch objectType {
|
||||
case constant.QuestionObjectType:
|
||||
questioninfo, ok := revisionitem.ContentParsed.(*schema.QuestionInfo)
|
||||
if ok {
|
||||
now := time.Now()
|
||||
question := &entity.Question{}
|
||||
question.ID = questioninfo.ID
|
||||
question.Title = questioninfo.Title
|
||||
question.OriginalText = questioninfo.Content
|
||||
question.ParsedText = questioninfo.HTML
|
||||
question.UpdatedAt = now
|
||||
saveerr := rs.questionRepo.UpdateQuestion(ctx, question, []string{"title", "original_text", "parsed_text", "updated_at"})
|
||||
if saveerr != nil {
|
||||
return saveerr
|
||||
}
|
||||
objectTagTags := make([]*schema.TagItem, 0)
|
||||
for _, tag := range questioninfo.Tags {
|
||||
item := &schema.TagItem{}
|
||||
item.SlugName = tag.SlugName
|
||||
objectTagTags = append(objectTagTags, item)
|
||||
}
|
||||
objectTagData := schema.TagChange{}
|
||||
objectTagData.ObjectID = question.ID
|
||||
objectTagData.Tags = objectTagTags
|
||||
saveerr = rs.tagCommon.ObjectChangeTag(ctx, &objectTagData)
|
||||
if saveerr != nil {
|
||||
return saveerr
|
||||
}
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: revisioninfo.UserID,
|
||||
ObjectID: revisioninfo.ObjectID,
|
||||
ActivityTypeKey: constant.ActQuestionEdited,
|
||||
RevisionID: revisioninfo.ID,
|
||||
OriginalObjectID: revisioninfo.ObjectID,
|
||||
})
|
||||
}
|
||||
//
|
||||
case constant.AnswerObjectType:
|
||||
answerinfo, ok := revisionitem.ContentParsed.(*schema.AnswerInfo)
|
||||
if ok {
|
||||
now := time.Now()
|
||||
insertData := new(entity.Answer)
|
||||
insertData.ID = answerinfo.ID
|
||||
insertData.OriginalText = answerinfo.Content
|
||||
insertData.ParsedText = answerinfo.HTML
|
||||
insertData.UpdatedAt = now
|
||||
saveerr := rs.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "update_time"})
|
||||
if saveerr != nil {
|
||||
return saveerr
|
||||
}
|
||||
saveerr = rs.questionCommon.UpdataPostTime(ctx, answerinfo.QuestionID)
|
||||
if saveerr != nil {
|
||||
return saveerr
|
||||
}
|
||||
questionInfo, exist, err := rs.questionRepo.GetQuestion(ctx, answerinfo.QuestionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return errors.BadRequest(reason.QuestionNotFound)
|
||||
}
|
||||
msg := &schema.NotificationMsg{
|
||||
TriggerUserID: revisioninfo.UserID,
|
||||
ReceiverUserID: questionInfo.UserID,
|
||||
Type: schema.NotificationTypeInbox,
|
||||
ObjectID: answerinfo.ID,
|
||||
}
|
||||
msg.ObjectType = constant.AnswerObjectType
|
||||
msg.NotificationAction = constant.UpdateAnswer
|
||||
notice_queue.AddNotification(msg)
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: revisioninfo.UserID,
|
||||
ObjectID: insertData.ID,
|
||||
OriginalObjectID: insertData.ID,
|
||||
ActivityTypeKey: constant.ActAnswerEdited,
|
||||
RevisionID: revisioninfo.ID,
|
||||
})
|
||||
}
|
||||
|
||||
case constant.TagObjectType:
|
||||
taginfo, ok := revisionitem.ContentParsed.(*schema.GetTagResp)
|
||||
if ok {
|
||||
tag := &entity.Tag{}
|
||||
tag.ID = taginfo.TagID
|
||||
tag.DisplayName = taginfo.DisplayName
|
||||
tag.SlugName = taginfo.SlugName
|
||||
tag.OriginalText = taginfo.OriginalText
|
||||
tag.ParsedText = taginfo.ParsedText
|
||||
saveerr := rs.tagRepo.UpdateTag(ctx, tag)
|
||||
if saveerr != nil {
|
||||
return saveerr
|
||||
}
|
||||
|
||||
tagInfo, exist, err := rs.tagCommon.GetTagByID(ctx, taginfo.TagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return errors.BadRequest(reason.TagNotFound)
|
||||
}
|
||||
if tagInfo.MainTagID == 0 && len(tagInfo.SlugName) > 0 {
|
||||
log.Debugf("tag %s update slug_name", tagInfo.SlugName)
|
||||
tagList, err := rs.tagRepo.GetTagList(ctx, &entity.Tag{MainTagID: converter.StringToInt64(tagInfo.ID)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateTagSlugNames := make([]string, 0)
|
||||
for _, tag := range tagList {
|
||||
updateTagSlugNames = append(updateTagSlugNames, tag.SlugName)
|
||||
}
|
||||
err = rs.tagRepo.UpdateTagSynonym(ctx, updateTagSlugNames, converter.StringToInt64(tagInfo.ID), tagInfo.MainTagSlugName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: revisioninfo.UserID,
|
||||
ObjectID: taginfo.TagID,
|
||||
OriginalObjectID: taginfo.TagID,
|
||||
ActivityTypeKey: constant.ActTagEdited,
|
||||
RevisionID: revisioninfo.ID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
err = rs.revisionRepo.UpdateStatus(ctx, req.ID, entity.RevisionReviewPassStatus)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/internal/service/revision_common"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
"github.com/answerdev/answer/internal/service/tag_common"
|
||||
tagcommonser "github.com/answerdev/answer/internal/service/tag_common"
|
||||
"github.com/answerdev/answer/pkg/htmltext"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
|
@ -23,17 +23,10 @@ import (
|
|||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
type TagRepo interface {
|
||||
RemoveTag(ctx context.Context, tagID string) (err error)
|
||||
UpdateTag(ctx context.Context, tag *entity.Tag) (err error)
|
||||
UpdateTagSynonym(ctx context.Context, tagSlugNameList []string, mainTagID int64, mainTagSlugName string) (err error)
|
||||
GetTagList(ctx context.Context, tag *entity.Tag) (tagList []*entity.Tag, err error)
|
||||
}
|
||||
|
||||
// TagService user service
|
||||
type TagService struct {
|
||||
tagRepo TagRepo
|
||||
tagCommonService *tag_common.TagCommonService
|
||||
tagRepo tagcommonser.TagRepo
|
||||
tagCommonService *tagcommonser.TagCommonService
|
||||
revisionService *revision_common.RevisionService
|
||||
followCommon activity_common.FollowRepo
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService
|
||||
|
@ -41,8 +34,8 @@ type TagService struct {
|
|||
|
||||
// NewTagService new tag service
|
||||
func NewTagService(
|
||||
tagRepo TagRepo,
|
||||
tagCommonService *tag_common.TagCommonService,
|
||||
tagRepo tagcommonser.TagRepo,
|
||||
tagCommonService *tagcommonser.TagCommonService,
|
||||
revisionService *revision_common.RevisionService,
|
||||
followCommon activity_common.FollowRepo,
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService) *TagService {
|
||||
|
@ -72,57 +65,7 @@ func (ts *TagService) RemoveTag(ctx context.Context, req *schema.RemoveTagReq) (
|
|||
|
||||
// UpdateTag update tag
|
||||
func (ts *TagService) UpdateTag(ctx context.Context, req *schema.UpdateTagReq) (err error) {
|
||||
tag := &entity.Tag{}
|
||||
_ = copier.Copy(tag, req)
|
||||
tag.ID = req.TagID
|
||||
err = ts.tagRepo.UpdateTag(ctx, tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tagInfo, exist, err := ts.tagCommonService.GetTagByID(ctx, req.TagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return errors.BadRequest(reason.TagNotFound)
|
||||
}
|
||||
if tagInfo.MainTagID == 0 && len(req.SlugName) > 0 {
|
||||
log.Debugf("tag %s update slug_name", tagInfo.SlugName)
|
||||
tagList, err := ts.tagRepo.GetTagList(ctx, &entity.Tag{MainTagID: converter.StringToInt64(tagInfo.ID)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateTagSlugNames := make([]string, 0)
|
||||
for _, tag := range tagList {
|
||||
updateTagSlugNames = append(updateTagSlugNames, tag.SlugName)
|
||||
}
|
||||
err = ts.tagRepo.UpdateTagSynonym(ctx, updateTagSlugNames, converter.StringToInt64(tagInfo.ID), tagInfo.MainTagSlugName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
revisionDTO := &schema.AddRevisionDTO{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tag.ID,
|
||||
Title: tag.SlugName,
|
||||
Log: req.EditSummary,
|
||||
}
|
||||
tagInfoJson, _ := json.Marshal(tagInfo)
|
||||
revisionDTO.Content = string(tagInfoJson)
|
||||
revisionID, err := ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tag.ID,
|
||||
OriginalObjectID: tag.ID,
|
||||
ActivityTypeKey: constant.ActTagEdited,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
return
|
||||
return ts.tagCommonService.UpdateTag(ctx, req)
|
||||
}
|
||||
|
||||
// GetTagInfo get tag one
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/answerdev/answer/internal/service/activity_queue"
|
||||
"github.com/answerdev/answer/internal/service/revision_common"
|
||||
"github.com/answerdev/answer/internal/service/siteinfo_common"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
@ -33,6 +34,13 @@ type TagCommonRepo interface {
|
|||
UpdateTagQuestionCount(ctx context.Context, tagID string, questionCount int) (err error)
|
||||
}
|
||||
|
||||
type TagRepo interface {
|
||||
RemoveTag(ctx context.Context, tagID string) (err error)
|
||||
UpdateTag(ctx context.Context, tag *entity.Tag) (err error)
|
||||
UpdateTagSynonym(ctx context.Context, tagSlugNameList []string, mainTagID int64, mainTagSlugName string) (err error)
|
||||
GetTagList(ctx context.Context, tag *entity.Tag) (tagList []*entity.Tag, err error)
|
||||
}
|
||||
|
||||
type TagRelRepo interface {
|
||||
AddTagRelList(ctx context.Context, tagList []*entity.TagRel) (err error)
|
||||
RemoveTagRelListByIDs(ctx context.Context, ids []int64) (err error)
|
||||
|
@ -48,17 +56,22 @@ type TagCommonService struct {
|
|||
revisionService *revision_common.RevisionService
|
||||
tagCommonRepo TagCommonRepo
|
||||
tagRelRepo TagRelRepo
|
||||
tagRepo TagRepo
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService
|
||||
}
|
||||
|
||||
// NewTagCommonService new tag service
|
||||
func NewTagCommonService(tagCommonRepo TagCommonRepo, tagRelRepo TagRelRepo,
|
||||
func NewTagCommonService(
|
||||
tagCommonRepo TagCommonRepo,
|
||||
tagRelRepo TagRelRepo,
|
||||
tagRepo TagRepo,
|
||||
revisionService *revision_common.RevisionService,
|
||||
siteInfoService *siteinfo_common.SiteInfoCommonService,
|
||||
) *TagCommonService {
|
||||
return &TagCommonService{
|
||||
tagCommonRepo: tagCommonRepo,
|
||||
tagRelRepo: tagRelRepo,
|
||||
tagRepo: tagRepo,
|
||||
revisionService: revisionService,
|
||||
siteInfoService: siteInfoService,
|
||||
}
|
||||
|
@ -582,3 +595,79 @@ func (ts *TagCommonService) CreateOrUpdateTagRelList(ctx context.Context, object
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ts *TagCommonService) UpdateTag(ctx context.Context, req *schema.UpdateTagReq) (err error) {
|
||||
var canUpdate bool
|
||||
_, existUnreviewed, err := ts.revisionService.ExistUnreviewedByObjectID(ctx, req.TagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existUnreviewed {
|
||||
err = errors.BadRequest(reason.AnswerCannotUpdate)
|
||||
return err
|
||||
}
|
||||
|
||||
tagInfo, exist, err := ts.GetTagByID(ctx, req.TagID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return errors.BadRequest(reason.TagNotFound)
|
||||
}
|
||||
|
||||
tagInfo.SlugName = req.SlugName
|
||||
tagInfo.DisplayName = req.DisplayName
|
||||
tagInfo.OriginalText = req.OriginalText
|
||||
tagInfo.ParsedText = req.ParsedText
|
||||
|
||||
revisionDTO := &schema.AddRevisionDTO{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tagInfo.ID,
|
||||
Title: tagInfo.SlugName,
|
||||
Log: req.EditSummary,
|
||||
}
|
||||
|
||||
if !req.IsAdmin {
|
||||
revisionDTO.Status = entity.RevisionUnreviewedStatus
|
||||
} else {
|
||||
canUpdate = true
|
||||
err = ts.tagRepo.UpdateTag(ctx, tagInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tagInfo.MainTagID == 0 && len(req.SlugName) > 0 {
|
||||
log.Debugf("tag %s update slug_name", tagInfo.SlugName)
|
||||
tagList, err := ts.tagRepo.GetTagList(ctx, &entity.Tag{MainTagID: converter.StringToInt64(tagInfo.ID)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateTagSlugNames := make([]string, 0)
|
||||
for _, tag := range tagList {
|
||||
updateTagSlugNames = append(updateTagSlugNames, tag.SlugName)
|
||||
}
|
||||
err = ts.tagRepo.UpdateTagSynonym(ctx, updateTagSlugNames, converter.StringToInt64(tagInfo.ID), tagInfo.MainTagSlugName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
revisionDTO.Status = entity.RevisionReviewPassStatus
|
||||
}
|
||||
|
||||
tagInfoJson, _ := json.Marshal(tagInfo)
|
||||
revisionDTO.Content = string(tagInfoJson)
|
||||
revisionID, err := ts.revisionService.AddRevision(ctx, revisionDTO, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if canUpdate {
|
||||
activity_queue.AddActivity(&schema.ActivityMsg{
|
||||
UserID: req.UserID,
|
||||
ObjectID: tagInfo.ID,
|
||||
OriginalObjectID: tagInfo.ID,
|
||||
ActivityTypeKey: constant.ActTagEdited,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -36,12 +36,13 @@ func NewUserCommon(userRepo UserRepo) *UserCommon {
|
|||
}
|
||||
}
|
||||
|
||||
func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, ID string) (*schema.UserBasicInfo, bool, error) {
|
||||
func (us *UserCommon) GetUserBasicInfoByID(ctx context.Context, ID string) (
|
||||
userBasicInfo *schema.UserBasicInfo, exist bool, err error) {
|
||||
userInfo, exist, err := us.userRepo.GetByUserID(ctx, ID)
|
||||
if err != nil {
|
||||
return nil, exist, err
|
||||
}
|
||||
info := us.UserBasicInfoFormat(ctx, userInfo)
|
||||
info := us.FormatUserBasicInfo(ctx, userInfo)
|
||||
return info, exist, nil
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,7 @@ func (us *UserCommon) GetUserBasicInfoByUserName(ctx context.Context, username s
|
|||
if err != nil {
|
||||
return nil, exist, err
|
||||
}
|
||||
info := us.UserBasicInfoFormat(ctx, userInfo)
|
||||
info := us.FormatUserBasicInfo(ctx, userInfo)
|
||||
return info, exist, nil
|
||||
}
|
||||
|
||||
|
@ -69,21 +70,21 @@ func (us *UserCommon) BatchUserBasicInfoByID(ctx context.Context, IDs []string)
|
|||
return userMap, err
|
||||
}
|
||||
for _, item := range dbInfo {
|
||||
info := us.UserBasicInfoFormat(ctx, item)
|
||||
info := us.FormatUserBasicInfo(ctx, item)
|
||||
userMap[item.ID] = info
|
||||
}
|
||||
return userMap, nil
|
||||
}
|
||||
|
||||
// UserBasicInfoFormat
|
||||
func (us *UserCommon) UserBasicInfoFormat(ctx context.Context, userInfo *entity.User) *schema.UserBasicInfo {
|
||||
// FormatUserBasicInfo format user basic info
|
||||
func (us *UserCommon) FormatUserBasicInfo(ctx context.Context, userInfo *entity.User) *schema.UserBasicInfo {
|
||||
userBasicInfo := &schema.UserBasicInfo{}
|
||||
Avatar := schema.FormatAvatarInfo(userInfo.Avatar)
|
||||
userBasicInfo.ID = userInfo.ID
|
||||
userBasicInfo.IsAdmin = userInfo.IsAdmin
|
||||
userBasicInfo.Username = userInfo.Username
|
||||
userBasicInfo.Rank = userInfo.Rank
|
||||
userBasicInfo.DisplayName = userInfo.DisplayName
|
||||
userBasicInfo.Avatar = Avatar
|
||||
userBasicInfo.Avatar = schema.FormatAvatarInfo(userInfo.Avatar)
|
||||
userBasicInfo.Website = userInfo.Website
|
||||
userBasicInfo.Location = userInfo.Location
|
||||
userBasicInfo.IPInfo = userInfo.IPInfo
|
||||
|
|
Loading…
Reference in New Issue