feat(badge): add event for the badge
This commit is contained in:
+10
-8
@@ -78,6 +78,7 @@ import (
|
||||
config2 "github.com/apache/incubator-answer/internal/service/config"
|
||||
"github.com/apache/incubator-answer/internal/service/content"
|
||||
"github.com/apache/incubator-answer/internal/service/dashboard"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
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"
|
||||
@@ -172,7 +173,8 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||
metaRepo := meta.NewMetaRepo(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)
|
||||
eventQueueService := event_queue.NewEventQueueService()
|
||||
userService := content.NewUserService(userRepo, userActiveActivityRepo, activityRepo, emailService, authService, siteInfoCommonService, userRoleRelService, userCommon, userExternalLoginService, userNotificationConfigRepo, userNotificationConfigService, questionCommon, eventQueueService)
|
||||
captchaRepo := captcha.NewCaptchaRepo(dataData)
|
||||
captchaService := action.NewCaptchaService(captchaRepo)
|
||||
userController := controller.NewUserController(authService, userService, captchaService, emailService, siteInfoCommonService, userNotificationConfigService)
|
||||
@@ -181,7 +183,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||
objService := object_info.NewObjService(answerRepo, questionRepo, commentCommonRepo, tagCommonRepo, tagCommonService)
|
||||
notificationQueueService := notice_queue.NewNotificationQueueService()
|
||||
externalNotificationQueueService := notice_queue.NewNewQuestionNotificationQueueService()
|
||||
commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService)
|
||||
commentService := comment2.NewCommentService(commentRepo, commentCommonRepo, userCommon, objService, voteRepo, emailService, userRepo, notificationQueueService, externalNotificationQueueService, activityQueueService, eventQueueService)
|
||||
rolePowerRelRepo := role.NewRolePowerRelRepo(dataData)
|
||||
rolePowerRelService := role2.NewRolePowerRelService(rolePowerRelRepo, userRoleRelService)
|
||||
rankService := rank2.NewRankService(userCommon, userRankRepo, objService, userRoleRelService, rolePowerRelService, configService)
|
||||
@@ -194,13 +196,13 @@ 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, questionCommon, notificationQueueService, siteInfoCommonService)
|
||||
questionService := content.NewQuestionService(questionRepo, answerRepo, 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)
|
||||
questionService := content.NewQuestionService(questionRepo, answerRepo, tagCommonService, questionCommon, userCommon, userRepo, userRoleRelService, revisionService, metaCommonService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService, reviewService, configService, eventQueueService)
|
||||
answerService := content.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService, reviewService, eventQueueService)
|
||||
reportHandle := report_handle.NewReportHandle(questionService, answerService, commentService)
|
||||
reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService)
|
||||
reportService := report2.NewReportService(reportRepo, objService, userCommon, answerRepo, questionRepo, commentCommonRepo, reportHandle, configService, eventQueueService)
|
||||
reportController := controller.NewReportController(reportService, rankService, captchaService)
|
||||
contentVoteRepo := activity.NewVoteRepo(dataData, activityRepo, userRankRepo, notificationQueueService)
|
||||
voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService)
|
||||
voteService := content.NewVoteService(contentVoteRepo, configService, questionRepo, answerRepo, commentCommonRepo, objService, eventQueueService)
|
||||
voteController := controller.NewVoteController(voteService, rankService, captchaService)
|
||||
tagService := tag2.NewTagService(tagRepo, tagCommonService, revisionService, followRepo, siteInfoCommonService, activityQueueService)
|
||||
tagController := controller.NewTagController(tagService, tagCommonService, rankService)
|
||||
@@ -251,7 +253,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)
|
||||
metaService := meta2.NewMetaService(metaCommonService, userCommon, answerRepo, questionRepo, eventQueueService)
|
||||
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, pluginController, permissionController, userPluginController, reviewController, metaController)
|
||||
swaggerRouter := router.NewSwaggerRouter(swaggerConf)
|
||||
@@ -260,7 +262,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
|
||||
avatarMiddleware := middleware.NewAvatarMiddleware(serviceConf, uploaderService)
|
||||
shortIDMiddleware := middleware.NewShortIDMiddleware(siteInfoCommonService)
|
||||
templateRenderController := templaterender.NewTemplateRenderController(questionService, userService, tagService, answerService, commentService, siteInfoCommonService, questionRepo)
|
||||
templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService)
|
||||
templateController := controller.NewTemplateController(templateRenderController, siteInfoCommonService, eventQueueService, userService)
|
||||
templateRouter := router.NewTemplateRouter(templateController, templateRenderController, siteInfoController, authUserMiddleware)
|
||||
connectorController := controller.NewConnectorController(siteInfoCommonService, emailService, userExternalLoginService)
|
||||
userCenterLoginService := user_external_login2.NewUserCenterLoginService(userRepo, userCommon, userExternalLoginRepo, userActiveActivityRepo, siteInfoCommonService)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 constant
|
||||
|
||||
// EventType event type. It is used to define the type of event. Such as object.action
|
||||
type EventType string
|
||||
|
||||
// event object
|
||||
const (
|
||||
eventQuestion = "question"
|
||||
eventAnswer = "answer"
|
||||
eventComment = "comment"
|
||||
eventUser = "user"
|
||||
)
|
||||
|
||||
// event action
|
||||
const (
|
||||
eventCreate = "create"
|
||||
eventUpdate = "update"
|
||||
eventDelete = "delete"
|
||||
eventVote = "vote"
|
||||
eventAccept = "accept" // only question have the accept event
|
||||
eventShare = "share" // the object share link has been clicked
|
||||
eventFlag = "flag"
|
||||
eventReact = "react"
|
||||
)
|
||||
|
||||
const (
|
||||
EventUserUpdate EventType = eventUser + "." + eventUpdate
|
||||
EventUserShare EventType = eventUser + "." + eventShare
|
||||
)
|
||||
|
||||
const (
|
||||
EventQuestionCreate EventType = eventQuestion + "." + eventCreate
|
||||
EventQuestionUpdate EventType = eventQuestion + "." + eventUpdate
|
||||
EventQuestionDelete EventType = eventQuestion + "." + eventDelete
|
||||
EventQuestionVote EventType = eventQuestion + "." + eventVote
|
||||
EventQuestionAccept EventType = eventQuestion + "." + eventAccept
|
||||
EventQuestionFlag EventType = eventQuestion + "." + eventFlag
|
||||
EventQuestionReact EventType = eventQuestion + "." + eventReact
|
||||
)
|
||||
|
||||
const (
|
||||
EventAnswerCreate EventType = eventAnswer + "." + eventCreate
|
||||
EventAnswerUpdate EventType = eventAnswer + "." + eventUpdate
|
||||
EventAnswerDelete EventType = eventAnswer + "." + eventDelete
|
||||
EventAnswerVote EventType = eventAnswer + "." + eventVote
|
||||
EventAnswerFlag EventType = eventAnswer + "." + eventFlag
|
||||
EventAnswerReact EventType = eventAnswer + "." + eventReact
|
||||
)
|
||||
|
||||
const (
|
||||
EventCommentCreate EventType = eventComment + "." + eventCreate
|
||||
EventCommentUpdate EventType = eventComment + "." + eventUpdate
|
||||
EventCommentDelete EventType = eventComment + "." + eventDelete
|
||||
EventCommentVote EventType = eventComment + "." + eventVote
|
||||
EventCommentFlag EventType = eventComment + "." + eventFlag
|
||||
)
|
||||
@@ -22,6 +22,8 @@ package controller
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/apache/incubator-answer/internal/service/content"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"github.com/apache/incubator-answer/plugin"
|
||||
"html/template"
|
||||
"net/http"
|
||||
@@ -54,12 +56,16 @@ type TemplateController struct {
|
||||
cssPath string
|
||||
templateRenderController *templaterender.TemplateRenderController
|
||||
siteInfoService siteinfo_common.SiteInfoCommonService
|
||||
eventQueueService event_queue.EventQueueService
|
||||
userService *content.UserService
|
||||
}
|
||||
|
||||
// NewTemplateController new controller
|
||||
func NewTemplateController(
|
||||
templateRenderController *templaterender.TemplateRenderController,
|
||||
siteInfoService siteinfo_common.SiteInfoCommonService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
userService *content.UserService,
|
||||
) *TemplateController {
|
||||
script, css := GetStyle()
|
||||
return &TemplateController{
|
||||
@@ -67,6 +73,8 @@ func NewTemplateController(
|
||||
cssPath: css,
|
||||
templateRenderController: templateRenderController,
|
||||
siteInfoService: siteInfoService,
|
||||
eventQueueService: eventQueueService,
|
||||
userService: userService,
|
||||
}
|
||||
}
|
||||
func GetStyle() (script []string, css string) {
|
||||
@@ -271,6 +279,7 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
|
||||
id := ctx.Param("id")
|
||||
title := ctx.Param("title")
|
||||
answerid := ctx.Param("answerid")
|
||||
shareUsername := ctx.Query("share")
|
||||
if checker.IsQuestionsIgnorePath(id) {
|
||||
// if id == "ask" {
|
||||
file, err := ui.Build.ReadFile("build/index.html")
|
||||
@@ -291,6 +300,13 @@ func (tc *TemplateController) QuestionInfo(ctx *gin.Context) {
|
||||
tc.Page404(ctx)
|
||||
return
|
||||
}
|
||||
if len(shareUsername) > 0 {
|
||||
userInfo, err := tc.userService.GetOtherUserInfoByUsername(
|
||||
ctx, &schema.GetOtherUserInfoByUsernameReq{Username: shareUsername})
|
||||
if err == nil {
|
||||
tc.eventQueueService.Send(ctx, schema.NewEvent(constant.EventUserShare, userInfo.ID))
|
||||
}
|
||||
}
|
||||
encodeTitle := htmltext.UrlTitle(detail.Title)
|
||||
if encodeTitle == title {
|
||||
correctTitle = true
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 badge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/base/data"
|
||||
"github.com/apache/incubator-answer/internal/schema"
|
||||
)
|
||||
|
||||
type BadgeEventService struct {
|
||||
data *data.Data
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewBadgeEventService(
|
||||
data *data.Data,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *BadgeEventService {
|
||||
n := &BadgeEventService{
|
||||
data: data,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
eventQueueService.RegisterHandler(n.Handler)
|
||||
return n
|
||||
}
|
||||
|
||||
func (ns *BadgeEventService) Handler(ctx context.Context, msg *schema.EventMsg) error {
|
||||
log.Debugf("received badge event %+v", msg)
|
||||
// TODO: Check if badge already exists
|
||||
|
||||
// TODO: Check rule
|
||||
|
||||
// TODO: Distribute badge
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 badge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"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/service/unique"
|
||||
"github.com/segmentfault/pacman/errors"
|
||||
)
|
||||
|
||||
// BadgeRuleRepo collection repository
|
||||
type BadgeRuleRepo struct {
|
||||
data *data.Data
|
||||
uniqueIDRepo unique.UniqueIDRepo
|
||||
}
|
||||
|
||||
// FilledPersonalProfile filled personal profile
|
||||
func (br *BadgeRuleRepo) FilledPersonalProfile(ctx context.Context, userID string) (reach bool, err error) {
|
||||
bean := &entity.User{ID: userID}
|
||||
exist, err := br.data.DB.Context(ctx).Get(bean)
|
||||
if err != nil {
|
||||
return false, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
|
||||
}
|
||||
if !exist {
|
||||
return false, nil
|
||||
}
|
||||
if len(bean.Bio) > 0 {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// FirstPostEdit first post edit
|
||||
func (br *BadgeRuleRepo) FirstPostEdit(ctx context.Context, userID string, objectID string) {
|
||||
|
||||
}
|
||||
|
||||
// FirstFlaggedPost first flagged post.
|
||||
func (br *BadgeRuleRepo) FirstFlaggedPost(ctx context.Context, userID string, reportID string) {
|
||||
}
|
||||
|
||||
// FirstVotedPost first voted post
|
||||
func (br *BadgeRuleRepo) FirstVotedPost(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// FirstReactedPost first reacted post
|
||||
func (br *BadgeRuleRepo) FirstReactedPost(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// FirstSharedPost first shared post
|
||||
func (br *BadgeRuleRepo) FirstSharedPost(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// AskQuestionAcceptAnswer ask question accept answer
|
||||
func (br *BadgeRuleRepo) AskQuestionAcceptAnswer(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// AnswerAccepted answer accepted
|
||||
func (br *BadgeRuleRepo) AnswerAccepted(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// ReachAnswerScore reach answer score
|
||||
func (br *BadgeRuleRepo) ReachAnswerScore(ctx context.Context) {
|
||||
|
||||
}
|
||||
|
||||
// ReachQuestionScore reach question score
|
||||
func (br *BadgeRuleRepo) ReachQuestionScore(ctx context.Context) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 badge
|
||||
|
||||
import "github.com/apache/incubator-answer/internal/base/constant"
|
||||
|
||||
var (
|
||||
EventRuleMapping = map[constant.EventType][]string{
|
||||
constant.EventUserUpdate: {FilledPersonalProfile},
|
||||
constant.EventUserShare: {FirstSharedPost},
|
||||
constant.EventQuestionCreate: {""},
|
||||
constant.EventQuestionUpdate: {FirstPostEdit},
|
||||
constant.EventQuestionDelete: {""},
|
||||
constant.EventQuestionVote: {FirstVotedPost, ReachQuestionScore},
|
||||
constant.EventQuestionAccept: {AskQuestionAcceptAnswer, AnswerAccepted},
|
||||
constant.EventQuestionFlag: {FirstFlaggedPost},
|
||||
constant.EventQuestionReact: {FirstReactedPost},
|
||||
constant.EventAnswerCreate: {""},
|
||||
constant.EventAnswerUpdate: {FirstPostEdit},
|
||||
constant.EventAnswerDelete: {""},
|
||||
constant.EventAnswerVote: {FirstVotedPost, ReachAnswerScore},
|
||||
constant.EventAnswerFlag: {FirstFlaggedPost},
|
||||
constant.EventAnswerReact: {FirstReactedPost},
|
||||
constant.EventCommentCreate: {""},
|
||||
constant.EventCommentUpdate: {""},
|
||||
constant.EventCommentDelete: {""},
|
||||
constant.EventCommentVote: {FirstVotedPost},
|
||||
constant.EventCommentFlag: {FirstFlaggedPost},
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 badge
|
||||
|
||||
const (
|
||||
// FilledPersonalProfile filled personal profile
|
||||
FilledPersonalProfile = "filled_personal_profile"
|
||||
// FirstPostEdit first post edit
|
||||
FirstPostEdit = "first_post_edit"
|
||||
// FirstFlaggedPost first flagged post.
|
||||
FirstFlaggedPost = "first_flagged_post"
|
||||
// FirstVotedPost first voted post
|
||||
FirstVotedPost = "first_voted_post"
|
||||
// FirstReactedPost first reacted post
|
||||
FirstReactedPost = "first_reacted_post"
|
||||
// FirstSharedPost first shared post
|
||||
FirstSharedPost = "first_shared_post"
|
||||
// AskQuestionAcceptAnswer ask question accept answer
|
||||
AskQuestionAcceptAnswer = "ask_question_accept_answer"
|
||||
// AnswerAccepted answer accepted
|
||||
AnswerAccepted = "answer_accepted"
|
||||
// ReachAnswerScore reach answer score
|
||||
ReachAnswerScore = "reach_answer_score"
|
||||
// ReachQuestionScore reach question score
|
||||
ReachQuestionScore = "reach_question_score"
|
||||
)
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 schema
|
||||
|
||||
import "github.com/apache/incubator-answer/internal/base/constant"
|
||||
|
||||
// EventMsg event message
|
||||
type EventMsg struct {
|
||||
EventType constant.EventType
|
||||
UserID string
|
||||
|
||||
QuestionID string
|
||||
QuestionUserID string
|
||||
|
||||
AnswerID string
|
||||
AnswerUserID string
|
||||
|
||||
CommentID string
|
||||
CommentUserID string
|
||||
|
||||
ExtraInfo map[string]string
|
||||
}
|
||||
|
||||
func NewEvent(e constant.EventType, userID string) *EventMsg {
|
||||
return &EventMsg{
|
||||
UserID: userID,
|
||||
EventType: e,
|
||||
ExtraInfo: make(map[string]string),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EventMsg) QID(questionID, userID string) *EventMsg {
|
||||
e.QuestionID = questionID
|
||||
e.QuestionUserID = userID
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *EventMsg) AID(answerID, userID string) *EventMsg {
|
||||
e.AnswerID = answerID
|
||||
e.AnswerUserID = userID
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *EventMsg) CID(comment, userID string) *EventMsg {
|
||||
e.CommentID = comment
|
||||
e.CommentUserID = userID
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *EventMsg) AddExtra(key, value string) *EventMsg {
|
||||
e.ExtraInfo[key] = value
|
||||
return e
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"time"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/base/constant"
|
||||
@@ -86,6 +87,7 @@ type CommentService struct {
|
||||
notificationQueueService notice_queue.NotificationQueueService
|
||||
externalNotificationQueueService notice_queue.ExternalNotificationQueueService
|
||||
activityQueueService activity_queue.ActivityQueueService
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
// NewCommentService new comment service
|
||||
@@ -100,6 +102,7 @@ func NewCommentService(
|
||||
notificationQueueService notice_queue.NotificationQueueService,
|
||||
externalNotificationQueueService notice_queue.ExternalNotificationQueueService,
|
||||
activityQueueService activity_queue.ActivityQueueService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *CommentService {
|
||||
return &CommentService{
|
||||
commentRepo: commentRepo,
|
||||
@@ -112,6 +115,7 @@ func NewCommentService(
|
||||
notificationQueueService: notificationQueueService,
|
||||
externalNotificationQueueService: externalNotificationQueueService,
|
||||
activityQueueService: activityQueueService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,13 +188,19 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment
|
||||
OriginalObjectID: req.ObjectID,
|
||||
ActivityTypeKey: constant.ActQuestionCommented,
|
||||
}
|
||||
var event *schema.EventMsg
|
||||
switch objInfo.ObjectType {
|
||||
case constant.QuestionObjectType:
|
||||
activityMsg.ActivityTypeKey = constant.ActQuestionCommented
|
||||
event = schema.NewEvent(constant.EventCommentCreate, req.UserID).
|
||||
CID(comment.ID, comment.UserID).QID(objInfo.QuestionID, objInfo.ObjectCreatorUserID)
|
||||
case constant.AnswerObjectType:
|
||||
activityMsg.ActivityTypeKey = constant.ActAnswerCommented
|
||||
event = schema.NewEvent(constant.EventCommentCreate, req.UserID).
|
||||
CID(comment.ID, comment.UserID).AID(objInfo.AnswerID, objInfo.ObjectCreatorUserID)
|
||||
}
|
||||
cs.activityQueueService.Send(ctx, activityMsg)
|
||||
cs.eventQueueService.Send(ctx, event)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -241,7 +251,12 @@ func (cs *CommentService) addCommentNotification(
|
||||
|
||||
// RemoveComment delete comment
|
||||
func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveCommentReq) (err error) {
|
||||
return cs.commentRepo.RemoveComment(ctx, req.CommentID)
|
||||
err = cs.commentRepo.RemoveComment(ctx, req.CommentID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventCommentDelete, req.UserID).CID(req.CommentID, req.UserID))
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateComment update comment
|
||||
@@ -273,6 +288,8 @@ func (cs *CommentService) UpdateComment(ctx context.Context, req *schema.UpdateC
|
||||
OriginalText: req.OriginalText,
|
||||
ParsedText: req.ParsedText,
|
||||
}
|
||||
cs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventCommentUpdate, req.UserID).
|
||||
CID(old.ID, old.UserID))
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ package content
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"time"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/base/constant"
|
||||
@@ -67,6 +68,7 @@ type AnswerService struct {
|
||||
externalNotificationQueueService notice_queue.ExternalNotificationQueueService
|
||||
activityQueueService activity_queue.ActivityQueueService
|
||||
reviewService *review.ReviewService
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewAnswerService(
|
||||
@@ -86,6 +88,7 @@ func NewAnswerService(
|
||||
externalNotificationQueueService notice_queue.ExternalNotificationQueueService,
|
||||
activityQueueService activity_queue.ActivityQueueService,
|
||||
reviewService *review.ReviewService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *AnswerService {
|
||||
return &AnswerService{
|
||||
answerRepo: answerRepo,
|
||||
@@ -104,6 +107,7 @@ func NewAnswerService(
|
||||
externalNotificationQueueService: externalNotificationQueueService,
|
||||
activityQueueService: activityQueueService,
|
||||
reviewService: reviewService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +179,8 @@ func (as *AnswerService) RemoveAnswer(ctx context.Context, req *schema.RemoveAns
|
||||
OriginalObjectID: answerInfo.ID,
|
||||
ActivityTypeKey: constant.ActAnswerDeleted,
|
||||
})
|
||||
as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventAnswerDelete, req.UserID).
|
||||
AID(answerInfo.ID, answerInfo.UserID))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -295,6 +301,8 @@ func (as *AnswerService) Insert(ctx context.Context, req *schema.AnswerAddReq) (
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionAnswered,
|
||||
})
|
||||
as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventAnswerCreate, req.UserID).
|
||||
AID(insertData.ID, insertData.UserID))
|
||||
return insertData.ID, nil
|
||||
}
|
||||
|
||||
@@ -383,6 +391,8 @@ func (as *AnswerService) Update(ctx context.Context, req *schema.AnswerUpdateReq
|
||||
ActivityTypeKey: constant.ActAnswerEdited,
|
||||
RevisionID: revisionID,
|
||||
})
|
||||
as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventAnswerUpdate, req.UserID).
|
||||
AID(insertData.ID, insertData.UserID))
|
||||
}
|
||||
|
||||
return insertData.ID, nil
|
||||
@@ -436,6 +446,9 @@ func (as *AnswerService) AcceptAnswer(ctx context.Context, req *schema.AcceptAns
|
||||
oldAnswerInfo.ID = uid.DeShortID(oldAnswerInfo.ID)
|
||||
}
|
||||
|
||||
as.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionAccept, req.UserID).
|
||||
QID(questionInfo.ID, questionInfo.UserID).AID(req.AnswerID, req.UserID))
|
||||
|
||||
as.updateAnswerRank(ctx, req.UserID, questionInfo, acceptedAnswerInfo, oldAnswerInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
answercommon "github.com/apache/incubator-answer/internal/service/answer_common"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -84,6 +85,7 @@ type QuestionService struct {
|
||||
newQuestionNotificationService *notification.ExternalNotificationService
|
||||
reviewService *review.ReviewService
|
||||
configService *config.ConfigService
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewQuestionService(
|
||||
@@ -106,6 +108,7 @@ func NewQuestionService(
|
||||
newQuestionNotificationService *notification.ExternalNotificationService,
|
||||
reviewService *review.ReviewService,
|
||||
configService *config.ConfigService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *QuestionService {
|
||||
return &QuestionService{
|
||||
questionRepo: questionRepo,
|
||||
@@ -127,6 +130,7 @@ func NewQuestionService(
|
||||
newQuestionNotificationService: newQuestionNotificationService,
|
||||
reviewService: reviewService,
|
||||
configService: configService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,6 +389,8 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
|
||||
qs.externalNotificationQueueService.Send(ctx,
|
||||
schema.CreateNewQuestionNotificationMsg(question.ID, question.Title, question.UserID, tags))
|
||||
}
|
||||
qs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionCreate, req.UserID).
|
||||
QID(question.ID, question.UserID))
|
||||
|
||||
questionInfo, err = qs.GetQuestion(ctx, question.ID, question.UserID, req.QuestionPermission)
|
||||
return
|
||||
@@ -546,6 +552,8 @@ func (qs *QuestionService) RemoveQuestion(ctx context.Context, req *schema.Remov
|
||||
OriginalObjectID: questionInfo.ID,
|
||||
ActivityTypeKey: constant.ActQuestionDeleted,
|
||||
})
|
||||
qs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionDelete, req.UserID).
|
||||
QID(questionInfo.ID, questionInfo.UserID))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -937,6 +945,8 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
|
||||
RevisionID: revisionID,
|
||||
OriginalObjectID: question.ID,
|
||||
})
|
||||
qs.eventQueueService.Send(ctx, schema.NewEvent(constant.EventQuestionUpdate, req.UserID).
|
||||
QID(question.ID, question.UserID))
|
||||
}
|
||||
|
||||
questionInfo, err = qs.GetQuestion(ctx, question.ID, question.UserID, req.QuestionPermission)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"time"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/base/constant"
|
||||
@@ -65,6 +66,7 @@ type UserService struct {
|
||||
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo
|
||||
userNotificationConfigService *user_notification_config.UserNotificationConfigService
|
||||
questionService *questioncommon.QuestionCommon
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewUserService(userRepo usercommon.UserRepo,
|
||||
@@ -79,6 +81,7 @@ func NewUserService(userRepo usercommon.UserRepo,
|
||||
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo,
|
||||
userNotificationConfigService *user_notification_config.UserNotificationConfigService,
|
||||
questionService *questioncommon.QuestionCommon,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *UserService {
|
||||
return &UserService{
|
||||
userCommonService: userCommonService,
|
||||
@@ -93,6 +96,7 @@ func NewUserService(userRepo usercommon.UserRepo,
|
||||
userNotificationConfigRepo: userNotificationConfigRepo,
|
||||
userNotificationConfigService: userNotificationConfigService,
|
||||
questionService: questionService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,6 +356,10 @@ func (us *UserService) UpdateInfo(ctx context.Context, req *schema.UpdateInfoReq
|
||||
|
||||
cond := us.formatUserInfoForUpdateInfo(oldUserInfo, req, siteUsers)
|
||||
err = us.userRepo.UpdateInfo(ctx, cond)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
us.eventQueueService.Send(ctx, schema.NewEvent(constant.EventUserUpdate, req.UserID))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ package content
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"strings"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/service/activity_common"
|
||||
@@ -62,6 +64,7 @@ type VoteService struct {
|
||||
commentCommonRepo comment_common.CommentCommonRepo
|
||||
objectService *object_info.ObjService
|
||||
activityRepo activity_common.ActivityRepo
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewVoteService(
|
||||
@@ -71,6 +74,7 @@ func NewVoteService(
|
||||
answerRepo answercommon.AnswerRepo,
|
||||
commentCommonRepo comment_common.CommentCommonRepo,
|
||||
objectService *object_info.ObjService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *VoteService {
|
||||
return &VoteService{
|
||||
voteRepo: voteRepo,
|
||||
@@ -79,6 +83,7 @@ func NewVoteService(
|
||||
answerRepo: answerRepo,
|
||||
commentCommonRepo: commentCommonRepo,
|
||||
objectService: objectService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +117,9 @@ func (vs *VoteService) VoteUp(ctx context.Context, req *schema.VoteReq) (resp *s
|
||||
return nil, err
|
||||
}
|
||||
err = vs.voteRepo.Vote(ctx, voteUpOperationInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -125,6 +133,7 @@ func (vs *VoteService) VoteUp(ctx context.Context, req *schema.VoteReq) (resp *s
|
||||
resp.Votes = resp.UpVotes - resp.DownVotes
|
||||
if !req.IsCancel {
|
||||
resp.VoteStatus = constant.ActVoteUp
|
||||
vs.sendEvent(ctx, req, objectInfo, resp)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -173,6 +182,7 @@ func (vs *VoteService) VoteDown(ctx context.Context, req *schema.VoteReq) (resp
|
||||
resp.Votes = resp.UpVotes - resp.DownVotes
|
||||
if !req.IsCancel {
|
||||
resp.VoteStatus = constant.ActVoteDown
|
||||
vs.sendEvent(ctx, req, objectInfo, resp)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -289,3 +299,24 @@ func (vs *VoteService) getActivities(ctx context.Context, op *schema.VoteOperati
|
||||
}
|
||||
return activities
|
||||
}
|
||||
|
||||
func (vs *VoteService) sendEvent(ctx context.Context,
|
||||
req *schema.VoteReq, objectInfo *schema.SimpleObjectInfo, resp *schema.VoteResp) {
|
||||
var event *schema.EventMsg
|
||||
switch objectInfo.ObjectType {
|
||||
case constant.QuestionObjectType:
|
||||
event = schema.NewEvent(constant.EventQuestionVote, req.UserID).
|
||||
QID(objectInfo.QuestionID, objectInfo.ObjectCreatorUserID)
|
||||
case constant.AnswerObjectType:
|
||||
event = schema.NewEvent(constant.EventAnswerVote, req.UserID).
|
||||
AID(objectInfo.AnswerID, objectInfo.ObjectCreatorUserID)
|
||||
case constant.CommentObjectType:
|
||||
event = schema.NewEvent(constant.EventCommentVote, req.UserID).
|
||||
CID(objectInfo.CommentID, objectInfo.ObjectCreatorUserID)
|
||||
default:
|
||||
return
|
||||
}
|
||||
event.AddExtra("vote_up_amount", fmt.Sprintf("%d", resp.UpVotes))
|
||||
event.AddExtra("vote_down_amount", fmt.Sprintf("%d", resp.DownVotes))
|
||||
vs.eventQueueService.Send(ctx, event)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 event_queue
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/schema"
|
||||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
type EventQueueService interface {
|
||||
Send(ctx context.Context, msg *schema.EventMsg)
|
||||
RegisterHandler(handler func(ctx context.Context, msg *schema.EventMsg) error)
|
||||
}
|
||||
|
||||
type eventQueueService struct {
|
||||
Queue chan *schema.EventMsg
|
||||
Handler func(ctx context.Context, msg *schema.EventMsg) error
|
||||
}
|
||||
|
||||
func (ns *eventQueueService) Send(ctx context.Context, msg *schema.EventMsg) {
|
||||
ns.Queue <- msg
|
||||
}
|
||||
|
||||
func (ns *eventQueueService) RegisterHandler(
|
||||
handler func(ctx context.Context, msg *schema.EventMsg) error) {
|
||||
ns.Handler = handler
|
||||
}
|
||||
|
||||
func (ns *eventQueueService) working() {
|
||||
go func() {
|
||||
for msg := range ns.Queue {
|
||||
log.Debugf("received badge %+v", msg)
|
||||
if ns.Handler == nil {
|
||||
log.Warnf("no handler for badge")
|
||||
continue
|
||||
}
|
||||
if err := ns.Handler(context.Background(), msg); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// NewEventQueueService create a new badge queue service
|
||||
func NewEventQueueService() EventQueueService {
|
||||
ns := &eventQueueService{}
|
||||
ns.Queue = make(chan *schema.EventMsg, 128)
|
||||
ns.working()
|
||||
return ns
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -46,14 +47,22 @@ type MetaService struct {
|
||||
userCommon *usercommon.UserCommon
|
||||
questionRepo questioncommon.QuestionRepo
|
||||
answerRepo answercommon.AnswerRepo
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
func NewMetaService(metaCommonService *metacommon.MetaCommonService, userCommon *usercommon.UserCommon, answerRepo answercommon.AnswerRepo, questionRepo questioncommon.QuestionRepo) *MetaService {
|
||||
func NewMetaService(
|
||||
metaCommonService *metacommon.MetaCommonService,
|
||||
userCommon *usercommon.UserCommon,
|
||||
answerRepo answercommon.AnswerRepo,
|
||||
questionRepo questioncommon.QuestionRepo,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *MetaService {
|
||||
return &MetaService{
|
||||
metaCommonService: metaCommonService,
|
||||
questionRepo: questionRepo,
|
||||
userCommon: userCommon,
|
||||
answerRepo: answerRepo,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,22 +95,27 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var event *schema.EventMsg
|
||||
if objectType == constant.AnswerObjectType {
|
||||
_, exist, err := ms.answerRepo.GetAnswer(ctx, req.ObjectID)
|
||||
answerInfo, exist, err := ms.answerRepo.GetAnswer(ctx, req.ObjectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return nil, myErrors.BadRequest(reason.AnswerNotFound)
|
||||
}
|
||||
event = schema.NewEvent(constant.EventAnswerReact, req.UserID).
|
||||
AID(answerInfo.ID, answerInfo.UserID)
|
||||
} else if objectType == constant.QuestionObjectType {
|
||||
_, exist, err := ms.questionRepo.GetQuestion(ctx, req.ObjectID)
|
||||
questionInfo, exist, err := ms.questionRepo.GetQuestion(ctx, req.ObjectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exist {
|
||||
return nil, myErrors.BadRequest(reason.QuestionNotFound)
|
||||
}
|
||||
event = schema.NewEvent(constant.EventQuestionReact, req.UserID).
|
||||
QID(questionInfo.ID, questionInfo.UserID)
|
||||
} else {
|
||||
return nil, myErrors.BadRequest(reason.ObjectNotFound)
|
||||
}
|
||||
@@ -138,7 +152,7 @@ func (ms *MetaService) AddOrUpdateReaction(ctx context.Context, req *schema.Upda
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ms.eventQueueService.Send(ctx, event)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/apache/incubator-answer/internal/service/config"
|
||||
"github.com/apache/incubator-answer/internal/service/content"
|
||||
"github.com/apache/incubator-answer/internal/service/dashboard"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
"github.com/apache/incubator-answer/internal/service/export"
|
||||
"github.com/apache/incubator-answer/internal/service/follow"
|
||||
"github.com/apache/incubator-answer/internal/service/meta"
|
||||
@@ -117,4 +118,5 @@ var ProviderSetService = wire.NewSet(
|
||||
notice_queue.NewNewQuestionNotificationQueueService,
|
||||
review.NewReviewService,
|
||||
meta.NewMetaService,
|
||||
event_queue.NewEventQueueService,
|
||||
)
|
||||
|
||||
@@ -21,6 +21,7 @@ package report
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/apache/incubator-answer/internal/service/event_queue"
|
||||
|
||||
"github.com/apache/incubator-answer/internal/base/constant"
|
||||
"github.com/apache/incubator-answer/internal/base/handler"
|
||||
@@ -55,6 +56,7 @@ type ReportService struct {
|
||||
commentCommonRepo comment_common.CommentCommonRepo
|
||||
reportHandle *report_handle.ReportHandle
|
||||
configService *config.ConfigService
|
||||
eventQueueService event_queue.EventQueueService
|
||||
}
|
||||
|
||||
// NewReportService new report service
|
||||
@@ -67,6 +69,7 @@ func NewReportService(
|
||||
commentCommonRepo comment_common.CommentCommonRepo,
|
||||
reportHandle *report_handle.ReportHandle,
|
||||
configService *config.ConfigService,
|
||||
eventQueueService event_queue.EventQueueService,
|
||||
) *ReportService {
|
||||
return &ReportService{
|
||||
reportRepo: reportRepo,
|
||||
@@ -77,6 +80,7 @@ func NewReportService(
|
||||
commentCommonRepo: commentCommonRepo,
|
||||
reportHandle: reportHandle,
|
||||
configService: configService,
|
||||
eventQueueService: eventQueueService,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +116,12 @@ func (rs *ReportService) AddReport(ctx context.Context, req *schema.AddReportReq
|
||||
Content: req.Content,
|
||||
Status: entity.ReportStatusPending,
|
||||
}
|
||||
return rs.reportRepo.AddReport(ctx, report)
|
||||
err = rs.reportRepo.AddReport(ctx, report)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rs.sendEvent(ctx, report, objInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUnreviewedReportPostPage get unreviewed report post page
|
||||
@@ -218,3 +227,22 @@ func (rs *ReportService) ReviewReport(ctx context.Context, req *schema.ReviewRep
|
||||
|
||||
return rs.reportRepo.UpdateStatus(ctx, report.ID, entity.ReportStatusCompleted)
|
||||
}
|
||||
|
||||
func (rs *ReportService) sendEvent(ctx context.Context,
|
||||
report *entity.Report, objectInfo *schema.SimpleObjectInfo) {
|
||||
var event *schema.EventMsg
|
||||
switch objectInfo.ObjectType {
|
||||
case constant.QuestionObjectType:
|
||||
event = schema.NewEvent(constant.EventQuestionFlag, report.UserID).
|
||||
QID(objectInfo.QuestionID, objectInfo.ObjectCreatorUserID)
|
||||
case constant.AnswerObjectType:
|
||||
event = schema.NewEvent(constant.EventAnswerFlag, report.UserID).
|
||||
AID(objectInfo.AnswerID, objectInfo.ObjectCreatorUserID)
|
||||
case constant.CommentObjectType:
|
||||
event = schema.NewEvent(constant.EventCommentFlag, report.UserID).
|
||||
CID(objectInfo.CommentID, objectInfo.ObjectCreatorUserID)
|
||||
default:
|
||||
return
|
||||
}
|
||||
rs.eventQueueService.Send(ctx, event)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user