feat(notification): add notification limit

This commit is contained in:
LinkinStars 2023-08-22 17:07:45 +08:00
parent 8a037f00db
commit e4a77367a4
15 changed files with 93 additions and 50 deletions

View File

@ -178,7 +178,7 @@ func initApplication(debug bool, serverConf *conf.Server, dbConf *data.Database,
collectionController := controller.NewCollectionController(collectionService) collectionController := controller.NewCollectionController(collectionService)
answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService) answerActivityRepo := activity.NewAnswerActivityRepo(dataData, activityRepo, userRankRepo, notificationQueueService)
answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService) answerActivityService := activity2.NewAnswerActivityService(answerActivityRepo, configService)
externalNotificationService := notification.NewExternalNotificationService(userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService) externalNotificationService := notification.NewExternalNotificationService(dataData, userNotificationConfigRepo, followRepo, emailService, userRepo, externalNotificationQueueService)
questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, revisionService, metaService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService) questionService := service.NewQuestionService(questionRepo, tagCommonService, questionCommon, userCommon, userRepo, revisionService, metaService, collectionCommon, answerActivityService, emailService, notificationQueueService, externalNotificationQueueService, activityQueueService, siteInfoCommonService, externalNotificationService)
answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService) answerService := service.NewAnswerService(answerRepo, questionRepo, questionCommon, userCommon, collectionCommon, userRepo, revisionService, answerActivityService, answerCommon, voteRepo, emailService, userRoleRelService, notificationQueueService, externalNotificationQueueService, activityQueueService)
questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService, captchaService) questionController := controller.NewQuestionController(questionService, answerService, rankService, siteInfoCommonService, captchaService)

4
go.mod
View File

@ -29,8 +29,8 @@ require (
github.com/ory/dockertest/v3 v3.9.1 github.com/ory/dockertest/v3 v3.9.1
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405 github.com/scottleedavis/go-exif-remove v0.0.0-20230314195146-7e059d593405
github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700 github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700 github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05 github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230516093754-b76aef1c1150 github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230516093754-b76aef1c1150
github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05 github.com/segmentfault/pacman/contrib/log/zap v0.0.0-20221018072427-a15dd1434e05

6
go.sum
View File

@ -89,6 +89,7 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@ -644,8 +645,12 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700 h1:VqxiuNGQg86GEKxnzmJegZR2Ufr7EVXo68mdKaf+/MQ= github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700 h1:VqxiuNGQg86GEKxnzmJegZR2Ufr7EVXo68mdKaf+/MQ=
github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs= github.com/segmentfault/pacman v1.0.5-0.20230822075009-309985fb8700/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f h1:9f2Bjf6bdMvNyUop32wAGJCdp+Jdm/d6nKBYvFvkRo0=
github.com/segmentfault/pacman v1.0.5-0.20230822083413-c0075a2d401f/go.mod h1:5lNp5REd8QMThmBUvR3Fi9Y3AsOB4GRq7soCB4QLqOs=
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700 h1:VZpexPTcr7sOxxYUGa/9cneyCESfisAhCNbaEuTpcwI= github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700 h1:VZpexPTcr7sOxxYUGa/9cneyCESfisAhCNbaEuTpcwI=
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs= github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822075009-309985fb8700/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f h1:1KHe0uN6p798E7XJZPhZkgm/hXk5CTjisCvFMqaZSKI=
github.com/segmentfault/pacman/contrib/cache/memory v0.0.0-20230822083413-c0075a2d401f/go.mod h1:rmf1TCwz67dyM+AmTwSd1BxTo2AOYHj262lP93bOZbs=
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05 h1:BlqTgc3/MYKG6vMI2MI+6o+7P4Gy5PXlawu185wPXAk= github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05 h1:BlqTgc3/MYKG6vMI2MI+6o+7P4Gy5PXlawu185wPXAk=
github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05/go.mod h1:prPjFam7MyZ5b3S9dcDOt2tMPz6kf7C9c243s9zSwPY= github.com/segmentfault/pacman/contrib/conf/viper v0.0.0-20221018072427-a15dd1434e05/go.mod h1:prPjFam7MyZ5b3S9dcDOt2tMPz6kf7C9c243s9zSwPY=
github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230516093754-b76aef1c1150 h1:OEuW1D7RGDE0CZDr0oGMw9Eiq7fAbD9C4WMrvSixamk= github.com/segmentfault/pacman/contrib/i18n v0.0.0-20230516093754-b76aef1c1150 h1:OEuW1D7RGDE0CZDr0oGMw9Eiq7fAbD9C4WMrvSixamk=
@ -774,6 +779,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=

View File

@ -3,20 +3,23 @@ package constant
import "time" import "time"
const ( const (
UserStatusChangedCacheKey = "answer:user:status:" UserStatusChangedCacheKey = "answer:user:status:"
UserStatusChangedCacheTime = 7 * 24 * time.Hour UserStatusChangedCacheTime = 7 * 24 * time.Hour
UserTokenCacheKey = "answer:user:token:" UserTokenCacheKey = "answer:user:token:"
UserTokenCacheTime = 7 * 24 * time.Hour UserTokenCacheTime = 7 * 24 * time.Hour
AdminTokenCacheKey = "answer:admin:token:" AdminTokenCacheKey = "answer:admin:token:"
AdminTokenCacheTime = 7 * 24 * time.Hour AdminTokenCacheTime = 7 * 24 * time.Hour
UserTokenMappingCacheKey = "answer:user-token:mapping:" UserTokenMappingCacheKey = "answer:user-token:mapping:"
SiteInfoCacheKey = "answer:site-info:" SiteInfoCacheKey = "answer:site-info:"
SiteInfoCacheTime = 1 * time.Hour SiteInfoCacheTime = 1 * time.Hour
ConfigID2KEYCacheKeyPrefix = "answer:config:id:" ConfigID2KEYCacheKeyPrefix = "answer:config:id:"
ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:" ConfigKEY2ContentCacheKeyPrefix = "answer:config:key:"
ConnectorUserExternalInfoCacheKey = "answer:connector:" ConnectorUserExternalInfoCacheKey = "answer:connector:"
ConnectorUserExternalInfoCacheTime = 10 * time.Minute ConnectorUserExternalInfoCacheTime = 10 * time.Minute
SiteMapQuestionCacheKeyPrefix = "answer:sitemap:question:%d" SiteMapQuestionCacheKeyPrefix = "answer:sitemap:question:%d"
SiteMapQuestionCacheTime = time.Hour SiteMapQuestionCacheTime = time.Hour
SitemapMaxSize = 50000 SitemapMaxSize = 50000
NewQuestionNotificationLimitCacheKeyPrefix = "answer:new-question-notification-limit:"
NewQuestionNotificationLimitCacheTime = 7 * 24 * time.Hour
NewQuestionNotificationLimitMax = 50
) )

View File

@ -71,7 +71,7 @@ var migrations = []Migration{
NewMigration("v1.1.0-beta.2", "update question post time", updateQuestionPostTime, true), NewMigration("v1.1.0-beta.2", "update question post time", updateQuestionPostTime, true),
NewMigration("v1.1.0", "add gravatar base url", updateCount, true), NewMigration("v1.1.0", "add gravatar base url", updateCount, true),
NewMigration("v1.1.1", "update the length of revision content", updateTheLengthOfRevisionContent, false), NewMigration("v1.1.1", "update the length of revision content", updateTheLengthOfRevisionContent, false),
NewMigration("v1.1.2", "add notification config", addNoticeConfig, false), NewMigration("v1.1.2", "add notification config", addNoticeConfig, true),
} }
func GetMigrations() []Migration { func GetMigrations() []Migration {

View File

@ -31,10 +31,10 @@ func (ar *authRepo) GetUserCacheInfo(ctx context.Context, accessToken string) (u
if err != nil { if err != nil {
return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() return nil, errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
} }
userInfo = &entity.UserCacheInfo{}
if !exist { if !exist {
return nil, nil return nil, nil
} }
userInfo = &entity.UserCacheInfo{}
_ = json.Unmarshal([]byte(userInfoCache), userInfo) _ = json.Unmarshal([]byte(userInfoCache), userInfo)
return userInfo, nil return userInfo, nil
} }

View File

@ -50,10 +50,11 @@ func (cr *captchaRepo) GetActionType(ctx context.Context, unit, actionType strin
if err != nil { if err != nil {
return nil, err return nil, err
} }
actionInfo = &entity.ActionRecordInfo{} if !exist {
if exist { return nil, nil
_ = json.Unmarshal([]byte(res), actionInfo)
} }
actionInfo = &entity.ActionRecordInfo{}
_ = json.Unmarshal([]byte(res), actionInfo)
return actionInfo, nil return actionInfo, nil
} }

View File

@ -53,6 +53,7 @@ func (sr *siteInfoRepo) GetByType(ctx context.Context, siteType string) (siteInf
exist, err = sr.data.DB.Context(ctx).Where(builder.Eq{"type": siteType}).Get(siteInfo) exist, err = sr.data.DB.Context(ctx).Where(builder.Eq{"type": siteType}).Get(siteInfo)
if err != nil { if err != nil {
err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack() err = errors.InternalServer(reason.DatabaseError).WithError(err).WithStack()
return nil, false, err
} }
if exist { if exist {
sr.setCache(ctx, siteType, siteInfo) sr.setCache(ctx, siteType, siteInfo)
@ -65,10 +66,11 @@ func (sr *siteInfoRepo) getCache(ctx context.Context, siteType string) (siteInfo
if err != nil { if err != nil {
return nil return nil
} }
siteInfo = &entity.SiteInfo{} if !exist {
if exist { return nil
_ = json.Unmarshal([]byte(siteInfoCache), siteInfo)
} }
siteInfo = &entity.SiteInfo{}
_ = json.Unmarshal([]byte(siteInfoCache), siteInfo)
return siteInfo return siteInfo
} }

View File

@ -89,9 +89,10 @@ func (ur *userExternalLoginRepo) GetCacheUserExternalLoginInfo(
if err != nil { if err != nil {
return info, err return info, err
} }
info = &schema.ExternalLoginUserInfoCache{} if !exist {
if exist { return nil, nil
_ = json.Unmarshal([]byte(res), &info)
} }
info = &schema.ExternalLoginUserInfoCache{}
_ = json.Unmarshal([]byte(res), &info)
return info, nil return info, nil
} }

View File

@ -111,17 +111,20 @@ func (cs *CaptchaService) ActionRecordVerifyCaptcha(
} }
func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) (int, error) { func (cs *CaptchaService) ActionRecordAdd(ctx context.Context, actionType string, unit string) (int, error) {
var err error info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType)
info, cahceErr := cs.captchaRepo.GetActionType(ctx, unit, actionType) if err != nil {
if cahceErr != nil {
log.Error(err) log.Error(err)
return 0, err
} }
info.Num++ amount := 1
err = cs.captchaRepo.SetActionType(ctx, unit, actionType, "", info.Num) if info != nil {
amount = info.Num + 1
}
err = cs.captchaRepo.SetActionType(ctx, unit, actionType, "", amount)
if err != nil { if err != nil {
return 0, err return 0, err
} }
return info.Num, nil return amount, nil
} }
func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, unit string) { func (cs *CaptchaService) ActionRecordDel(ctx context.Context, actionType string, unit string) {

View File

@ -2,6 +2,7 @@ package action
import ( import (
"context" "context"
"github.com/segmentfault/pacman/log"
"time" "time"
"github.com/answerdev/answer/internal/entity" "github.com/answerdev/answer/internal/entity"
@ -13,8 +14,14 @@ import (
func (cs *CaptchaService) ValidationStrategy(ctx context.Context, unit, actionType string) bool { func (cs *CaptchaService) ValidationStrategy(ctx context.Context, unit, actionType string) bool {
info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType) info, err := cs.captchaRepo.GetActionType(ctx, unit, actionType)
if err != nil { if err != nil {
//No record, no processing log.Error(err)
// return false
}
if info == nil {
info = &entity.ActionRecordInfo{
LastTime: time.Now().Unix(),
Num: 1,
}
} }
switch actionType { switch actionType {
case entity.CaptchaActionEmail: case entity.CaptchaActionEmail:

View File

@ -70,8 +70,8 @@ type DashboardService interface {
} }
func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardInfo, error) { func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardInfo, error) {
dashboardInfo, err := ds.getFromCache(ctx) dashboardInfo := ds.getFromCache(ctx)
if err != nil { if dashboardInfo == nil {
dashboardInfo = &schema.DashboardInfo{} dashboardInfo = &schema.DashboardInfo{}
dashboardInfo.QuestionCount = ds.questionCount(ctx) dashboardInfo.QuestionCount = ds.questionCount(ctx)
dashboardInfo.AnswerCount = ds.answerCount(ctx) dashboardInfo.AnswerCount = ds.answerCount(ctx)
@ -95,19 +95,20 @@ func (ds *dashboardService) Statistical(ctx context.Context) (*schema.DashboardI
return dashboardInfo, nil return dashboardInfo, nil
} }
func (ds *dashboardService) getFromCache(ctx context.Context) (dashboardInfo *schema.DashboardInfo, err error) { func (ds *dashboardService) getFromCache(ctx context.Context) (dashboardInfo *schema.DashboardInfo) {
infoStr, exist, err := ds.data.Cache.GetString(ctx, schema.DashboardCacheKey) infoStr, exist, err := ds.data.Cache.GetString(ctx, schema.DashboardCacheKey)
if err != nil { if err != nil {
return nil, err log.Errorf("get dashboard statistical from cache failed: %s", err)
return nil
}
if !exist {
return nil
} }
dashboardInfo = &schema.DashboardInfo{} dashboardInfo = &schema.DashboardInfo{}
if !exist {
return dashboardInfo, nil
}
if err = json.Unmarshal([]byte(infoStr), dashboardInfo); err != nil { if err = json.Unmarshal([]byte(infoStr), dashboardInfo); err != nil {
return nil, err return nil
} }
return dashboardInfo, nil return dashboardInfo
} }
func (ds *dashboardService) setCache(ctx context.Context, info *schema.DashboardInfo) { func (ds *dashboardService) setCache(ctx context.Context, info *schema.DashboardInfo) {

View File

@ -22,6 +22,7 @@ type ExternalNotificationService struct {
} }
func NewExternalNotificationService( func NewExternalNotificationService(
data *data.Data,
userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo, userNotificationConfigRepo user_notification_config.UserNotificationConfigRepo,
followRepo activity_common.FollowRepo, followRepo activity_common.FollowRepo,
emailService *export.EmailService, emailService *export.EmailService,
@ -29,6 +30,7 @@ func NewExternalNotificationService(
notificationQueueService notice_queue.ExternalNotificationQueueService, notificationQueueService notice_queue.ExternalNotificationQueueService,
) *ExternalNotificationService { ) *ExternalNotificationService {
n := &ExternalNotificationService{ n := &ExternalNotificationService{
data: data,
userNotificationConfigRepo: userNotificationConfigRepo, userNotificationConfigRepo: userNotificationConfigRepo,
followRepo: followRepo, followRepo: followRepo,
emailService: emailService, emailService: emailService,

View File

@ -105,7 +105,24 @@ func (ns *ExternalNotificationService) getNewQuestionSubscribers(ctx context.Con
} }
func (ns *ExternalNotificationService) checkSendNewQuestionNotificationEmailLimit(ctx context.Context, userID string) bool { func (ns *ExternalNotificationService) checkSendNewQuestionNotificationEmailLimit(ctx context.Context, userID string) bool {
// TODO: check if reach send limit key := constant.NewQuestionNotificationLimitCacheKeyPrefix + userID
old, exist, err := ns.data.Cache.GetInt64(ctx, key)
if err != nil {
log.Error(err)
return false
}
if exist && old >= constant.NewQuestionNotificationLimitMax {
log.Debugf("%s user reach new question notification limit", userID)
return true
}
if !exist {
err = ns.data.Cache.SetInt64(ctx, key, 1, constant.NewQuestionNotificationLimitCacheTime)
} else {
_, err = ns.data.Cache.Increase(ctx, key, 1)
}
if err != nil {
log.Error(err)
}
return false return false
} }

View File

@ -252,7 +252,7 @@ func (us *UserExternalLoginService) ExternalLoginBindingUserSendEmail(
} }
resp = &schema.ExternalLoginBindingUserSendEmailResp{} resp = &schema.ExternalLoginBindingUserSendEmailResp{}
externalLoginInfo, err := us.userExternalLoginRepo.GetCacheUserExternalLoginInfo(ctx, req.BindingKey) externalLoginInfo, err := us.userExternalLoginRepo.GetCacheUserExternalLoginInfo(ctx, req.BindingKey)
if err != nil || len(externalLoginInfo.ExternalID) == 0 { if err != nil || externalLoginInfo == nil {
return nil, errors.BadRequest(reason.UserNotFound) return nil, errors.BadRequest(reason.UserNotFound)
} }
if len(externalLoginInfo.Email) > 0 { if len(externalLoginInfo.Email) > 0 {
@ -308,7 +308,7 @@ func (us *UserExternalLoginService) ExternalLoginBindingUserSendEmail(
func (us *UserExternalLoginService) ExternalLoginBindingUser( func (us *UserExternalLoginService) ExternalLoginBindingUser(
ctx context.Context, bindingKey string, oldUserInfo *entity.User) (err error) { ctx context.Context, bindingKey string, oldUserInfo *entity.User) (err error) {
externalLoginInfo, err := us.userExternalLoginRepo.GetCacheUserExternalLoginInfo(ctx, bindingKey) externalLoginInfo, err := us.userExternalLoginRepo.GetCacheUserExternalLoginInfo(ctx, bindingKey)
if err != nil || len(externalLoginInfo.ExternalID) == 0 { if err != nil || externalLoginInfo == nil {
return errors.BadRequest(reason.UserNotFound) return errors.BadRequest(reason.UserNotFound)
} }
return us.bindOldUser(ctx, externalLoginInfo, oldUserInfo) return us.bindOldUser(ctx, externalLoginInfo, oldUserInfo)