From eeb5f94a06805521ab3c00cc28dc7996589b6c3a Mon Sep 17 00:00:00 2001 From: LinkinStars Date: Mon, 28 Aug 2023 16:21:28 +0800 Subject: [PATCH] fix(answer): fix incorrect notification triggers when accept the answer --- internal/controller/answer_controller.go | 6 +- internal/repo/activity/answer_repo.go | 3 +- internal/repo/answer/answer_repo.go | 31 +++++----- internal/schema/answer_schema.go | 13 ++++- internal/service/answer_common/answer.go | 2 +- internal/service/answer_service.go | 74 ++++++++++-------------- 6 files changed, 62 insertions(+), 67 deletions(-) diff --git a/internal/controller/answer_controller.go b/internal/controller/answer_controller.go index 81344b85..60120e4c 100644 --- a/internal/controller/answer_controller.go +++ b/internal/controller/answer_controller.go @@ -319,11 +319,11 @@ func (ac *AnswerController) AnswerList(ctx *gin.Context) { // @Accept json // @Produce json // @Security ApiKeyAuth -// @Param data body schema.AnswerAcceptedReq true "AnswerAcceptedReq" +// @Param data body schema.AcceptAnswerReq true "AcceptAnswerReq" // @Success 200 {string} string "" // @Router /answer/api/v1/answer/acceptance [post] func (ac *AnswerController) Accepted(ctx *gin.Context) { - req := &schema.AnswerAcceptedReq{} + req := &schema.AcceptAnswerReq{} if handler.BindAndCheck(ctx, req) { return } @@ -341,7 +341,7 @@ func (ac *AnswerController) Accepted(ctx *gin.Context) { return } - err = ac.answerService.UpdateAccepted(ctx, req) + err = ac.answerService.AcceptAnswer(ctx, req) handler.HandleResponse(ctx, err, nil) } diff --git a/internal/repo/activity/answer_repo.go b/internal/repo/activity/answer_repo.go index fa4aacd0..80335f73 100644 --- a/internal/repo/activity/answer_repo.go +++ b/internal/repo/activity/answer_repo.go @@ -55,7 +55,6 @@ func (ar *AnswerActivityRepo) SaveAcceptAnswerActivity(ctx context.Context, op * return nil } - ar.data.DB.ShowSQL(true) // save activity _, err = ar.data.DB.Transaction(func(session *xorm.Session) (result any, err error) { session = session.Context(ctx) @@ -331,7 +330,7 @@ func (ar *AnswerActivityRepo) sendAcceptAnswerNotification( ObjectID: op.AnswerObjectID, } if act.ActivityUserID != op.QuestionUserID { - msg.TriggerUserID = op.QuestionUserID + msg.TriggerUserID = op.TriggerUserID msg.ObjectType = constant.AnswerObjectType msg.NotificationAction = constant.NotificationAcceptAnswer ar.notificationQueueService.Send(ctx, msg) diff --git a/internal/repo/answer/answer_repo.go b/internal/repo/answer/answer_repo.go index 377a5c28..a662225d 100644 --- a/internal/repo/answer/answer_repo.go +++ b/internal/repo/answer/answer_repo.go @@ -166,30 +166,29 @@ func (ar *answerRepo) GetAnswerPage(ctx context.Context, page, pageSize int, ans return } -// UpdateAccepted -// If no answer is selected, the answer id can be 0 -func (ar *answerRepo) UpdateAccepted(ctx context.Context, id string, questionID string) error { - if questionID == "" { - return nil - } - id = uid.DeShortID(id) +// UpdateAcceptedStatus update all accepted status of this question's answers +func (ar *answerRepo) UpdateAcceptedStatus(ctx context.Context, acceptedAnswerID string, questionID string) error { + acceptedAnswerID = uid.DeShortID(acceptedAnswerID) questionID = uid.DeShortID(questionID) - var data entity.Answer - data.ID = id - data.Accepted = schema.AnswerAcceptedFailed - _, err := ar.data.DB.Context(ctx).Where("question_id =?", questionID).Cols("adopted").Update(&data) + // update all this question's answer accepted status to false + _, err := ar.data.DB.Context(ctx).Where("question_id = ?", questionID).Cols("adopted").Update(&entity.Answer{ + Accepted: schema.AnswerAcceptedFailed, + }) if err != nil { - return err + return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } - if id != "0" { - data.Accepted = schema.AnswerAcceptedEnable - _, err = ar.data.DB.Context(ctx).Where("id = ?", id).Cols("adopted").Update(&data) + + // if acceptedAnswerID is not empty, update accepted status to true + if len(acceptedAnswerID) > 0 && acceptedAnswerID != "0" { + _, err = ar.data.DB.Context(ctx).Where("id = ?", acceptedAnswerID).Cols("adopted").Update(&entity.Answer{ + Accepted: schema.AnswerAcceptedEnable, + }) if err != nil { return errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() } } - _ = ar.updateSearch(ctx, id) + _ = ar.updateSearch(ctx, acceptedAnswerID) return nil } diff --git a/internal/schema/answer_schema.go b/internal/schema/answer_schema.go index 4777e770..2c09b043 100644 --- a/internal/schema/answer_schema.go +++ b/internal/schema/answer_schema.go @@ -108,12 +108,19 @@ type AdminAnswerInfo struct { } `json:"question_info"` } -type AnswerAcceptedReq struct { - QuestionID string `json:"question_id"` - AnswerID string `json:"answer_id"` +type AcceptAnswerReq struct { + QuestionID string `validate:"required,gt=0,lte=30" json:"question_id"` + AnswerID string `validate:"omitempty" json:"answer_id"` UserID string `json:"-"` } +func (req *AcceptAnswerReq) Check() (errFields []*validator.FormErrorField, err error) { + if len(req.AnswerID) == 0 { + req.AnswerID = "0" + } + return nil, nil +} + type AdminSetAnswerStatusRequest struct { StatusStr string `json:"status"` AnswerID string `json:"answer_id"` diff --git a/internal/service/answer_common/answer.go b/internal/service/answer_common/answer.go index 2373a6d0..1d61cd4d 100644 --- a/internal/service/answer_common/answer.go +++ b/internal/service/answer_common/answer.go @@ -17,7 +17,7 @@ type AnswerRepo interface { GetAnswer(ctx context.Context, id string) (answer *entity.Answer, exist bool, err error) GetAnswerList(ctx context.Context, answer *entity.Answer) (answerList []*entity.Answer, err error) GetAnswerPage(ctx context.Context, page, pageSize int, answer *entity.Answer) (answerList []*entity.Answer, total int64, err error) - UpdateAccepted(ctx context.Context, id string, questionID string) error + UpdateAcceptedStatus(ctx context.Context, acceptedAnswerID string, questionID string) error GetByID(ctx context.Context, id string) (*entity.Answer, bool, error) GetCountByQuestionID(ctx context.Context, questionID string) (int64, error) GetCountByUserID(ctx context.Context, userID string) (int64, error) diff --git a/internal/service/answer_service.go b/internal/service/answer_service.go index 4c0e57b6..3b50c04a 100644 --- a/internal/service/answer_service.go +++ b/internal/service/answer_service.go @@ -325,47 +325,47 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq return insertData.ID, nil } -// UpdateAccepted -func (as *AnswerService) UpdateAccepted(ctx context.Context, req *schema.AnswerAcceptedReq) error { - if req.AnswerID == "" { - req.AnswerID = "0" - } - if req.UserID == "" { - return nil - } - - newAnswerInfo := &entity.Answer{} - newAnswerInfoexist := false - var err error - - if req.AnswerID != "0" { - newAnswerInfo, newAnswerInfoexist, err = as.answerRepo.GetByID(ctx, req.AnswerID) - if err != nil { - return err - } - newAnswerInfo.ID = uid.DeShortID(newAnswerInfo.ID) - if !newAnswerInfoexist { - return errors.BadRequest(reason.AnswerNotFound) - } - } - +// AcceptAnswer accept answer +func (as *AnswerService) AcceptAnswer(ctx context.Context, req *schema.AcceptAnswerReq) (err error) { + // find question questionInfo, exist, err := as.questionRepo.GetQuestion(ctx, req.QuestionID) if err != nil { return err } - questionInfo.ID = uid.DeShortID(questionInfo.ID) if !exist { return errors.BadRequest(reason.QuestionNotFound) } - // if questionInfo.UserID != req.UserID { - // return fmt.Errorf("no permission to set answer") - // } + questionInfo.ID = uid.DeShortID(questionInfo.ID) if questionInfo.AcceptedAnswerID == req.AnswerID { return nil } + // find answer + var acceptedAnswerInfo *entity.Answer + if len(req.AnswerID) > 1 { + acceptedAnswerInfo, exist, err = as.answerRepo.GetByID(ctx, req.AnswerID) + if err != nil { + return err + } + if !exist { + return errors.BadRequest(reason.AnswerNotFound) + } + acceptedAnswerInfo.ID = uid.DeShortID(acceptedAnswerInfo.ID) + } + + // update answers status + if err = as.answerRepo.UpdateAcceptedStatus(ctx, req.AnswerID, req.QuestionID); err != nil { + return err + } + + // update question status + err = as.questionCommon.UpdateAccepted(ctx, req.QuestionID, req.AnswerID) + if err != nil { + log.Error("UpdateLastAnswer error", err.Error()) + } + var oldAnswerInfo *entity.Answer - if len(questionInfo.AcceptedAnswerID) > 0 && questionInfo.AcceptedAnswerID != "0" { + if len(questionInfo.AcceptedAnswerID) > 1 { oldAnswerInfo, _, err = as.answerRepo.GetByID(ctx, questionInfo.AcceptedAnswerID) if err != nil { return err @@ -373,17 +373,7 @@ func (as *AnswerService) UpdateAccepted(ctx context.Context, req *schema.AnswerA oldAnswerInfo.ID = uid.DeShortID(oldAnswerInfo.ID) } - err = as.answerRepo.UpdateAccepted(ctx, req.AnswerID, req.QuestionID) - if err != nil { - return err - } - - err = as.questionCommon.UpdateAccepted(ctx, req.QuestionID, req.AnswerID) - if err != nil { - log.Error("UpdateLastAnswer error", err.Error()) - } - - as.updateAnswerRank(ctx, req.UserID, questionInfo, newAnswerInfo, oldAnswerInfo) + as.updateAnswerRank(ctx, req.UserID, questionInfo, acceptedAnswerInfo, oldAnswerInfo) return nil } @@ -398,9 +388,9 @@ func (as *AnswerService) updateAnswerRank(ctx context.Context, userID string, log.Error(err) } } - if newAnswerInfo.ID != "" { + if newAnswerInfo != nil { err := as.answerActivityService.AcceptAnswer(ctx, userID, newAnswerInfo.ID, - questionInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == userID) + questionInfo.ID, questionInfo.UserID, newAnswerInfo.UserID, newAnswerInfo.UserID == questionInfo.UserID) if err != nil { log.Error(err) }