in internal/service/content/question_service.go [859:1026]
func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.QuestionUpdate) (questionInfo any, err error) {
var canUpdate bool
questionInfo = &schema.QuestionInfoResp{}
_, existUnreviewed, err := qs.revisionService.ExistUnreviewedByObjectID(ctx, req.ID)
if err != nil {
return
}
if existUnreviewed {
err = errors.BadRequest(reason.QuestionCannotUpdate)
return
}
dbinfo, has, err := qs.questionRepo.GetQuestion(ctx, req.ID)
if err != nil {
return
}
if !has {
return
}
if dbinfo.Status == entity.QuestionStatusDeleted {
err = errors.BadRequest(reason.QuestionCannotUpdate)
return nil, err
}
now := time.Now()
question := &entity.Question{}
question.Title = req.Title
question.OriginalText = req.Content
question.ParsedText = req.HTML
question.ID = uid.DeShortID(req.ID)
question.UpdatedAt = now
question.PostUpdateTime = now
question.UserID = dbinfo.UserID
question.LastEditUserID = req.UserID
oldTags, tagerr := qs.tagCommon.GetObjectEntityTag(ctx, question.ID)
if tagerr != nil {
return questionInfo, tagerr
}
tagNameList := make([]string, 0)
oldtagNameList := make([]string, 0)
for _, tag := range req.Tags {
tag.SlugName = strings.ReplaceAll(tag.SlugName, " ", "-")
tagNameList = append(tagNameList, tag.SlugName)
}
for _, tag := range oldTags {
oldtagNameList = append(oldtagNameList, tag.SlugName)
}
isChange := qs.tagCommon.CheckTagsIsChange(ctx, tagNameList, oldtagNameList)
//If the content is the same, ignore it
if dbinfo.Title == req.Title && dbinfo.OriginalText == req.Content && !isChange {
return
}
Tags, tagerr := qs.tagCommon.GetTagListByNames(ctx, tagNameList)
if tagerr != nil {
return questionInfo, tagerr
}
// if user can not use reserved tag, old reserved tag can not be removed and new reserved tag can not be added.
if !req.CanUseReservedTag {
CheckOldTag, CheckNewTag, CheckOldTaglist, CheckNewTaglist := qs.CheckChangeReservedTag(ctx, oldTags, Tags)
if !CheckOldTag {
errMsg := fmt.Sprintf(`The reserved tag "%s" must be present.`,
strings.Join(CheckOldTaglist, ","))
errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags",
ErrorMsg: errMsg,
})
err = errors.BadRequest(reason.RequestFormatError).WithMsg(errMsg)
return errorlist, err
}
if !CheckNewTag {
errMsg := fmt.Sprintf(`"%s" can only be used by moderators.`,
strings.Join(CheckNewTaglist, ","))
errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags",
ErrorMsg: errMsg,
})
err = errors.BadRequest(reason.RequestFormatError).WithMsg(errMsg)
return errorlist, err
}
}
// Check whether mandatory labels are selected
recommendExist, err := qs.tagCommon.ExistRecommend(ctx, req.Tags)
if err != nil {
return
}
if !recommendExist {
errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags",
ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter),
})
err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err
}
//Administrators and themselves do not need to be audited
revisionDTO := &schema.AddRevisionDTO{
UserID: question.UserID,
ObjectID: question.ID,
Title: question.Title,
Log: req.EditSummary,
}
if req.NoNeedReview {
canUpdate = true
}
// It's not you or the administrator that needs to be reviewed
if !canUpdate {
revisionDTO.Status = entity.RevisionUnreviewedStatus
revisionDTO.UserID = req.UserID //use revision userid
} else {
//Direct modification
revisionDTO.Status = entity.RevisionReviewPassStatus
//update question to db
question.ParsedText, err = qs.questioncommon.UpdateQuestionLink(ctx, question.ID, "", question.ParsedText, question.OriginalText)
if err != nil {
return questionInfo, err
}
saveerr := qs.questionRepo.UpdateQuestion(ctx, question, []string{"title", "original_text", "parsed_text", "updated_at", "post_update_time", "last_edit_user_id"})
if saveerr != nil {
return questionInfo, saveerr
}
objectTagData := schema.TagChange{}
objectTagData.ObjectID = question.ID
objectTagData.Tags = req.Tags
objectTagData.UserID = req.UserID
tagerr := qs.ChangeTag(ctx, &objectTagData)
if tagerr != nil {
return questionInfo, tagerr
}
}
questionWithTagsRevision, err := qs.changeQuestionToRevision(ctx, question, Tags)
if err != nil {
return nil, err
}
infoJSON, _ := json.Marshal(questionWithTagsRevision)
revisionDTO.Content = string(infoJSON)
revisionID, err := qs.revisionService.AddRevision(ctx, revisionDTO, true)
if err != nil {
return
}
if canUpdate {
qs.activityQueueService.Send(ctx, &schema.ActivityMsg{
UserID: req.UserID,
ObjectID: question.ID,
ActivityTypeKey: constant.ActQuestionEdited,
RevisionID: revisionID,
OriginalObjectID: question.ID,
})
qs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionUpdate, req.UserID).TID(question.ID).
QID(question.ID, question.UserID))
}
questionInfo, err = qs.GetQuestion(ctx, question.ID, question.UserID, req.QuestionPermission)
return
}