This is an automated email from the ASF dual-hosted git repository. linkinstar pushed a commit to branch dev in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
commit d9cca1bad10649ab628f7e11008d02a233d40522 Author: hgaol <[email protected]> AuthorDate: Thu May 9 11:28:52 2024 +0800 refactor meta_service and meta_common_service and fix other issues --- cmd/wire_gen.go | 34 +--- internal/repo/meta/meta_repo.go | 91 ++-------- internal/schema/meta_schema.go | 14 +- internal/service/activity/activity.go | 6 +- internal/service/content/question_service.go | 6 +- internal/service/meta/meta_service.go | 190 +++++++++++++-------- .../service/meta_common/meta_common_service.go | 99 +++++++++++ internal/service/mock/siteinfo_repo_mock.go | 19 --- internal/service/provider.go | 4 +- internal/service/question_common/question.go | 12 +- ui/src/common/interface.ts | 7 + .../Detail/components/Reactions/index.tsx | 6 +- ui/src/services/common.ts | 2 +- 13 files changed, 272 insertions(+), 218 deletions(-) diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go index 4ce4612f..d17655c5 100644 --- a/cmd/wire_gen.go +++ b/cmd/wire_gen.go @@ -1,28 +1,8 @@ -//go:build !wireinject -// +build !wireinject - -/* - * 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. - */ - // Code generated by Wire. DO NOT EDIT. //go:generate go run github.com/google/wire/cmd/wire +//go:build !wireinject +// +build !wireinject package answercmd @@ -81,6 +61,7 @@ import ( export2 "github.com/apache/incubator-answer/internal/service/export" "github.com/apache/incubator-answer/internal/service/follow" meta2 "github.com/apache/incubator-answer/internal/service/meta" + "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/apache/incubator-answer/internal/service/notice_queue" "github.com/apache/incubator-answer/internal/service/notification" "github.com/apache/incubator-answer/internal/service/notification_common" @@ -169,8 +150,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, collectionCommon := collectioncommon.NewCollectionCommon(collectionRepo) answerCommon := answercommon.NewAnswerCommon(answerRepo) metaRepo := meta.NewMetaRepo(dataData) - metaService := meta2.NewMetaService(metaRepo, userCommon) - questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaService, configService, activityQueueService, revisionRepo, dataData) + metaCommonService := metacommon.NewMetaCommonService(metaRepo) + questionCommon := questioncommon.NewQuestionCommon(questionRepo, answerRepo, voteRepo, followRepo, tagCommonService, userCommon, collectionCommon, answerCommon, metaCommonService, configService, activityQueueService, revisionRepo, dataData) userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon) captchaRepo := captcha.NewCaptchaRepo(dataData) captchaService := action.NewCaptchaService(captchaRepo) @@ -193,7 +174,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService, userExternalLoginRepo, siteInfoCommonService) reviewRepo := review.NewReviewRepo(dataData) reviewService := review2.NewReviewService(reviewRepo, objService, userCommon, userRepo, questionRepo, answerRepo, userRoleRelService, externalNotificationQueueService, tagCommonService, notificationQueueService, siteInfoCommonService) - questionService := content.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService) + questionService := content.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService) answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService) reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService) reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService) @@ -240,7 +221,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, activityActivityRepo := activity.NewActivityRepo(dataData, configService) activityCommon := activity_common2.NewActivityCommon(activityRepo, activityQueueService) commentCommonService := comment_common.NewCommentCommonService(commentCommonRepo) - activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaService, configService) + activityService := activity2.NewActivityService(activityActivityRepo, userCommon, activityCommon, tagCommonService, objService, commentCommonService, revisionService, metaCommonService, configService) activityController := controller.NewActivityController(activityService) roleController := controller_admin.NewRoleController(roleService) pluginConfigRepo := plugin_config.NewPluginConfigRepo(dataData) @@ -250,6 +231,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database, permissionController := controller.NewPermissionController(rankService) userPluginController := controller.NewUserPluginController(pluginCommonService) reviewController := controller.NewReviewController(reviewService, rankService, captchaService) + metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo) metaController := controller.NewMetaController(metaService) answerAPIRouter := router.NewAnswerAPIRouter(langController, userController, commentController, reportController, voteController, tagController, followController, collectionController, questionController, answerController, searchController, revisionController, rankController, userAdminController, reasonController, themeController, siteInfoController, controllerSiteInfoController, notificationController, dashboardController, uploadController, activityController, roleController, pluginCon [...] swaggerRouter := router.NewSwaggerRouter(swaggerConf) diff --git a/internal/repo/meta/meta_repo.go b/internal/repo/meta/meta_repo.go index c3e85c71..384fd185 100644 --- a/internal/repo/meta/meta_repo.go +++ b/internal/repo/meta/meta_repo.go @@ -21,13 +21,11 @@ package meta import ( "context" - "encoding/json" "github.com/apache/incubator-answer/internal/base/data" "github.com/apache/incubator-answer/internal/base/reason" "github.com/apache/incubator-answer/internal/entity" - "github.com/apache/incubator-answer/internal/schema" - "github.com/apache/incubator-answer/internal/service/meta" + "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/segmentfault/pacman/errors" "xorm.io/builder" "xorm.io/xorm" @@ -39,7 +37,7 @@ type metaRepo struct { } // NewMetaRepo new repository -func NewMetaRepo(data *data.Data) meta.MetaRepo { +func NewMetaRepo(data *data.Data) metacommon.MetaRepo { return &metaRepo{ data: data, } @@ -73,97 +71,32 @@ func (mr *metaRepo) UpdateMeta(ctx context.Context, meta *entity.Meta) (err erro } // AddOrUpdateMetaByObjectIdAndKey if exist record with same objectID and key, update it. Or create a new one -func (mr *metaRepo) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, req *schema.UpdateReactionReq) (schema.ReactSummaryMeta, error) { - result, err := mr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { +func (mr *metaRepo) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objectId, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) error { + _, err := mr.data.DB.Transaction(func(session *xorm.Session) (interface{}, error) { session = session.Context(ctx) // 1. acquire meta entity with target object id and key metaEntity := &entity.Meta{} - exist, err := mr.data.DB.Context(ctx).Where(builder.Eq{"object_id": req.ObjectID}.And(builder.Eq{"`key`": entity.ObjectReactSummaryKey})).ForUpdate().Get(metaEntity) + exist, err := session.Where(builder.Eq{"object_id": objectId}.And(builder.Eq{"`key`": key})).ForUpdate().Get(metaEntity) if err != nil { - return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() - } - - var reaction schema.ReactSummaryMeta - // if not exist, create new one - if !exist { - reaction = schema.ReactSummaryMeta{} - } else { - err = json.Unmarshal([]byte(metaEntity.Value), &reaction) - if err != nil { - return nil, err - } + return nil, err } - // update reaction - mr.updateReaction(req, reaction) - - // write back to meta repo - reactSumBytes, err := json.Marshal(reaction) + meta, err := f(metaEntity, exist) if err != nil { return nil, err } - metaObj := &entity.Meta{ - ObjectID: req.ObjectID, - Key: entity.ObjectReactSummaryKey, - Value: string(reactSumBytes), - } + // return entity.Meta if exist { - _, err = session.Update(metaObj) + _, err = session.ID(metaEntity.ID).Update(meta) } else { - _, err = session.Insert(metaObj) + _, err = session.Insert(meta) } - return reaction, err + return nil, err }) - - if err != nil { - return nil, errors.InternalServer(reason.DatabaseError).WithError(err) - } - - if ret, ok := result.(schema.ReactSummaryMeta); ok { - return ret, nil - } else { - return nil, errors.InternalServer(reason.UnknownError).WithMsg("Unable to cast to schema.ReactSummaryMeta.") - } -} - -// updateReaction update reaction -func (mr *metaRepo) updateReaction(req *schema.UpdateReactionReq, reaction schema.ReactSummaryMeta) { - emojiUserIds, ok := reaction[req.Emoji] - - if !ok { - emojiUserIds = make([]string, 0) - } - - found := false - for _, item := range emojiUserIds { - if item == req.UserID { - found = true - break - } - } - - removeItem := func(arr []string, target string) []string { - result := make([]string, 0, len(arr)) - - for _, item := range arr { - if item != target { - result = append(result, item) - } - } - - return result - } - - if req.Reaction == "activate" && !found { - emojiUserIds = append(emojiUserIds, req.UserID) - } else if req.Reaction == "deactivate" && found { - emojiUserIds = removeItem(emojiUserIds, req.UserID) - } - - reaction[req.Emoji] = emojiUserIds + return err } // GetMetaByObjectIdAndKey get meta one diff --git a/internal/schema/meta_schema.go b/internal/schema/meta_schema.go index bf458bfc..0774aca2 100644 --- a/internal/schema/meta_schema.go +++ b/internal/schema/meta_schema.go @@ -20,16 +20,20 @@ package schema type UpdateReactionReq struct { - ObjectID string `validate:"required" form:"object_id" json:"object_id"` // object id - Emoji string `validate:"required" form:"emoji" json:"emoji"` // emoji - Reaction string `validate:"required" form:"reaction" json:"reaction"` // reaction + ObjectID string `validate:"required" json:"object_id"` + Emoji string `validate:"required,oneof=heart smile frown" json:"emoji"` + Reaction string `validate:"required,oneof=activate deactivate" json:"reaction"` UserID string `json:"-"` } type GetReactionReq struct { - ObjectID string `validate:"required" form:"object_id" json:"object_id"` // object id + ObjectID string `validate:"required" form:"object_id"` } type ReactSummaryMeta map[string][]string -type ReactionResp ReactSummaryMeta +type ReactionResp struct { + // reaction summary is a map, key is emoji, value is username list + // such as {"heart": ["jack", "tom"], "smile": ["andy"], "frown": ["bob"]} + ReactionSummary ReactSummaryMeta `json:"reaction_summary"` +} diff --git a/internal/service/activity/activity.go b/internal/service/activity/activity.go index f6d692f5..7188fa94 100644 --- a/internal/service/activity/activity.go +++ b/internal/service/activity/activity.go @@ -26,6 +26,7 @@ import ( "strings" "github.com/apache/incubator-answer/internal/service/activity_common" + "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/apache/incubator-answer/internal/base/constant" "github.com/apache/incubator-answer/internal/base/handler" @@ -33,7 +34,6 @@ import ( "github.com/apache/incubator-answer/internal/schema" "github.com/apache/incubator-answer/internal/service/comment_common" "github.com/apache/incubator-answer/internal/service/config" - "github.com/apache/incubator-answer/internal/service/meta" "github.com/apache/incubator-answer/internal/service/object_info" "github.com/apache/incubator-answer/internal/service/revision_common" "github.com/apache/incubator-answer/internal/service/tag_common" @@ -58,7 +58,7 @@ type ActivityService struct { objectInfoService *object_info.ObjService commentCommonService *comment_common.CommentCommonService revisionService *revision_common.RevisionService - metaService *meta.MetaService + metaService *metacommon.MetaCommonService configService *config.ConfigService } @@ -71,7 +71,7 @@ func NewActivityService( objectInfoService *object_info.ObjService, commentCommonService *comment_common.CommentCommonService, revisionService *revision_common.RevisionService, - metaService *meta.MetaService, + metaService *metacommon.MetaCommonService, configService *config.ConfigService, ) *ActivityService { return &ActivityService{ diff --git a/internal/service/content/question_service.go b/internal/service/content/question_service.go index 171f67bd..e11a608b 100644 --- a/internal/service/content/question_service.go +++ b/internal/service/content/question_service.go @@ -38,7 +38,7 @@ import ( collectioncommon "github.com/apache/incubator-answer/internal/service/collection_common" "github.com/apache/incubator-answer/internal/service/config" "github.com/apache/incubator-answer/internal/service/export" - "github.com/apache/incubator-answer/internal/service/meta" + "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/apache/incubator-answer/internal/service/notice_queue" "github.com/apache/incubator-answer/internal/service/notification" "github.com/apache/incubator-answer/internal/service/permission" @@ -71,7 +71,7 @@ type QuestionService struct { userRepo usercommon.UserRepo userRoleRelService *role.UserRoleRelService revisionService *revision_common.RevisionService - metaService *meta.MetaService + metaService *metacommon.MetaCommonService collectionCommon *collectioncommon.CollectionCommon answerActivityService *activity.AnswerActivityService emailService *export.EmailService @@ -92,7 +92,7 @@ func NewQuestionService( userRepo usercommon.UserRepo, userRoleRelService *role.UserRoleRelService, revisionService *revision_common.RevisionService, - metaService *meta.MetaService, + metaService *metacommon.MetaCommonService, collectionCommon *collectioncommon.CollectionCommon, answerActivityService *activity.AnswerActivityService, emailService *export.EmailService, diff --git a/internal/service/meta/meta_service.go b/internal/service/meta/meta_service.go index b06fa736..a22e0237 100644 --- a/internal/service/meta/meta_service.go +++ b/internal/service/meta/meta_service.go @@ -24,110 +24,117 @@ import ( "encoding/json" "errors" + "github.com/apache/incubator-answer/internal/base/constant" "github.com/apache/incubator-answer/internal/base/reason" "github.com/apache/incubator-answer/internal/entity" "github.com/apache/incubator-answer/internal/schema" + answercommon "github.com/apache/incubator-answer/internal/service/answer_common" + metacommon "github.com/apache/incubator-answer/internal/service/meta_common" + questioncommon "github.com/apache/incubator-answer/internal/service/question_common" usercommon "github.com/apache/incubator-answer/internal/service/user_common" + "github.com/apache/incubator-answer/pkg/obj" myErrors "github.com/segmentfault/pacman/errors" ) -// MetaRepo meta repository -type MetaRepo interface { - AddMeta(ctx context.Context, meta *entity.Meta) (err error) - RemoveMeta(ctx context.Context, id int) (err error) - UpdateMeta(ctx context.Context, meta *entity.Meta) (err error) - AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, req *schema.UpdateReactionReq) (schema.ReactSummaryMeta, error) - GetMetaByObjectIdAndKey(ctx context.Context, objectId, key string) (meta *entity.Meta, exist bool, err error) - GetMetaList(ctx context.Context, meta *entity.Meta) (metas []*entity.Meta, err error) -} - // MetaService user service type MetaService struct { - metaRepo MetaRepo - userCommon *usercommon.UserCommon + metaCommonService *metacommon.MetaCommonService + userCommon *usercommon.UserCommon + questionRepo questioncommon.QuestionRepo + answerRepo answercommon.AnswerRepo } -func NewMetaService(metaRepo MetaRepo, userCommon *usercommon.UserCommon) *MetaService { +func NewMetaService(metaCommonService *metacommon.MetaCommonService, userCommon *usercommon.UserCommon, answerRepo answercommon.AnswerRepo, questionRepo questioncommon.QuestionRepo) *MetaService { return &MetaService{ - metaRepo: metaRepo, - userCommon: userCommon, - } -} - -// AddMeta add meta -func (ms *MetaService) AddMeta(ctx context.Context, objID, key, value string) (err error) { - meta := &entity.Meta{ - ObjectID: objID, - Key: key, - Value: value, - } - return ms.metaRepo.AddMeta(ctx, meta) -} - -// RemoveMeta delete meta -func (ms *MetaService) RemoveMeta(ctx context.Context, id int) (err error) { - return ms.metaRepo.RemoveMeta(ctx, id) -} - -// UpdateMeta update meta -func (ms *MetaService) UpdateMeta(ctx context.Context, metaID int, key, value string) (err error) { - meta := &entity.Meta{ - ID: metaID, - Key: key, - Value: value, - } - return ms.metaRepo.UpdateMeta(ctx, meta) -} - -// GetMetaByObjectIdAndKey get meta one -func (ms *MetaService) GetMetaByObjectIdAndKey(ctx context.Context, objectID, key string) (meta *entity.Meta, err error) { - meta, exist, err := ms.metaRepo.GetMetaByObjectIdAndKey(ctx, objectID, key) - if err != nil { - return + metaCommonService: metaCommonService, + questionRepo: questionRepo, + userCommon: userCommon, + answerRepo: answerRepo, } - if !exist { - return nil, myErrors.BadRequest(reason.MetaObjectNotFound) - } - return meta, nil -} - -// GetMetaList get meta list all -func (ms *MetaService) GetMetaList(ctx context.Context, objID string) (metas []*entity.Meta, err error) { - metas, err = ms.metaRepo.GetMetaList(ctx, &entity.Meta{ObjectID: objID}) - if err != nil { - return nil, err - } - return metas, err } // GetReactionByObjectId get reaction -func (ms *MetaService) GetReactionByObjectId(ctx context.Context, objectID string) (resp schema.ReactionResp, err error) { - reactionMeta, err := ms.GetMetaByObjectIdAndKey(ctx, objectID, entity.ObjectReactSummaryKey) +func (ms *MetaService) GetReactionByObjectId(ctx context.Context, objectID string) (resp *schema.ReactionResp, err error) { + resp = &schema.ReactionResp{} + reactionMeta, err := ms.metaCommonService.GetMetaByObjectIdAndKey(ctx, objectID, entity.ObjectReactSummaryKey) // if not exist, return nil if err != nil { var pacmanErr *myErrors.Error if errors.As(err, &pacmanErr) && pacmanErr.Reason == reason.MetaObjectNotFound { - return nil, nil + return resp, nil } else { - return nil, err + return resp, err } } var reaction schema.ReactSummaryMeta err = json.Unmarshal([]byte(reactionMeta.Value), &reaction) if err != nil { - return nil, err + return resp, err } return ms.convertToReactionResp(ctx, reaction) } // AddOrUpdateReaction add or update reaction -func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.UpdateReactionReq) (resp schema.ReactionResp, err error) { - reaction, err := ms.metaRepo.AddOrUpdateMetaByObjectIdAndKey(ctx, req) +func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.UpdateReactionReq) (resp *schema.ReactionResp, err error) { + // check if object exist and it's answer or question + objectType, err := obj.GetObjectTypeStrByObjectID(req.ObjectID) if err != nil { return nil, err } + if objectType == constant.AnswerObjectType { + _, exist, err := ms.answerRepo.GetAnswer(ctx, req.ObjectID) + if err != nil { + return nil, err + } + if !exist { + return nil, myErrors.BadRequest(reason.AnswerNotFound) + } + } else if objectType == constant.QuestionObjectType { + _, exist, err := ms.questionRepo.GetQuestion(ctx, req.ObjectID) + if err != nil { + return nil, err + } + if !exist { + return nil, myErrors.BadRequest(reason.QuestionNotFound) + } + } else { + return nil, myErrors.BadRequest(reason.ObjectNotFound) + } + + // add or update + var reaction schema.ReactSummaryMeta + err = ms.metaCommonService.AddOrUpdateMetaByObjectIdAndKey(ctx, req.ObjectID, entity.ObjectReactSummaryKey, func(meta *entity.Meta, exist bool) (*entity.Meta, error) { + // if not exist, create new one + if !exist { + reaction = schema.ReactSummaryMeta{} + } else { + err = json.Unmarshal([]byte(meta.Value), &reaction) + if err != nil { + return nil, err + } + } + + // update reaction + ms.updateReaction(req, reaction) + + // write back to meta repo + reactSumBytes, err := json.Marshal(reaction) + if err != nil { + return nil, err + } + + return &entity.Meta{ + ObjectID: req.ObjectID, + Key: entity.ObjectReactSummaryKey, + Value: string(reactSumBytes), + }, nil + }) + + if err != nil { + return nil, myErrors.InternalServer(reason.DatabaseError).WithError(err) + } resp, err = ms.convertToReactionResp(ctx, reaction) if err != nil { @@ -137,20 +144,59 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda return resp, nil } -func (ms *MetaService) convertToReactionResp(ctx context.Context, reaction schema.ReactSummaryMeta) (schema.ReactionResp, error) { - resp := schema.ReactionResp{} +// updateReaction update reaction +func (ms *MetaService) updateReaction(req *schema.UpdateReactionReq, reaction schema.ReactSummaryMeta) { + emojiUserIds, ok := reaction[req.Emoji] + + if !ok { + emojiUserIds = make([]string, 0) + } + + found := false + for _, item := range emojiUserIds { + if item == req.UserID { + found = true + break + } + } + + removeItem := func(arr []string, target string) []string { + result := make([]string, 0, len(arr)) + + for _, item := range arr { + if item != target { + result = append(result, item) + } + } + + return result + } + + if req.Reaction == "activate" && !found { + emojiUserIds = append(emojiUserIds, req.UserID) + } else if req.Reaction == "deactivate" && found { + emojiUserIds = removeItem(emojiUserIds, req.UserID) + } + + reaction[req.Emoji] = emojiUserIds +} + +func (ms *MetaService) convertToReactionResp(ctx context.Context, reaction schema.ReactSummaryMeta) (*schema.ReactionResp, error) { + resp := &schema.ReactionResp{ + ReactionSummary: make(schema.ReactSummaryMeta), + } // traverse map and convert to username for emoji, userIds := range reaction { userNames := make([]string, 0) userBasicInfos, err := ms.userCommon.BatchUserBasicInfoByID(ctx, userIds) if err != nil { - return nil, err + return resp, err } // get username for _, userBasicInfo := range userBasicInfos { userNames = append(userNames, userBasicInfo.Username) } - resp[emoji] = userNames + resp.ReactionSummary[emoji] = userNames } return resp, nil diff --git a/internal/service/meta_common/meta_common_service.go b/internal/service/meta_common/meta_common_service.go new file mode 100644 index 00000000..d34f7d43 --- /dev/null +++ b/internal/service/meta_common/meta_common_service.go @@ -0,0 +1,99 @@ +/* + * 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 metacommon + +import ( + "context" + + "github.com/apache/incubator-answer/internal/base/reason" + "github.com/apache/incubator-answer/internal/entity" + myErrors "github.com/segmentfault/pacman/errors" +) + +// MetaRepo meta repository +type MetaRepo interface { + AddMeta(ctx context.Context, meta *entity.Meta) (err error) + RemoveMeta(ctx context.Context, id int) (err error) + UpdateMeta(ctx context.Context, meta *entity.Meta) (err error) + AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objectId, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) error + GetMetaByObjectIdAndKey(ctx context.Context, objectId, key string) (meta *entity.Meta, exist bool, err error) + GetMetaList(ctx context.Context, meta *entity.Meta) (metas []*entity.Meta, err error) +} + +// MetaCommonService user service +type MetaCommonService struct { + metaRepo MetaRepo +} + +func NewMetaCommonService(metaRepo MetaRepo) *MetaCommonService { + return &MetaCommonService{ + metaRepo: metaRepo, + } +} + +// AddMeta add meta +func (ms *MetaCommonService) AddMeta(ctx context.Context, objID, key, value string) (err error) { + meta := &entity.Meta{ + ObjectID: objID, + Key: key, + Value: value, + } + return ms.metaRepo.AddMeta(ctx, meta) +} + +// RemoveMeta delete meta +func (ms *MetaCommonService) RemoveMeta(ctx context.Context, id int) (err error) { + return ms.metaRepo.RemoveMeta(ctx, id) +} + +// UpdateMeta update meta +func (ms *MetaCommonService) UpdateMeta(ctx context.Context, metaID int, key, value string) (err error) { + meta := &entity.Meta{ + ID: metaID, + Key: key, + Value: value, + } + return ms.metaRepo.UpdateMeta(ctx, meta) +} + +func (ms *MetaCommonService) AddOrUpdateMetaByObjectIdAndKey(ctx context.Context, objID, key string, f func(*entity.Meta, bool) (*entity.Meta, error)) (err error) { + return ms.metaRepo.AddOrUpdateMetaByObjectIdAndKey(ctx, objID, key, f) +} + +// GetMetaByObjectIdAndKey get meta one +func (ms *MetaCommonService) GetMetaByObjectIdAndKey(ctx context.Context, objectID, key string) (meta *entity.Meta, err error) { + meta, exist, err := ms.metaRepo.GetMetaByObjectIdAndKey(ctx, objectID, key) + if err != nil { + return + } + if !exist { + return nil, myErrors.BadRequest(reason.MetaObjectNotFound) + } + return meta, nil +} + +// GetMetaList get meta list all +func (ms *MetaCommonService) GetMetaList(ctx context.Context, objID string) (metas []*entity.Meta, err error) { + metas, err = ms.metaRepo.GetMetaList(ctx, &entity.Meta{ObjectID: objID}) + if err != nil { + return nil, err + } + return metas, err +} diff --git a/internal/service/mock/siteinfo_repo_mock.go b/internal/service/mock/siteinfo_repo_mock.go index abc1fe07..cdc72b80 100644 --- a/internal/service/mock/siteinfo_repo_mock.go +++ b/internal/service/mock/siteinfo_repo_mock.go @@ -1,22 +1,3 @@ -/* - * 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. - */ - // Code generated by MockGen. DO NOT EDIT. // Source: ./siteinfo_service.go diff --git a/internal/service/provider.go b/internal/service/provider.go index 2bdd42b6..e82d9316 100644 --- a/internal/service/provider.go +++ b/internal/service/provider.go @@ -36,6 +36,7 @@ import ( "github.com/apache/incubator-answer/internal/service/export" "github.com/apache/incubator-answer/internal/service/follow" "github.com/apache/incubator-answer/internal/service/meta" + "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/apache/incubator-answer/internal/service/notice_queue" "github.com/apache/incubator-answer/internal/service/notification" notficationcommon "github.com/apache/incubator-answer/internal/service/notification_common" @@ -89,7 +90,7 @@ var ProviderSetService = wire.NewSet( rank.NewRankService, search_parser.NewSearchParser, content.NewSearchService, - meta.NewMetaService, + metacommon.NewMetaCommonService, object_info.NewObjService, report_handle.NewReportHandle, user_admin.NewUserAdminService, @@ -115,4 +116,5 @@ var ProviderSetService = wire.NewSet( notification.NewExternalNotificationService, notice_queue.NewNewQuestionNotificationQueueService, review.NewReviewService, + meta.NewMetaService, ) diff --git a/internal/service/question_common/question.go b/internal/service/question_common/question.go index ff0b9da5..fce3761e 100644 --- a/internal/service/question_common/question.go +++ b/internal/service/question_common/question.go @@ -32,7 +32,7 @@ import ( "github.com/apache/incubator-answer/internal/service/activity_common" "github.com/apache/incubator-answer/internal/service/activity_queue" "github.com/apache/incubator-answer/internal/service/config" - "github.com/apache/incubator-answer/internal/service/meta" + metacommon "github.com/apache/incubator-answer/internal/service/meta_common" "github.com/apache/incubator-answer/internal/service/revision" "github.com/apache/incubator-answer/pkg/checker" "github.com/apache/incubator-answer/pkg/htmltext" @@ -86,7 +86,7 @@ type QuestionCommon struct { userCommon *usercommon.UserCommon collectionCommon *collectioncommon.CollectionCommon AnswerCommon *answercommon.AnswerCommon - metaService *meta.MetaService + metaCommonService *metacommon.MetaCommonService configService *config.ConfigService activityQueueService activity_queue.ActivityQueueService revisionRepo revision.RevisionRepo @@ -101,7 +101,7 @@ func NewQuestionCommon(questionRepo QuestionRepo, userCommon *usercommon.UserCommon, collectionCommon *collectioncommon.CollectionCommon, answerCommon *answercommon.AnswerCommon, - metaService *meta.MetaService, + metaCommonService *metacommon.MetaCommonService, configService *config.ConfigService, activityQueueService activity_queue.ActivityQueueService, revisionRepo revision.RevisionRepo, @@ -116,7 +116,7 @@ func NewQuestionCommon(questionRepo QuestionRepo, userCommon: userCommon, collectionCommon: collectionCommon, AnswerCommon: answerCommon, - metaService: metaService, + metaCommonService: metaCommonService, configService: configService, activityQueueService: activityQueueService, revisionRepo: revisionRepo, @@ -235,7 +235,7 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionID string, loginUser } resp = qs.ShowFormat(ctx, questionInfo) if resp.Status == entity.QuestionStatusClosed { - metaInfo, err := qs.metaService.GetMetaByObjectIdAndKey(ctx, questionInfo.ID, entity.QuestionCloseReasonKey) + metaInfo, err := qs.metaCommonService.GetMetaByObjectIdAndKey(ctx, questionInfo.ID, entity.QuestionCloseReasonKey) if err != nil { log.Error(err) } else { @@ -528,7 +528,7 @@ func (qs *QuestionCommon) CloseQuestion(ctx context.Context, req *schema.CloseQu CloseType: req.CloseType, CloseMsg: req.CloseMsg, }) - err = qs.metaService.AddMeta(ctx, req.ID, entity.QuestionCloseReasonKey, string(closeMeta)) + err = qs.metaCommonService.AddMeta(ctx, req.ID, entity.QuestionCloseReasonKey, string(closeMeta)) if err != nil { return err } diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index 53f8eef5..d5f64f40 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -719,3 +719,10 @@ export interface PutFlagReviewParams { captcha_code?: any; captcha_id?: any; } + +/** + * @description response for reaction + */ +export interface ReactionItems { + reaction_summary: Record<string, string[]>; +} diff --git a/ui/src/pages/Questions/Detail/components/Reactions/index.tsx b/ui/src/pages/Questions/Detail/components/Reactions/index.tsx index 5ade0319..0d380204 100644 --- a/ui/src/pages/Questions/Detail/components/Reactions/index.tsx +++ b/ui/src/pages/Questions/Detail/components/Reactions/index.tsx @@ -36,13 +36,13 @@ const Index: FC<Props> = ({ showAddCommentBtn, handleClickComment, }) => { - const [reactions, setReactions] = useState<Record<string, string[]>>({}); + const [reactions, setReactions] = useState<Record<string, string[]>>(); const { t } = useTranslation('translation'); const { username = '' } = loggedUserInfoStore((state) => state.user); useEffect(() => { queryReactions(objectId).then((res) => { - setReactions(res); + setReactions(res.reaction_summary); }); }, []); @@ -59,7 +59,7 @@ const Index: FC<Props> = ({ reaction = 'deactivate'; } updateReaction({ ...params, reaction }).then((res) => { - setReactions(res); + setReactions(res.reaction_summary); }); }; diff --git a/ui/src/services/common.ts b/ui/src/services/common.ts index a783fa49..dff52cb7 100644 --- a/ui/src/services/common.ts +++ b/ui/src/services/common.ts @@ -93,7 +93,7 @@ export const updateReaction = (params) => { }; export const queryReactions = (object_id: string) => { - return request.get<Record<string, string[]>>( + return request.get<Type.ReactionItems>( `/answer/api/v1/meta/reaction?object_id=${object_id}`, ); };
