mirror of https://gitee.com/answerdev/answer.git
feat(notification): add upvote and down vote notification
This commit is contained in:
parent
3952439d49
commit
c56d54b0fe
|
@ -5,14 +5,24 @@ const (
|
|||
UpdateQuestion = "notification.action.update_question"
|
||||
// AnswerTheQuestion answer the question
|
||||
AnswerTheQuestion = "notification.action.answer_the_question"
|
||||
// UpVotedTheQuestion up voted the question
|
||||
UpVotedTheQuestion = "notification.action.up_voted_question"
|
||||
// DownVotedTheQuestion down voted the question
|
||||
DownVotedTheQuestion = "notification.action.down_voted_question"
|
||||
// UpdateAnswer update answer
|
||||
UpdateAnswer = "notification.action.update_answer"
|
||||
// AcceptAnswer accept answer
|
||||
AcceptAnswer = "notification.action.accept_answer"
|
||||
// UpVotedTheAnswer up voted the answer
|
||||
UpVotedTheAnswer = "notification.action.up_voted_answer"
|
||||
// DownVotedTheAnswer down voted the answer
|
||||
DownVotedTheAnswer = "notification.action.down_voted_answer"
|
||||
// CommentQuestion comment question
|
||||
CommentQuestion = "notification.action.comment_question"
|
||||
// CommentAnswer comment answer
|
||||
CommentAnswer = "notification.action.comment_answer"
|
||||
// UpVotedTheComment up voted the comment
|
||||
UpVotedTheComment = "notification.action.up_voted_comment"
|
||||
// ReplyToYou reply to you
|
||||
ReplyToYou = "notification.action.reply_to_you"
|
||||
// MentionYou mention you
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/constant"
|
||||
"github.com/answerdev/answer/pkg/converter"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/pager"
|
||||
|
@ -70,7 +71,9 @@ var LimitDownActions = map[string][]string{
|
|||
|
||||
func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUserID string, actions []string) (resp *schema.VoteResp, err error) {
|
||||
resp = &schema.VoteResp{}
|
||||
notificationUserIDs := make([]string, 0)
|
||||
achievementNotificationUserIDs := make([]string, 0)
|
||||
sendInboxNotification := false
|
||||
upVote := false
|
||||
_, err = vr.data.DB.Transaction(func(session *xorm.Session) (result any, err error) {
|
||||
result = nil
|
||||
for _, action := range actions {
|
||||
|
@ -127,7 +130,7 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
if isReachStandard {
|
||||
insertActivity.Rank = 0
|
||||
}
|
||||
notificationUserIDs = append(notificationUserIDs, activityUserID)
|
||||
achievementNotificationUserIDs = append(achievementNotificationUserIDs, activityUserID)
|
||||
}
|
||||
|
||||
if has {
|
||||
|
@ -142,13 +145,17 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sendInboxNotification = true
|
||||
}
|
||||
|
||||
// update votes
|
||||
if action == "vote_down" || action == "vote_up" {
|
||||
if action == constant.ActVoteDown || action == constant.ActVoteUp {
|
||||
votes := 1
|
||||
if action == "vote_down" {
|
||||
if action == constant.ActVoteDown {
|
||||
upVote = false
|
||||
votes = -1
|
||||
} else {
|
||||
upVote = true
|
||||
}
|
||||
err = vr.updateVotes(ctx, session, objectID, votes)
|
||||
if err != nil {
|
||||
|
@ -165,9 +172,12 @@ func (vr *VoteRepo) vote(ctx context.Context, objectID string, userID, objectUse
|
|||
resp, err = vr.GetVoteResultByObjectId(ctx, objectID)
|
||||
resp.VoteStatus = vr.voteCommon.GetVoteStatus(ctx, objectID, userID)
|
||||
|
||||
for _, activityUserID := range notificationUserIDs {
|
||||
for _, activityUserID := range achievementNotificationUserIDs {
|
||||
vr.sendNotification(ctx, activityUserID, objectUserID, objectID)
|
||||
}
|
||||
if sendInboxNotification {
|
||||
vr.sendVoteInboxNotification(userID, objectUserID, objectID, upVote)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -441,3 +451,40 @@ func (vr *VoteRepo) sendNotification(ctx context.Context, activityUserID, object
|
|||
}
|
||||
notice_queue.AddNotification(msg)
|
||||
}
|
||||
|
||||
func (vr *VoteRepo) sendVoteInboxNotification(triggerUserID, receiverUserID, objectID string, upvote bool) {
|
||||
if triggerUserID == receiverUserID {
|
||||
return
|
||||
}
|
||||
objectType, _ := obj.GetObjectTypeStrByObjectID(objectID)
|
||||
|
||||
msg := &schema.NotificationMsg{
|
||||
TriggerUserID: triggerUserID,
|
||||
ReceiverUserID: receiverUserID,
|
||||
Type: schema.NotificationTypeInbox,
|
||||
ObjectID: objectID,
|
||||
ObjectType: objectType,
|
||||
}
|
||||
if objectType == constant.QuestionObjectType {
|
||||
if upvote {
|
||||
msg.NotificationAction = constant.UpVotedTheQuestion
|
||||
} else {
|
||||
msg.NotificationAction = constant.DownVotedTheQuestion
|
||||
}
|
||||
}
|
||||
if objectType == constant.AnswerObjectType {
|
||||
if upvote {
|
||||
msg.NotificationAction = constant.UpVotedTheAnswer
|
||||
} else {
|
||||
msg.NotificationAction = constant.DownVotedTheAnswer
|
||||
}
|
||||
}
|
||||
if objectType == constant.CommentObjectType {
|
||||
if upvote {
|
||||
msg.NotificationAction = constant.UpVotedTheComment
|
||||
}
|
||||
}
|
||||
if len(msg.NotificationAction) > 0 {
|
||||
notice_queue.AddNotification(msg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,9 +63,23 @@ func (g *GetPluginConfigResp) SetConfigFields(ctx *gin.Context, fields []plugin.
|
|||
configField.UIOptions.Label = field.UIOptions.Label.Translate(ctx)
|
||||
configField.UIOptions.Text = field.UIOptions.Text.Translate(ctx)
|
||||
if field.UIOptions.Action != nil {
|
||||
configField.UIOptions.Action = &ConfigFieldUIOptionAction{
|
||||
Url: field.UIOptions.Action.Url,
|
||||
uiOptionAction := &UIOptionAction{
|
||||
Url: field.UIOptions.Action.Url,
|
||||
Method: field.UIOptions.Action.Method,
|
||||
}
|
||||
if field.UIOptions.Action.Loading != nil {
|
||||
uiOptionAction.Loading = &LoadingAction{
|
||||
Text: field.UIOptions.Action.Loading.Text.Translate(ctx),
|
||||
State: string(field.UIOptions.Action.Loading.State),
|
||||
}
|
||||
}
|
||||
if field.UIOptions.Action.OnComplete != nil {
|
||||
uiOptionAction.OnCompleteAction = &OnCompleteAction{
|
||||
ToastReturnMessage: field.UIOptions.Action.OnComplete.ToastReturnMessage,
|
||||
RefreshFormConfig: field.UIOptions.Action.OnComplete.RefreshFormConfig,
|
||||
}
|
||||
}
|
||||
configField.UIOptions.Action = uiOptionAction
|
||||
}
|
||||
|
||||
for _, option := range field.Options {
|
||||
|
@ -90,13 +104,13 @@ type ConfigField struct {
|
|||
}
|
||||
|
||||
type ConfigFieldUIOptions struct {
|
||||
Placeholder string `json:"placeholder,omitempty"`
|
||||
Rows string `json:"rows,omitempty"`
|
||||
InputType string `json:"input_type,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Action *ConfigFieldUIOptionAction `json:"action,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Placeholder string `json:"placeholder,omitempty"`
|
||||
Rows string `json:"rows,omitempty"`
|
||||
InputType string `json:"input_type,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Action *UIOptionAction `json:"action,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
type ConfigFieldOption struct {
|
||||
|
@ -104,8 +118,21 @@ type ConfigFieldOption struct {
|
|||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ConfigFieldUIOptionAction struct {
|
||||
Url string `json:"url"`
|
||||
type UIOptionAction struct {
|
||||
Url string `json:"url"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Loading *LoadingAction `json:"loading,omitempty"`
|
||||
OnCompleteAction *OnCompleteAction `json:"on_complete,omitempty"`
|
||||
}
|
||||
|
||||
type LoadingAction struct {
|
||||
Text string `json:"text"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type OnCompleteAction struct {
|
||||
ToastReturnMessage bool `json:"toast_return_message"`
|
||||
RefreshFormConfig bool `json:"refresh_form_config"`
|
||||
}
|
||||
|
||||
type UpdatePluginConfigReq struct {
|
||||
|
|
|
@ -63,12 +63,12 @@ func NewVoteService(
|
|||
}
|
||||
|
||||
// VoteUp vote up
|
||||
func (as *VoteService) VoteUp(ctx context.Context, dto *schema.VoteDTO) (voteResp *schema.VoteResp, err error) {
|
||||
func (vs *VoteService) VoteUp(ctx context.Context, dto *schema.VoteDTO) (voteResp *schema.VoteResp, err error) {
|
||||
voteResp = &schema.VoteResp{}
|
||||
|
||||
var objectUserID string
|
||||
|
||||
objectUserID, err = as.GetObjectUserID(ctx, dto.ObjectID)
|
||||
objectUserID, err = vs.GetObjectUserID(ctx, dto.ObjectID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -80,19 +80,19 @@ func (as *VoteService) VoteUp(ctx context.Context, dto *schema.VoteDTO) (voteRes
|
|||
}
|
||||
|
||||
if dto.IsCancel {
|
||||
return as.voteRepo.VoteUpCancel(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
return vs.voteRepo.VoteUpCancel(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
} else {
|
||||
return as.voteRepo.VoteUp(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
return vs.voteRepo.VoteUp(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
}
|
||||
}
|
||||
|
||||
// VoteDown vote down
|
||||
func (as *VoteService) VoteDown(ctx context.Context, dto *schema.VoteDTO) (voteResp *schema.VoteResp, err error) {
|
||||
func (vs *VoteService) VoteDown(ctx context.Context, dto *schema.VoteDTO) (voteResp *schema.VoteResp, err error) {
|
||||
voteResp = &schema.VoteResp{}
|
||||
|
||||
var objectUserID string
|
||||
|
||||
objectUserID, err = as.GetObjectUserID(ctx, dto.ObjectID)
|
||||
objectUserID, err = vs.GetObjectUserID(ctx, dto.ObjectID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ func (as *VoteService) VoteDown(ctx context.Context, dto *schema.VoteDTO) (voteR
|
|||
}
|
||||
|
||||
if dto.IsCancel {
|
||||
return as.voteRepo.VoteDownCancel(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
return vs.voteRepo.VoteDownCancel(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
} else {
|
||||
return as.voteRepo.VoteDown(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
return vs.voteRepo.VoteDown(ctx, dto.ObjectID, dto.UserID, objectUserID)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,13 @@ type ConfigField struct {
|
|||
}
|
||||
|
||||
type ConfigFieldUIOptions struct {
|
||||
Placeholder Translator `json:"placeholder,omitempty"`
|
||||
Rows string `json:"rows,omitempty"`
|
||||
InputType InputType `json:"input_type,omitempty"`
|
||||
Label Translator `json:"label,omitempty"`
|
||||
Action *ConfigFieldUIOptionAction `json:"action,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
Text Translator `json:"text,omitempty"`
|
||||
Placeholder Translator `json:"placeholder,omitempty"`
|
||||
Rows string `json:"rows,omitempty"`
|
||||
InputType InputType `json:"input_type,omitempty"`
|
||||
Label Translator `json:"label,omitempty"`
|
||||
Action *UIOptionAction `json:"action,omitempty"`
|
||||
Variant string `json:"variant,omitempty"`
|
||||
Text Translator `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
type ConfigFieldOption struct {
|
||||
|
@ -58,8 +58,29 @@ type ConfigFieldOption struct {
|
|||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type ConfigFieldUIOptionAction struct {
|
||||
Url string `json:"url"`
|
||||
type UIOptionAction struct {
|
||||
Url string `json:"url"`
|
||||
Method string `json:"method,omitempty"`
|
||||
Loading *LoadingAction `json:"loading,omitempty"`
|
||||
OnComplete *OnCompleteAction `json:"on_complete,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
LoadingActionStateNone LoadingActionType = "none"
|
||||
LoadingActionStatePending LoadingActionType = "pending"
|
||||
LoadingActionStateComplete LoadingActionType = "completed"
|
||||
)
|
||||
|
||||
type LoadingActionType string
|
||||
|
||||
type LoadingAction struct {
|
||||
Text Translator `json:"text"`
|
||||
State LoadingActionType `json:"state"`
|
||||
}
|
||||
|
||||
type OnCompleteAction struct {
|
||||
ToastReturnMessage bool `json:"toast_return_message"`
|
||||
RefreshFormConfig bool `json:"refresh_form_config"`
|
||||
}
|
||||
|
||||
type Config interface {
|
||||
|
|
Loading…
Reference in New Issue