by Robin at 20231230; fix

This commit is contained in:
Leufolium 2023-12-30 19:28:50 +08:00
parent 6b73807a4e
commit b0d29a76db
13 changed files with 208 additions and 16 deletions

View File

@ -23,14 +23,15 @@ const (
// apollo_config
const (
MaxPswdWrongTimesKey = "max_pswd_wrong_times"
MaxVeriCodeValidDurationKey = "max_veri_code_valid_duration"
IosKey = "ios"
AndroidKey = "android"
AccountInitKey = "account_init"
TagNumKey = "tag_num"
PlatformNumKey = "platform_num"
SupportWxIdNumKey = "support_wx_id_num"
MaxPswdWrongTimesKey = "max_pswd_wrong_times"
MaxVeriCodeValidDurationKey = "max_veri_code_valid_duration"
IosKey = "ios"
AndroidKey = "android"
AccountInitKey = "account_init"
TagNumKey = "tag_num"
PlatformNumKey = "platform_num"
SupportWxIdNumKey = "support_wx_id_num"
MaxDailyVeriCodeSendTimesKey = "max_daily_veri_code_send_times"
)
// del_flag

View File

@ -126,6 +126,10 @@ var ErrCodeMsgMap = map[ErrCode]string{
ErrCodeContactCustomerServiceSessionSrvFail: "联系客服对话表服务错误",
ErrCodeContactCustomerServiceSessionNotExist: "联系客服对话表不存在",
ErrCodeVeriCodeSendTimesSrvFail: "验证码频次表服务错误",
ErrCodeVeriCodeSendTimesNotExist: "验证码频次表不存在",
ErrCodeVeriCodeSendTimesReachedDailyUpperbound: "验证码发送次数已达每日上限",
}
const (
@ -300,6 +304,12 @@ const (
ErrCodeContactCustomerServiceSessionSrvFail ErrCode = -24001 // 联系客服对话表服务错误
ErrCodeContactCustomerServiceSessionNotExist ErrCode = -24002 // 联系客服对话表不存在
// VeriCodeSendTimes: 25xxx
ErrCodeVeriCodeSendTimesSrvOk ErrCode = ErrCodeOk
ErrCodeVeriCodeSendTimesSrvFail ErrCode = -25001 // 验证码频次表服务错误
ErrCodeVeriCodeSendTimesNotExist ErrCode = -25002 // 验证码频次表不存在
ErrCodeVeriCodeSendTimesReachedDailyUpperbound ErrCode = -25003 // 验证码发送次数已达每日上限
// Media: 60xxx
ErrCodeMediaSrvOk ErrCode = ErrCodeOk
ErrCodeMediaSrvFail ErrCode = -60001 // 媒体服务错误

View File

@ -15,7 +15,7 @@ func OpSendVeriCode(ctx *gin.Context) {
ec := service.DefaultService.OpSendVeriCode(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("OpSendVeriCode fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrorMsg(ctx, "server error")
ReplyErrCodeMsg(ctx, ec)
return
}

View File

@ -15,7 +15,7 @@ func ApiSendVeriCode(ctx *gin.Context) {
ec := service.DefaultService.ApiSendVeriCode(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("ApiSendVeriCode fail, req: %v, ec: %v", util.ToJson(req), ec)
ReplyErrorMsg(ctx, "server error")
ReplyErrCodeMsg(ctx, ec)
return
}

View File

@ -86,8 +86,9 @@ const (
DBAccount = "account"
COLAccount = "account"
DBVeriCode = "vericode"
COLVeriCode = "vericode"
DBVeriCode = "vericode"
COLVeriCode = "vericode"
COLVeriCodeSendTimes = "vericode_send_times"
DBMoment = "moment"
COLMoment = "moment"
@ -214,6 +215,11 @@ func (m *Mongo) getColVeriCode() *qmgo.Collection {
return m.clientMix.Database(DBVeriCode).Collection(COLVeriCode)
}
// VeriCode频次表
func (m *Mongo) getColVeriCodeSendTimes() *qmgo.Collection {
return m.clientMix.Database(DBVeriCode).Collection(COLVeriCodeSendTimes)
}
// 动态表
func (m *Mongo) getColMoment() *qmgo.Collection {
return m.clientMix.Database(DBMoment).Collection(COLMoment)
@ -1020,6 +1026,32 @@ func (m *Mongo) GetVeriCodeListByPhoneHash(ctx *gin.Context, req *vericodeproto.
return vericode, err
}
// 验证码频次
func (m *Mongo) GetAndUpdateVeriCodeSendTimes(ctx *gin.Context, deviceId string) (veriCodeSendTimes *dbstruct.VeriCodeSendTimes, err error) {
col := m.getColVeriCodeSendTimes()
change := qmgo.Change{
Update: qmgo.M{"$inc": qmgo.M{"send_times": 1}},
Upsert: true,
ReturnNew: false,
}
veriCodeSendTimesInstance := dbstruct.VeriCodeSendTimes{}
if err = col.Find(ctx, qmgo.M{"_id": deviceId}).Apply(change, &veriCodeSendTimesInstance); err != nil {
logger.Error("change error : %v", err)
return
}
return &veriCodeSendTimesInstance, err
}
// 清空验证码频次表
func (m *Mongo) ClearVeriCodeSendTimes(ctx *gin.Context) error {
col := m.getColVeriCodeSendTimes()
_, err := col.RemoveAll(ctx, qmgo.M{})
return err
}
// 动态相关
func (m *Mongo) CreateMoment(ctx *gin.Context, moment *dbstruct.Moment) error {
col := m.getColMoment()

View File

@ -37,7 +37,13 @@ import (
// 发送验证码
func (s *Service) ApiSendVeriCode(ctx *gin.Context, req *vericodeproto.ApiSendReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeResourceSrvOk
ec = errcode.ErrCodeLoginSrvOk
ec = s.ApiSendVeriCodeBusinessValidate(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
return
}
err := _DefaultVeriCode.OpSendVeriCode(ctx, &vericodeproto.OpSendReq{
MobilePhone: req.MobilePhone,
RegionCode: req.RegionCode,

View File

@ -8,6 +8,7 @@ import (
loginproto "service/api/proto/login/proto"
streamerproto "service/api/proto/streamer/proto"
streamerauthapprovalproto "service/api/proto/streamerauthapproval/proto"
vericodeproto "service/api/proto/vericode/proto"
businessvalidator "service/app/mix/service/business_validator"
"service/bizcommon/util"
"service/dbstruct"
@ -18,6 +19,24 @@ import (
"github.com/gin-gonic/gin"
)
// 发送验证码
func (s *Service) ApiSendVeriCodeBusinessValidate(ctx *gin.Context, req *vericodeproto.ApiSendReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk
resultList := businessvalidator.NewLoginBusinessValidator(ctx, req).
QueryVeriCodeSendTimes(_DefaultVeriCodeSendTimes.OpGetAndUpdate, req.Did).
EnsureVeriCodeSendTimesNotReachedDailyUpperbound().
Validate().
Collect()
ec, _ = resultList[0].(errcode.ErrCode)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("ApiSendVeriCodeBusinessValidate business validation failed!")
return
}
return
}
// 密码登录
func (s *Service) ApiLoginByPswdBusinessValidate(ctx *gin.Context, req *loginproto.ApiLoginByPswdReq) (login *dbstruct.Login, account *dbstruct.Account, ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk

View File

@ -25,9 +25,10 @@ type LoginBusinessValidator struct {
passwordAccessor loginproto.PasswordAccessible //访问密码的接口
// 结果
login *dbstruct.Login
account *dbstruct.Account
vericode *dbstruct.VeriCode
login *dbstruct.Login
account *dbstruct.Account
vericode *dbstruct.VeriCode
vericodeSendTimes *dbstruct.VeriCodeSendTimes
}
func NewLoginBusinessValidator(ctx *gin.Context, req any) *LoginBusinessValidator {
@ -242,6 +243,40 @@ func (l *LoginBusinessValidator) EnsureIsOpRole() *LoginBusinessValidator {
return l
}
func (l *LoginBusinessValidator) QueryVeriCodeSendTimes(fun func(*gin.Context, string) (*dbstruct.VeriCodeSendTimes, error), devId string) *LoginBusinessValidator {
l.oplist = append(l.oplist, func() {
vericodeSendTimes, err := fun(l.ctx, devId)
if err != nil {
l.ec = errcode.ErrCodeVeriCodeSendTimesSrvFail
return
}
l.vericodeSendTimes = vericodeSendTimes
})
return l
}
func (l *LoginBusinessValidator) EnsureVeriCodeSendTimesNotReachedDailyUpperbound() *LoginBusinessValidator {
l.oplist = append(l.oplist, func() {
// 读取每日发送上限
maxDailyVeriCodeSendTimes, err := apollo.GetIntValue(consts.MaxDailyVeriCodeSendTimesKey, apollo.ApolloOpts().SetNamespace("application"))
if err != nil {
logger.Error("Apollo read failed : %v", err)
l.ec = errcode.ErrCodeApolloReadFail
return
}
if l.vericodeSendTimes.SendTimes > int64(maxDailyVeriCodeSendTimes) {
logger.Error("the vericode send times of this device has reached its daily upperbound")
l.ec = errcode.ErrCodeVeriCodeSendTimesReachedDailyUpperbound
return
}
})
return l
}
// 执行校验
func (s *LoginBusinessValidator) Validate() *LoginBusinessValidator {
s.BusinessValidateStream.Validate()

View File

@ -30,6 +30,7 @@ func (s *CronService) Run() {
s.ReloadRecommList()
s.ImageAuditBatch()
s.TextAuditBatch()
s.ClearVeriCodeSendTimes()
}
func (s *CronService) ReloadRecommList() {
@ -79,3 +80,18 @@ func (s *CronService) TextAuditBatch() {
})
scheduler.StartAsync()
}
func (s *CronService) ClearVeriCodeSendTimes() {
loc, _ := time.LoadLocation("Asia/Shanghai")
scheduler := gocron.NewScheduler(loc)
scheduler.Every(1).Day().At("00:00").Do(func() {
logger.Info("Clearing vericode_send_times collection...")
ctx := &gin.Context{}
if err := _DefaultVeriCodeSendTimes.OpClear(ctx); err != nil {
logger.Error("Clear vericode_send_times collection fail: %v", err)
}
logger.Info("vericode_send_times collection has been cleared")
})
scheduler.StartAsync()
}

View File

@ -0,0 +1,40 @@
package logic
import (
"service/app/mix/dao"
"service/dbstruct"
"service/library/logger"
"github.com/gin-gonic/gin"
)
type VeriCodeSendTimes struct {
store *dao.Store
}
func NewVeriCodeSendTimes(store *dao.Store) (a *VeriCodeSendTimes) {
a = &VeriCodeSendTimes{
store: store,
}
return
}
func (p *VeriCodeSendTimes) OpGetAndUpdate(ctx *gin.Context, devId string) (*dbstruct.VeriCodeSendTimes, error) {
vericodeSendTimes, err := p.store.GetAndUpdateVeriCodeSendTimes(ctx, devId)
if err != nil {
logger.Error("GetAndUpdateVeriCodeSendTimes fail, err: %v", err)
return nil, err
}
return vericodeSendTimes, nil
}
func (p *VeriCodeSendTimes) OpClear(ctx *gin.Context) error {
err := p.store.ClearVeriCodeSendTimes(ctx)
if err != nil {
logger.Error("ClearVeriCodeSendTimes fail, err: %v", err)
return err
}
return nil
}

View File

@ -16,6 +16,7 @@ import (
streamerlinkproto "service/api/proto/streamerlink/proto"
textaudittaskproto "service/api/proto/textaudittask/proto"
userwxaddcheckproto "service/api/proto/userwxaddcheck/proto"
vericodeproto "service/api/proto/vericode/proto"
businessvalidator "service/app/mix/service/business_validator"
"service/dbstruct"
"service/library/logger"
@ -23,6 +24,24 @@ import (
"github.com/gin-gonic/gin"
)
// 发送验证码
func (s *Service) OpSendVeriCodeBusinessValidate(ctx *gin.Context, req *vericodeproto.OpSendReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk
resultList := businessvalidator.NewLoginBusinessValidator(ctx, req).
QueryVeriCodeSendTimes(_DefaultVeriCodeSendTimes.OpGetAndUpdate, req.Did).
EnsureVeriCodeSendTimesNotReachedDailyUpperbound().
Validate().
Collect()
ec, _ = resultList[0].(errcode.ErrCode)
if ec != errcode.ErrCodeLoginSrvOk {
logger.Error("OpSendVeriCodeBusinessValidate business validation failed!")
return
}
return
}
// 密码登录
func (s *Service) OpLoginByPswdBusinessValidate(ctx *gin.Context, req *loginproto.OpLoginByPswdReq) (login *dbstruct.Login, account *dbstruct.Account, ec errcode.ErrCode) {
ec = errcode.ErrCodeLoginSrvOk

View File

@ -65,6 +65,7 @@ var (
var (
_DefaultToken *logic.Token
_DefaultVeriCode *logic.VeriCode
_DefaultVeriCodeSendTimes *logic.VeriCodeSendTimes
_DefaultAccount *logic.Account
_DefaultProduct *logic.Product
_DefaultCatalog *logic.Catalog
@ -129,6 +130,7 @@ func (s *Service) Init(c any) (err error) {
_DefaultToken = logic.NewToken(store, cfg.Crypto)
_DefaultVeriCode = logic.NewVeriCode(store, cfg.Dysmsapi)
_DefaultVeriCodeSendTimes = logic.NewVeriCodeSendTimes(store)
_DefaultAccount = logic.NewAccount(store)
_DefaultProduct = logic.NewProduct(store)
_DefaultCatalog = logic.NewCatalog(store)
@ -439,6 +441,12 @@ func (s *Service) GetBannerList(ctx *gin.Context) (list []*dbstruct.Banner, ec e
// 发送验证码
func (s *Service) OpSendVeriCode(ctx *gin.Context, req *vericodeproto.OpSendReq) (ec errcode.ErrCode) {
ec = errcode.ErrCodeResourceSrvOk
ec = s.OpSendVeriCodeBusinessValidate(ctx, req)
if ec != errcode.ErrCodeLoginSrvOk {
return
}
err := _DefaultVeriCode.OpSendVeriCode(ctx, req)
if err != nil {
logger.Error("OpSendVeriCode fail, err: %v", err)

View File

@ -0,0 +1,6 @@
package dbstruct
type VeriCodeSendTimes struct {
Id string `json:"id" bson:"_id"` //id,用户的b_did
SendTimes int64 `json:"send_times" bson:"send_times"` //发送次数
}