564 lines
18 KiB
Go
564 lines
18 KiB
Go
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
package content
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/apache/answer/internal/base/constant"
|
|
"github.com/apache/answer/internal/base/handler"
|
|
"github.com/apache/answer/internal/base/pager"
|
|
"github.com/apache/answer/internal/base/reason"
|
|
"github.com/apache/answer/internal/base/translator"
|
|
"github.com/apache/answer/internal/entity"
|
|
"github.com/apache/answer/internal/schema"
|
|
"github.com/apache/answer/internal/service/activity"
|
|
"github.com/apache/answer/internal/service/activityqueue"
|
|
answercommon "github.com/apache/answer/internal/service/answer_common"
|
|
"github.com/apache/answer/internal/service/noticequeue"
|
|
"github.com/apache/answer/internal/service/object_info"
|
|
questioncommon "github.com/apache/answer/internal/service/question_common"
|
|
"github.com/apache/answer/internal/service/report_common"
|
|
"github.com/apache/answer/internal/service/review"
|
|
"github.com/apache/answer/internal/service/revision"
|
|
"github.com/apache/answer/internal/service/tag_common"
|
|
usercommon "github.com/apache/answer/internal/service/user_common"
|
|
"github.com/apache/answer/pkg/converter"
|
|
"github.com/apache/answer/pkg/htmltext"
|
|
"github.com/apache/answer/pkg/obj"
|
|
"github.com/apache/answer/pkg/uid"
|
|
"github.com/jinzhu/copier"
|
|
"github.com/segmentfault/pacman/errors"
|
|
"github.com/segmentfault/pacman/log"
|
|
)
|
|
|
|
// RevisionService user service
|
|
type RevisionService struct {
|
|
revisionRepo revision.RevisionRepo
|
|
userCommon *usercommon.UserCommon
|
|
questionCommon *questioncommon.QuestionCommon
|
|
answerService *AnswerService
|
|
objectInfoService *object_info.ObjService
|
|
questionRepo questioncommon.QuestionRepo
|
|
answerRepo answercommon.AnswerRepo
|
|
tagRepo tag_common.TagRepo
|
|
tagCommon *tag_common.TagCommonService
|
|
notificationQueueService noticequeue.Service
|
|
activityQueueService activityqueue.Service
|
|
reportRepo report_common.ReportRepo
|
|
reviewService *review.ReviewService
|
|
reviewActivity activity.ReviewActivityRepo
|
|
}
|
|
|
|
func NewRevisionService(
|
|
revisionRepo revision.RevisionRepo,
|
|
userCommon *usercommon.UserCommon,
|
|
questionCommon *questioncommon.QuestionCommon,
|
|
answerService *AnswerService,
|
|
objectInfoService *object_info.ObjService,
|
|
questionRepo questioncommon.QuestionRepo,
|
|
answerRepo answercommon.AnswerRepo,
|
|
tagRepo tag_common.TagRepo,
|
|
tagCommon *tag_common.TagCommonService,
|
|
notificationQueueService noticequeue.Service,
|
|
activityQueueService activityqueue.Service,
|
|
reportRepo report_common.ReportRepo,
|
|
reviewService *review.ReviewService,
|
|
reviewActivity activity.ReviewActivityRepo,
|
|
) *RevisionService {
|
|
return &RevisionService{
|
|
revisionRepo: revisionRepo,
|
|
userCommon: userCommon,
|
|
questionCommon: questionCommon,
|
|
answerService: answerService,
|
|
objectInfoService: objectInfoService,
|
|
questionRepo: questionRepo,
|
|
answerRepo: answerRepo,
|
|
tagRepo: tagRepo,
|
|
tagCommon: tagCommon,
|
|
notificationQueueService: notificationQueueService,
|
|
activityQueueService: activityQueueService,
|
|
reportRepo: reportRepo,
|
|
reviewService: reviewService,
|
|
reviewActivity: reviewActivity,
|
|
}
|
|
}
|
|
|
|
func (rs *RevisionService) RevisionAudit(ctx context.Context, req *schema.RevisionAuditReq) (err error) {
|
|
revisioninfo, exist, err := rs.revisionRepo.GetRevisionByID(ctx, req.ID)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if !exist {
|
|
return
|
|
}
|
|
if revisioninfo.Status != entity.RevisionUnreviewedStatus {
|
|
return
|
|
}
|
|
objectType, objectTypeerr := obj.GetObjectTypeStrByObjectID(revisioninfo.ObjectID)
|
|
if objectTypeerr != nil {
|
|
return objectTypeerr
|
|
}
|
|
if req.Operation == schema.RevisionAuditReject {
|
|
if err = checkRevisionAuditPermission(req, objectType); err != nil {
|
|
return err
|
|
}
|
|
err = rs.revisionRepo.UpdateStatus(ctx, req.ID, entity.RevisionReviewRejectStatus, req.UserID)
|
|
return
|
|
}
|
|
if req.Operation == schema.RevisionAuditApprove {
|
|
if err = checkRevisionAuditPermission(req, objectType); err != nil {
|
|
return err
|
|
}
|
|
revisionitem := &schema.GetRevisionResp{}
|
|
_ = copier.Copy(revisionitem, revisioninfo)
|
|
rs.parseItem(ctx, revisionitem)
|
|
var saveErr error
|
|
switch objectType {
|
|
case constant.QuestionObjectType:
|
|
saveErr = rs.revisionAuditQuestion(ctx, revisionitem)
|
|
case constant.AnswerObjectType:
|
|
saveErr = rs.revisionAuditAnswer(ctx, revisionitem)
|
|
case constant.TagObjectType:
|
|
saveErr = rs.revisionAuditTag(ctx, revisionitem)
|
|
}
|
|
if saveErr != nil {
|
|
return saveErr
|
|
}
|
|
err = rs.revisionRepo.UpdateStatus(ctx, req.ID, entity.RevisionReviewPassStatus, req.UserID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = rs.reviewActivity.Review(ctx, &schema.PassReviewActivity{
|
|
UserID: revisioninfo.UserID,
|
|
TriggerUserID: req.UserID,
|
|
ObjectID: revisioninfo.ObjectID,
|
|
OriginalObjectID: "0",
|
|
RevisionID: revisioninfo.ID,
|
|
})
|
|
if err != nil {
|
|
log.Errorf("add review activity failed: %v", err)
|
|
}
|
|
|
|
msg := &schema.NotificationMsg{
|
|
TriggerUserID: req.UserID,
|
|
ReceiverUserID: revisioninfo.UserID,
|
|
Type: schema.NotificationTypeAchievement,
|
|
ObjectID: revisioninfo.ObjectID,
|
|
ObjectType: objectType,
|
|
}
|
|
rs.notificationQueueService.Send(ctx, msg)
|
|
return
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func checkRevisionAuditPermission(req *schema.RevisionAuditReq, objectType string) error {
|
|
switch objectType {
|
|
case constant.QuestionObjectType:
|
|
if !req.CanReviewQuestion {
|
|
return errors.BadRequest(reason.RevisionNoPermission)
|
|
}
|
|
case constant.AnswerObjectType:
|
|
if !req.CanReviewAnswer {
|
|
return errors.BadRequest(reason.RevisionNoPermission)
|
|
}
|
|
case constant.TagObjectType:
|
|
if !req.CanReviewTag {
|
|
return errors.BadRequest(reason.RevisionNoPermission)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (rs *RevisionService) revisionAuditQuestion(ctx context.Context, revisionitem *schema.GetRevisionResp) (err error) {
|
|
questioninfo, ok := revisionitem.ContentParsed.(*schema.QuestionInfoResp)
|
|
if ok {
|
|
var PostUpdateTime time.Time
|
|
dbquestion, exist, dberr := rs.questionRepo.GetQuestion(ctx, questioninfo.ID)
|
|
if dberr != nil || !exist {
|
|
return
|
|
}
|
|
|
|
PostUpdateTime = time.Unix(questioninfo.UpdateTime, 0)
|
|
if dbquestion.PostUpdateTime.Unix() > PostUpdateTime.Unix() {
|
|
PostUpdateTime = dbquestion.PostUpdateTime
|
|
}
|
|
question := &entity.Question{}
|
|
question.ID = questioninfo.ID
|
|
question.Title = questioninfo.Title
|
|
question.OriginalText = questioninfo.Content
|
|
question.ParsedText = questioninfo.HTML
|
|
question.UpdatedAt = time.Unix(questioninfo.UpdateTime, 0)
|
|
question.PostUpdateTime = PostUpdateTime
|
|
question.LastEditUserID = revisionitem.UserID
|
|
saveerr := rs.questionRepo.UpdateQuestion(ctx, question, []string{"title", "original_text", "parsed_text", "updated_at", "post_update_time", "last_edit_user_id"})
|
|
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
|
|
minimumTags, err := rs.tagCommon.GetMinimumTags(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, saveerr = rs.tagCommon.ObjectChangeTag(ctx, &objectTagData, minimumTags)
|
|
if saveerr != nil {
|
|
return saveerr
|
|
}
|
|
rs.activityQueueService.Send(ctx, &schema.ActivityMsg{
|
|
UserID: revisionitem.UserID,
|
|
ObjectID: revisionitem.ObjectID,
|
|
ActivityTypeKey: constant.ActQuestionEdited,
|
|
RevisionID: revisionitem.ID,
|
|
OriginalObjectID: revisionitem.ObjectID,
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (rs *RevisionService) revisionAuditAnswer(ctx context.Context, revisionitem *schema.GetRevisionResp) (err error) {
|
|
answerinfo, ok := revisionitem.ContentParsed.(*schema.AnswerInfo)
|
|
if ok {
|
|
var PostUpdateTime time.Time
|
|
dbquestion, exist, dberr := rs.questionRepo.GetQuestion(ctx, answerinfo.QuestionID)
|
|
if dberr != nil || !exist {
|
|
return
|
|
}
|
|
|
|
PostUpdateTime = time.Unix(answerinfo.UpdateTime, 0)
|
|
if dbquestion.PostUpdateTime.Unix() > PostUpdateTime.Unix() {
|
|
PostUpdateTime = dbquestion.PostUpdateTime
|
|
}
|
|
|
|
insertData := new(entity.Answer)
|
|
insertData.ID = answerinfo.ID
|
|
insertData.OriginalText = answerinfo.Content
|
|
insertData.ParsedText = answerinfo.HTML
|
|
insertData.UpdatedAt = time.Unix(answerinfo.UpdateTime, 0)
|
|
insertData.LastEditUserID = revisionitem.UserID
|
|
saveerr := rs.answerRepo.UpdateAnswer(ctx, insertData, []string{"original_text", "parsed_text", "updated_at", "last_edit_user_id"})
|
|
if saveerr != nil {
|
|
return saveerr
|
|
}
|
|
saveerr = rs.questionCommon.UpdatePostSetTime(ctx, answerinfo.QuestionID, PostUpdateTime)
|
|
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: revisionitem.UserID,
|
|
ReceiverUserID: questionInfo.UserID,
|
|
Type: schema.NotificationTypeInbox,
|
|
ObjectID: answerinfo.ID,
|
|
}
|
|
msg.ObjectType = constant.AnswerObjectType
|
|
msg.NotificationAction = constant.NotificationUpdateAnswer
|
|
rs.notificationQueueService.Send(ctx, msg)
|
|
|
|
rs.activityQueueService.Send(ctx, &schema.ActivityMsg{
|
|
UserID: revisionitem.UserID,
|
|
ObjectID: insertData.ID,
|
|
OriginalObjectID: insertData.ID,
|
|
ActivityTypeKey: constant.ActAnswerEdited,
|
|
RevisionID: revisionitem.ID,
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (rs *RevisionService) revisionAuditTag(ctx context.Context, revisionitem *schema.GetRevisionResp) (err error) {
|
|
taginfo, ok := revisionitem.ContentParsed.(*schema.GetTagResp)
|
|
if ok {
|
|
tag := &entity.Tag{}
|
|
tag.ID = taginfo.TagID
|
|
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
|
|
}
|
|
}
|
|
|
|
rs.activityQueueService.Send(ctx, &schema.ActivityMsg{
|
|
UserID: revisionitem.UserID,
|
|
ObjectID: taginfo.TagID,
|
|
OriginalObjectID: taginfo.TagID,
|
|
ActivityTypeKey: constant.ActTagEdited,
|
|
RevisionID: revisionitem.ID,
|
|
})
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetUnreviewedRevisionPage get unreviewed list
|
|
func (rs *RevisionService) GetUnreviewedRevisionPage(ctx context.Context, req *schema.RevisionSearch) (
|
|
resp *pager.PageModel, err error) {
|
|
revisionResp := make([]*schema.GetUnreviewedRevisionResp, 0)
|
|
if len(req.GetCanReviewObjectTypes()) == 0 {
|
|
return pager.NewPageModel(0, revisionResp), nil
|
|
}
|
|
revisionPage, total, err := rs.revisionRepo.GetUnreviewedRevisionPage(
|
|
ctx, req.Page, 1, req.GetCanReviewObjectTypes())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, rev := range revisionPage {
|
|
item := &schema.GetUnreviewedRevisionResp{}
|
|
_, ok := constant.ObjectTypeNumberMapping[rev.ObjectType]
|
|
if !ok {
|
|
continue
|
|
}
|
|
item.Type = constant.ObjectTypeNumberMapping[rev.ObjectType]
|
|
info, err := rs.objectInfoService.GetUnreviewedRevisionInfo(ctx, rev.ObjectID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
item.Info = info
|
|
revisionitem := &schema.GetRevisionResp{}
|
|
_ = copier.Copy(revisionitem, rev)
|
|
rs.parseItem(ctx, revisionitem)
|
|
item.UnreviewedInfo = revisionitem
|
|
|
|
// get user info
|
|
userInfo, exists, e := rs.userCommon.GetUserBasicInfoByID(ctx, revisionitem.UserID)
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
if exists {
|
|
var uinfo schema.UserBasicInfo
|
|
_ = copier.Copy(&uinfo, userInfo)
|
|
item.UnreviewedInfo.UserInfo = uinfo
|
|
}
|
|
item.Info.UrlTitle = htmltext.UrlTitle(item.Info.Title)
|
|
item.UnreviewedInfo.UrlTitle = htmltext.UrlTitle(item.UnreviewedInfo.Title)
|
|
revisionResp = append(revisionResp, item)
|
|
}
|
|
return pager.NewPageModel(total, revisionResp), nil
|
|
}
|
|
|
|
// GetRevisionList get revision list all
|
|
func (rs *RevisionService) GetRevisionList(ctx context.Context, req *schema.GetRevisionListReq) (resp []schema.GetRevisionResp, err error) {
|
|
var (
|
|
rev entity.Revision
|
|
revs []entity.Revision
|
|
)
|
|
|
|
resp = []schema.GetRevisionResp{}
|
|
objInfo, infoErr := rs.objectInfoService.GetInfo(ctx, req.ObjectID)
|
|
if infoErr != nil {
|
|
return nil, infoErr
|
|
}
|
|
if err := objInfo.CheckVisibility(req.UserID, req.IsAdmin); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_ = copier.Copy(&rev, req)
|
|
|
|
revs, err = rs.revisionRepo.GetRevisionList(ctx, &rev)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, r := range revs {
|
|
var (
|
|
uinfo schema.UserBasicInfo
|
|
item schema.GetRevisionResp
|
|
)
|
|
|
|
_ = copier.Copy(&item, r)
|
|
rs.parseItem(ctx, &item)
|
|
|
|
// get user info
|
|
userInfo, exists, e := rs.userCommon.GetUserBasicInfoByID(ctx, item.UserID)
|
|
if e != nil {
|
|
return nil, e
|
|
}
|
|
if exists {
|
|
err = copier.Copy(&uinfo, userInfo)
|
|
item.UserInfo = uinfo
|
|
}
|
|
resp = append(resp, item)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (rs *RevisionService) parseItem(ctx context.Context, item *schema.GetRevisionResp) {
|
|
var (
|
|
err error
|
|
question entity.QuestionWithTagsRevision
|
|
questionInfo *schema.QuestionInfoResp
|
|
answer entity.Answer
|
|
answerInfo *schema.AnswerInfo
|
|
tag entity.Tag
|
|
tagInfo *schema.GetTagResp
|
|
)
|
|
|
|
shortID := handler.GetEnableShortID(ctx)
|
|
if shortID {
|
|
item.ObjectID = uid.EnShortID(item.ObjectID)
|
|
}
|
|
switch item.ObjectType {
|
|
case constant.ObjectTypeStrMapping["question"]:
|
|
err = json.Unmarshal([]byte(item.Content), &question)
|
|
if err != nil {
|
|
break
|
|
}
|
|
questionInfo = rs.questionCommon.ShowFormatWithTag(ctx, &question)
|
|
if shortID {
|
|
questionInfo.ID = uid.EnShortID(questionInfo.ID)
|
|
}
|
|
item.ContentParsed = questionInfo
|
|
case constant.ObjectTypeStrMapping["answer"]:
|
|
err = json.Unmarshal([]byte(item.Content), &answer)
|
|
if err != nil {
|
|
break
|
|
}
|
|
answerInfo = rs.answerService.ShowFormat(ctx, &answer)
|
|
if shortID {
|
|
answerInfo.ID = uid.EnShortID(answerInfo.ID)
|
|
answerInfo.QuestionID = uid.EnShortID(answerInfo.QuestionID)
|
|
}
|
|
item.ContentParsed = answerInfo
|
|
case constant.ObjectTypeStrMapping["tag"]:
|
|
err = json.Unmarshal([]byte(item.Content), &tag)
|
|
if err != nil {
|
|
break
|
|
}
|
|
tagInfo = &schema.GetTagResp{
|
|
TagID: tag.ID,
|
|
CreatedAt: tag.CreatedAt.Unix(),
|
|
UpdatedAt: tag.UpdatedAt.Unix(),
|
|
SlugName: tag.SlugName,
|
|
DisplayName: tag.DisplayName,
|
|
OriginalText: tag.OriginalText,
|
|
ParsedText: tag.ParsedText,
|
|
FollowCount: tag.FollowCount,
|
|
QuestionCount: tag.QuestionCount,
|
|
Recommend: tag.Recommend,
|
|
Reserved: tag.Reserved,
|
|
}
|
|
tagInfo.GetExcerpt()
|
|
item.ContentParsed = tagInfo
|
|
}
|
|
|
|
if err != nil {
|
|
item.ContentParsed = item.Content
|
|
}
|
|
item.CreatedAtParsed = item.CreatedAt.Unix()
|
|
}
|
|
|
|
// CheckCanUpdateRevision can check revision
|
|
func (rs *RevisionService) CheckCanUpdateRevision(ctx context.Context, req *schema.CheckCanQuestionUpdate) (
|
|
resp *schema.ErrTypeData, err error) {
|
|
_, exist, err := rs.revisionRepo.ExistUnreviewedByObjectID(ctx, req.ID)
|
|
if err != nil {
|
|
return nil, nil
|
|
}
|
|
if exist {
|
|
return &schema.ErrTypeToast, errors.BadRequest(reason.RevisionReviewUnderway)
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
// GetReviewingType get reviewing type
|
|
func (rs *RevisionService) GetReviewingType(ctx context.Context, req *schema.GetReviewingTypeReq) (resp []*schema.GetReviewingTypeResp, err error) {
|
|
resp = make([]*schema.GetReviewingTypeResp, 0)
|
|
|
|
// get queue amount
|
|
if req.IsAdmin {
|
|
reviewCount, err := rs.reviewService.GetReviewPendingCount(ctx)
|
|
if err != nil {
|
|
log.Errorf("get report count failed: %v", err)
|
|
} else {
|
|
resp = append(resp, &schema.GetReviewingTypeResp{
|
|
Name: string(constant.QueuedPost),
|
|
Label: translator.Tr(handler.GetLangByCtx(ctx), constant.ReviewQueuedPostLabel),
|
|
TodoAmount: reviewCount,
|
|
})
|
|
}
|
|
}
|
|
|
|
// get flag amount
|
|
if req.IsAdmin {
|
|
reportCount, err := rs.reportRepo.GetReportCount(ctx)
|
|
if err != nil {
|
|
log.Errorf("get report count failed: %v", err)
|
|
} else {
|
|
resp = append(resp, &schema.GetReviewingTypeResp{
|
|
Name: string(constant.FlaggedPost),
|
|
Label: translator.Tr(handler.GetLangByCtx(ctx), constant.ReviewFlaggedPostLabel),
|
|
TodoAmount: reportCount,
|
|
})
|
|
}
|
|
}
|
|
|
|
// get suggestion amount
|
|
countUnreviewedRevision, err := rs.revisionRepo.CountUnreviewedRevision(ctx, req.GetCanReviewObjectTypes())
|
|
if err != nil {
|
|
log.Errorf("get unreviewed revision count failed: %v", err)
|
|
} else {
|
|
resp = append(resp, &schema.GetReviewingTypeResp{
|
|
Name: string(constant.SuggestedPostEdit),
|
|
Label: translator.Tr(handler.GetLangByCtx(ctx), constant.ReviewSuggestedPostEditLabel),
|
|
TodoAmount: countUnreviewedRevision,
|
|
})
|
|
}
|
|
return resp, nil
|
|
}
|