1增加接码过期时间
This commit is contained in:
@ -23,9 +23,13 @@ type SmsPhone struct {
|
|||||||
Code string `json:"code" gorm:"type:varchar(10);comment:验证码"`
|
Code string `json:"code" gorm:"type:varchar(10);comment:验证码"`
|
||||||
Status int `json:"status" gorm:"type:tinyint;comment:状态 1-等待验证码 2-已获取"`
|
Status int `json:"status" gorm:"type:tinyint;comment:状态 1-等待验证码 2-已获取"`
|
||||||
ExpireTime *time.Time `json:"expireTime" gorm:"type:datetime;comment:过期时间"`
|
ExpireTime *time.Time `json:"expireTime" gorm:"type:datetime;comment:过期时间"`
|
||||||
|
StartTime *time.Time `json:"startTime" gorm:"type:datetime;comment:开始时间"`
|
||||||
|
EndTime *time.Time `json:"endTime" gorm:"type:datetime;comment:结束时间 单次接码结束时间"`
|
||||||
Actived int `json:"actived" gorm:"type:tinyint;comment:是否激活(长期租赁如果第一次没接收到验证码 则不会激活号码) 1-未激活 2-已激活 3-已失效"`
|
Actived int `json:"actived" gorm:"type:tinyint;comment:是否激活(长期租赁如果第一次没接收到验证码 则不会激活号码) 1-未激活 2-已激活 3-已失效"`
|
||||||
Price decimal.Decimal `json:"price" gorm:"type:decimal(10,2);comment:价格"`
|
Price decimal.Decimal `json:"price" gorm:"type:decimal(10,2);comment:价格"`
|
||||||
AutoRenewal int `json:"autoRenewal" gorm:"type:tinyint;comment:是否自动续费 1-自动续费 2-手动续费"`
|
AutoRenewal int `json:"autoRenewal" gorm:"type:tinyint;comment:是否自动续费 1-自动续费 2-手动续费"`
|
||||||
|
Remark string `json:"remark" gorm:"type:varchar(255);comment:备注"`
|
||||||
|
PlatformName string `json:"platformName" gorm:"-"`
|
||||||
models.ModelTime
|
models.ModelTime
|
||||||
models.ControlBy
|
models.ControlBy
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ type SmsReceiveLog struct {
|
|||||||
UserId int `json:"userId" gorm:"type:bigint;comment:用户id"`
|
UserId int `json:"userId" gorm:"type:bigint;comment:用户id"`
|
||||||
Service string `json:"service" gorm:"type:varchar(30);comment:服务"`
|
Service string `json:"service" gorm:"type:varchar(30);comment:服务"`
|
||||||
ServiceCode string `json:"serviceCode" gorm:"type:varchar(30);comment:服务code"`
|
ServiceCode string `json:"serviceCode" gorm:"type:varchar(30);comment:服务code"`
|
||||||
MessageId int `json:"messageId" gorm:"type:int;comment:短信id"`
|
MessageId string `json:"messageId" gorm:"type:int;comment:短信id"`
|
||||||
Phone string `json:"phone" gorm:"type:varchar(30);comment:号码"`
|
Phone string `json:"phone" gorm:"type:varchar(30);comment:号码"`
|
||||||
Code string `json:"code" gorm:"type:varchar(20);comment:验证码"`
|
Code string `json:"code" gorm:"type:varchar(20);comment:验证码"`
|
||||||
Status int `json:"status" gorm:"type:tinyint;comment:状态 0-等待验证码 1-成功 2-失败"`
|
Status int `json:"status" gorm:"type:tinyint;comment:状态 0-等待验证码 1-成功 2-失败"`
|
||||||
|
|||||||
@ -152,6 +152,8 @@ type WeakUpReq struct {
|
|||||||
type WeakUpResp struct {
|
type WeakUpResp struct {
|
||||||
ActivationId string `json:"activationId" comment:"激活id"`
|
ActivationId string `json:"activationId" comment:"激活id"`
|
||||||
MessageId string `json:"messageId" commment:"消息id"`
|
MessageId string `json:"messageId" commment:"消息id"`
|
||||||
|
StartTime *time.Time `json:"startTime" comment:"接码开始时间"`
|
||||||
|
EndTime *time.Time `json:"endTime" comment:"接码过期时间"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WeakUpReq) Validate() error {
|
func (s *WeakUpReq) Validate() error {
|
||||||
@ -192,6 +194,9 @@ type SmsPhoneCleanMyPhoneReq struct {
|
|||||||
type SmsPhoneGetPhoneResp struct {
|
type SmsPhoneGetPhoneResp struct {
|
||||||
Phone string `json:"phone"`
|
Phone string `json:"phone"`
|
||||||
EndAt *time.Time `json:"endTime"`
|
EndAt *time.Time `json:"endTime"`
|
||||||
|
StartTime *time.Time `json:"-" comment:"唤醒后单次接码开始时间"`
|
||||||
|
EndTime *time.Time `json:"-" comment:"唤醒后单次接码过期时间"`
|
||||||
|
MessageId string `json:"-" comment:"消息id"`
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +213,8 @@ type OpenGetNumberResp struct {
|
|||||||
Number string `json:"number"`
|
Number string `json:"number"`
|
||||||
ActivationId string `json:"activationId"`
|
ActivationId string `json:"activationId"`
|
||||||
ExpireTime *time.Time `json:"expireTime"`
|
ExpireTime *time.Time `json:"expireTime"`
|
||||||
|
StartTime *time.Time `json:"startTime"`
|
||||||
|
EndTime *time.Time `json:"endTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OpenWakeUpReq struct {
|
type OpenWakeUpReq struct {
|
||||||
|
|||||||
@ -212,3 +212,13 @@ type TextVerifiedSmsItemResp struct {
|
|||||||
ParsedCode string `json:"parsedCode"`
|
ParsedCode string `json:"parsedCode"`
|
||||||
Encrypted bool `json:"encrypted"`
|
Encrypted bool `json:"encrypted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TextVerifiedGetNumbersResp struct {
|
||||||
|
HasNext bool `json:"hasNext" comment:"是否有下一页"`
|
||||||
|
Links TextVerifiedGetNumbersLinksResp `json:"links"`
|
||||||
|
Data []VerificationDTO `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TextVerifiedGetNumbersLinksResp struct {
|
||||||
|
Next *TextVerifiedResp `json:"next"`
|
||||||
|
}
|
||||||
|
|||||||
@ -115,7 +115,7 @@ func (e MemberRecharge) CustomRecharge(req *dto.MemberRechargeCustomRechargeReq,
|
|||||||
return errors.New("server error")
|
return errors.New("server error")
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheExpireDuration := time.Duration(orderExpireTime+1) * time.Minute
|
cacheExpireDuration := time.Duration(orderExpireTime+10) * time.Minute
|
||||||
key := fmt.Sprintf("pre_order:%s", amount)
|
key := fmt.Sprintf("pre_order:%s", amount)
|
||||||
err = e.Orm.Transaction(func(tx *gorm.DB) error {
|
err = e.Orm.Transaction(func(tx *gorm.DB) error {
|
||||||
if err1 := tx.Create(&data).Error; err1 != nil {
|
if err1 := tx.Create(&data).Error; err1 != nil {
|
||||||
|
|||||||
@ -36,6 +36,8 @@ func (e SmsPhone) OpenGetNumber(req *dto.GetNumberReq, userId int) (dto.OpenGetN
|
|||||||
resp.ActivationId = smsPhone.NewActivationId
|
resp.ActivationId = smsPhone.NewActivationId
|
||||||
resp.ExpireTime = smsPhone.ExpireTime
|
resp.ExpireTime = smsPhone.ExpireTime
|
||||||
resp.Number = smsPhone.Phone
|
resp.Number = smsPhone.Phone
|
||||||
|
resp.StartTime = smsPhone.StartTime
|
||||||
|
resp.EndTime = smsPhone.EndTime
|
||||||
|
|
||||||
return resp, statuscode.Success
|
return resp, statuscode.Success
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ func (e *SmsPhone) CancelNumber(req *dto.SmsPhoneCancelNumberReq, userId int) in
|
|||||||
|
|
||||||
if code == statuscode.Success {
|
if code == statuscode.Success {
|
||||||
err := e.Orm.Transaction(func(tx *gorm.DB) error {
|
err := e.Orm.Transaction(func(tx *gorm.DB) error {
|
||||||
if err1 := e.Orm.Model(data).Updates(map[string]interface{}{"status": 3, "code": "", "actived": "3", "auto_renewal": 2}).Error; err1 != nil {
|
if err1 := e.Orm.Model(data).Updates(map[string]interface{}{"status": 3, "code": "", "actived": "3", "auto_renewal": 2, "deleted_at": time.Now()}).Error; err1 != nil {
|
||||||
e.Log.Errorf("更新短信号码失败, %s", err1)
|
e.Log.Errorf("更新短信号码失败, %s", err1)
|
||||||
return err1
|
return err1
|
||||||
}
|
}
|
||||||
@ -143,21 +145,27 @@ func (e *SmsPhone) WeakUp(req *dto.WeakUpReq, userId int, defult bool) (dto.Weak
|
|||||||
}
|
}
|
||||||
|
|
||||||
if smsPhone.Status != 1 || defult {
|
if smsPhone.Status != 1 || defult {
|
||||||
newActivationId, messageId, code := e.WeakUpManage(&smsPhone)
|
newActivationId, messageId, startTime, endTime, code := e.WeakUpManage(&smsPhone)
|
||||||
|
|
||||||
if code == statuscode.ServerError {
|
if code == statuscode.ServerError {
|
||||||
return result, code
|
return result, code
|
||||||
} else if code == statuscode.Success {
|
} else if code == statuscode.Success {
|
||||||
if err := e.Orm.Model(smsPhone).Updates(map[string]interface{}{"new_activation_id": newActivationId, "status": 1, "code": "", "message_id": messageId}).Error; err != nil {
|
if err := e.Orm.Model(smsPhone).
|
||||||
|
Updates(map[string]interface{}{
|
||||||
|
"new_activation_id": newActivationId, "status": 1, "code": "",
|
||||||
|
"message_id": messageId, "start_time": startTime, "end_time": endTime}).Error; err != nil {
|
||||||
e.Log.Errorf("更新短信号码失败, %s", err)
|
e.Log.Errorf("更新短信号码失败, %s", err)
|
||||||
return result, statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
result.ActivationId = newActivationId
|
result.ActivationId = newActivationId
|
||||||
result.MessageId = messageId
|
result.MessageId = messageId
|
||||||
|
result.StartTime = startTime
|
||||||
|
result.EndTime = endTime
|
||||||
} else if code == statuscode.SmsLongNumWaitCode {
|
} else if code == statuscode.SmsLongNumWaitCode {
|
||||||
e.Log.Info("无须唤醒")
|
if err := e.Orm.Model(smsPhone).
|
||||||
if err := e.Orm.Model(smsPhone).Updates(map[string]interface{}{"status": 1, "code": ""}).Error; err != nil {
|
Updates(map[string]interface{}{"status": 1, "code": "", "start_time": startTime, "end_time": endTime}).
|
||||||
|
Error; err != nil {
|
||||||
e.Log.Errorf("更新短信号码失败, %s", err)
|
e.Log.Errorf("更新短信号码失败, %s", err)
|
||||||
return result, statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
@ -171,18 +179,18 @@ func (e *SmsPhone) WeakUp(req *dto.WeakUpReq, userId int, defult bool) (dto.Weak
|
|||||||
|
|
||||||
// 唤醒号码
|
// 唤醒号码
|
||||||
// returns newActivationId,messageId, code
|
// returns newActivationId,messageId, code
|
||||||
func (e *SmsPhone) WeakUpManage(req *models.SmsPhone) (string, string, int) {
|
func (e *SmsPhone) WeakUpManage(req *models.SmsPhone) (string, string, *time.Time, *time.Time, int) {
|
||||||
switch req.PlatformCode {
|
switch req.PlatformCode {
|
||||||
case global.SmsPlatformDaisysms:
|
case global.SmsPlatformDaisysms:
|
||||||
service := SmsDaisysms{Service: e.Service}
|
service := SmsDaisysms{Service: e.Service}
|
||||||
id, code := service.getExtraActivation(req.ActivationId)
|
id, code := service.getExtraActivation(req.ActivationId)
|
||||||
return strconv.Itoa(id), "", code
|
return strconv.Itoa(id), "", nil, nil, code
|
||||||
case global.SmsPlatformTextVerified:
|
case global.SmsPlatformTextVerified:
|
||||||
service := SmsTextVerified{Service: e.Service}
|
service := SmsTextVerified{Service: e.Service}
|
||||||
|
resp, code := service.getExtraActivation(req.NewActivationId)
|
||||||
return service.getExtraActivation(req.NewActivationId)
|
return resp.ReservationId, resp.Id, resp.UsageWindowStart, resp.UsageWindowEnd, code
|
||||||
default:
|
default:
|
||||||
return "", "", statuscode.SmsPlatformUnavailable
|
return "", "", nil, nil, statuscode.SmsPlatformUnavailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +209,17 @@ func (e *SmsPhone) GetMyPage(req *dto.SmsPhoneGetPageReq, userId int, phone *[]m
|
|||||||
return statuscode.ServerError
|
return statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dictService := SysDictData{}
|
||||||
|
dictService.Orm = e.Orm
|
||||||
|
dictService.Log = e.Log
|
||||||
|
dictDatas, _ := dictService.GetMapByType("sms_platform")
|
||||||
|
|
||||||
|
for index := range *phone {
|
||||||
|
if dict, ok := dictDatas[(*phone)[index].PlatformCode]; ok {
|
||||||
|
(*phone)[index].PlatformName = dict.DictLabel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return statuscode.Success
|
return statuscode.Success
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +300,7 @@ func (e *SmsPhone) DoGetNumber(balanceService *MemberBalance, req *dto.GetNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
activationId, phone, code, expireTime := e.GetNumberManage(req.PlatformCode, req.Type, req.ServiceCode, price, req.Period)
|
activationId, phone, code, expireTime, startTime, endTime := e.GetNumberManage(req.PlatformCode, req.Type, req.ServiceCode, price, req.Period)
|
||||||
|
|
||||||
if code != statuscode.Success {
|
if code != statuscode.Success {
|
||||||
return decimal.Decimal{}, models.SmsPhone{}, code
|
return decimal.Decimal{}, models.SmsPhone{}, code
|
||||||
@ -299,6 +318,8 @@ func (e *SmsPhone) DoGetNumber(balanceService *MemberBalance, req *dto.GetNumber
|
|||||||
smsPhone.MessageId = activationId
|
smsPhone.MessageId = activationId
|
||||||
smsPhone.NewActivationId = activationId
|
smsPhone.NewActivationId = activationId
|
||||||
smsPhone.Actived = 1
|
smsPhone.Actived = 1
|
||||||
|
smsPhone.StartTime = startTime
|
||||||
|
smsPhone.EndTime = endTime
|
||||||
|
|
||||||
smsPhone.Price = price
|
smsPhone.Price = price
|
||||||
if req.Type == 1 {
|
if req.Type == 1 {
|
||||||
@ -310,6 +331,10 @@ func (e *SmsPhone) DoGetNumber(balanceService *MemberBalance, req *dto.GetNumber
|
|||||||
smsPhone.ExpireTime = &now
|
smsPhone.ExpireTime = &now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//平台不允许取消
|
||||||
|
if req.PlatformCode == global.SmsPlatformTextVerified {
|
||||||
|
smsPhone.Actived = 2
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if expireTime != nil {
|
if expireTime != nil {
|
||||||
smsPhone.ExpireTime = expireTime
|
smsPhone.ExpireTime = expireTime
|
||||||
@ -355,24 +380,30 @@ func (e *SmsPhone) DoGetNumber(balanceService *MemberBalance, req *dto.GetNumber
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 租赁号码
|
// 租赁号码
|
||||||
func (e *SmsPhone) GetNumberManage(platformCode string, typ int, serviceCode string, price decimal.Decimal, period int) (string, string, int, *time.Time) {
|
// return activationId 激活id
|
||||||
|
// phone 号码
|
||||||
|
// code 状态码
|
||||||
|
// *expirateTime 号码过期时间
|
||||||
|
// *startTime 长效号码单次接码开始使用(textverified有用)
|
||||||
|
// *endTime 长效号码单次接码过期时间(textverified有用)
|
||||||
|
func (e *SmsPhone) GetNumberManage(platformCode string, typ int, serviceCode string, price decimal.Decimal, period int) (string, string, int, *time.Time, *time.Time, *time.Time) {
|
||||||
switch platformCode {
|
switch platformCode {
|
||||||
case global.SmsPlatformDaisysms:
|
case global.SmsPlatformDaisysms:
|
||||||
service := SmsDaisysms{Service: e.Service}
|
service := SmsDaisysms{Service: e.Service}
|
||||||
activationId, phone, code := service.GetNumberForApi(typ, serviceCode, price, period)
|
activationId, phone, code := service.GetNumberForApi(typ, serviceCode, price, period)
|
||||||
|
|
||||||
return strconv.Itoa(activationId), phone, code, nil
|
return strconv.Itoa(activationId), phone, code, nil, nil, nil
|
||||||
case global.SmsPlatformTextVerified:
|
case global.SmsPlatformTextVerified:
|
||||||
service := SmsTextVerified{Service: e.Service}
|
service := SmsTextVerified{Service: e.Service}
|
||||||
resp, code := service.GetNumberForApi(typ, serviceCode, price, period)
|
resp, code := service.GetNumberAndWakeUp(typ, serviceCode, price, period)
|
||||||
|
|
||||||
if code != statuscode.Success {
|
if code != statuscode.Success {
|
||||||
return "", "", code, nil
|
return "", "", code, nil, resp.StartTime, resp.EndTime
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.Id, resp.Phone, code, resp.EndAt
|
return resp.Id, resp.Phone, code, resp.EndAt, resp.StartTime, resp.EndTime
|
||||||
default:
|
default:
|
||||||
return "", "", statuscode.SmsPlatformUnavailable, nil
|
return "", "", statuscode.SmsPlatformUnavailable, nil, nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,11 +447,17 @@ func (e *SmsPhone) SyncCodes() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range phones {
|
for _, item := range phones {
|
||||||
code, codeStatus := e.GetCodeManage(item.PlatformCode, item.NewActivationId, item.Type, item.UpdatedAt.Unix())
|
code, codeStatus := e.GetCodeManage(item.PlatformCode, item.NewActivationId,
|
||||||
|
item.Type, item.UserId, item.Service, item.ServiceCode)
|
||||||
|
|
||||||
if code == "" {
|
if code == "" {
|
||||||
expireTime := item.UpdatedAt.Add(time.Second * 150)
|
var expireTime time.Time
|
||||||
if item.PlatformCode == global.SmsPlatformTextVerified && expireTime.Before(time.Now()) {
|
|
||||||
|
if item.EndTime != nil {
|
||||||
|
expireTime = *item.EndTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Status == 3 && item.Actived == 2) || (item.PlatformCode == global.SmsPlatformTextVerified && expireTime.Before(time.Now())) {
|
||||||
if err := e.Orm.Model(&item).Updates(map[string]interface{}{"status": 3, "updated_at": time.Now()}).Error; err != nil {
|
if err := e.Orm.Model(&item).Updates(map[string]interface{}{"status": 3, "updated_at": time.Now()}).Error; err != nil {
|
||||||
e.Log.Errorf("手机号一睡眠 %s", item.Phone)
|
e.Log.Errorf("手机号一睡眠 %s", item.Phone)
|
||||||
}
|
}
|
||||||
@ -473,7 +510,7 @@ func (e *SmsPhone) SyncCodes() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取验证码
|
// 获取验证码
|
||||||
func (e *SmsPhone) GetCodeManage(platformCode string, messageId string, typ int, unixTime int64) (string, int) {
|
func (e *SmsPhone) GetCodeManage(platformCode string, messageId string, typ int, userId int, smsService, serviceCode string) (string, int) {
|
||||||
switch platformCode {
|
switch platformCode {
|
||||||
case global.SmsPlatformDaisysms:
|
case global.SmsPlatformDaisysms:
|
||||||
service := SmsDaisysms{Service: e.Service}
|
service := SmsDaisysms{Service: e.Service}
|
||||||
@ -481,98 +518,224 @@ func (e *SmsPhone) GetCodeManage(platformCode string, messageId string, typ int,
|
|||||||
return service.GetCodeForApi(messageId)
|
return service.GetCodeForApi(messageId)
|
||||||
case global.SmsPlatformTextVerified:
|
case global.SmsPlatformTextVerified:
|
||||||
service := SmsTextVerified{Service: e.Service}
|
service := SmsTextVerified{Service: e.Service}
|
||||||
return service.GetCode(messageId, typ, unixTime)
|
return service.GetCode(messageId, typ, userId, smsService, serviceCode)
|
||||||
default:
|
default:
|
||||||
return "", statuscode.SmsPlatformUnavailable
|
return "", statuscode.SmsPlatformUnavailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动续期
|
// AutoRenewal 自动续期处理
|
||||||
func (e SmsServices) AutoRenewal() error {
|
// 处理即将到期的长期号码自动续费逻辑
|
||||||
var datas []models.SmsPhone
|
func (e *SmsPhone) AutoRenewal() error {
|
||||||
var data models.SmsPhone
|
// 获取24小时内到期的自动续费号码
|
||||||
startTime := time.Now().Add(-24 * time.Hour)
|
expiredPhones, err := e.getExpiredPhones()
|
||||||
endTime := time.Now().Add(24 * time.Hour)
|
if err != nil {
|
||||||
|
|
||||||
smsServices := SmsServices{Service: e.Service}
|
|
||||||
serviceMap := smsServices.GetMapAll()
|
|
||||||
|
|
||||||
configService := SysConfig{Service: e.Service}
|
|
||||||
mapDatas, _ := configService.GetMapByKeys([]string{"renew_number_premium_daisysms", "renew_number_premium_textverified"})
|
|
||||||
|
|
||||||
if err := e.Orm.Model(&models.SmsPhone{}).Where("auto_renewal =1 and type =1 and actived =2 and expire_time >=? and expire_time <?", startTime, endTime).Find(&datas).Error; err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range datas {
|
// 获取服务配置映射
|
||||||
percent := decimal.NewFromInt(1)
|
serviceMap, premiumMap, err := e.getRenewalConfigs()
|
||||||
price := decimal.Zero
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if service, ok := serviceMap[item.PlatformCode+"_"+item.ServiceCode]; !ok {
|
// 处理每个到期号码
|
||||||
|
for _, phone := range expiredPhones {
|
||||||
|
if err := e.processPhoneRenewal(phone, serviceMap, premiumMap); err != nil {
|
||||||
|
e.Log.Errorf("处理号码续费失败 [PhoneID: %d]: %v", phone.Id, err)
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
price = service.LongPrice
|
|
||||||
switch {
|
|
||||||
case item.PlatformCode == global.SmsPlatformDaisysms:
|
|
||||||
p, ok := mapDatas["renew_number_premium_daisysms"]
|
|
||||||
val, _ := decimal.NewFromString(p.ConfigValue)
|
|
||||||
|
|
||||||
if ok && val.Cmp(decimal.Zero) > 0 {
|
|
||||||
per := decimal.NewFromInt(100).Add(val)
|
|
||||||
percent = per.Div(decimal.NewFromInt(100)).Truncate(2)
|
|
||||||
}
|
|
||||||
case item.PlatformCode == global.SmsPlatformTextVerified:
|
|
||||||
p, ok := mapDatas["renew_number_premium_textverified"]
|
|
||||||
val, _ := decimal.NewFromString(p.ConfigValue)
|
|
||||||
|
|
||||||
if ok && val.Cmp(decimal.Zero) > 0 {
|
|
||||||
per := decimal.NewFromInt(100).Add(val)
|
|
||||||
percent = per.Div(decimal.NewFromInt(100)).Truncate(2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
renewLog := models.SmsRenewalLog{}
|
|
||||||
renewLog.UserId = item.UserId
|
|
||||||
renewLog.PhoneId = item.Id
|
|
||||||
renewLog.Type = item.Type
|
|
||||||
renewLog.Amount = price.Mul(percent).Truncate(2)
|
|
||||||
renewLog.BeforeTime = *item.ExpireTime
|
|
||||||
renewLog.Period = 30
|
|
||||||
|
|
||||||
if err := e.Orm.Transaction(func(tx *gorm.DB) error {
|
|
||||||
db := tx.Exec("UPDATE member_balance set balance = balance - ? where user_id = ? and balance >= ?", price, item.UserId, price)
|
|
||||||
|
|
||||||
if db.Error != nil {
|
|
||||||
return db.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
if db.RowsAffected == 0 {
|
|
||||||
return errors.New("余额不足")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err1 := tx.Create(&renewLog).Error; err1 != nil {
|
|
||||||
|
|
||||||
return errors.New("创建续费日志失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
newExpireTime := item.ExpireTime.AddDate(0, 0, 30)
|
|
||||||
if err1 := tx.Model(data).Where("id =?", item.Id).Update("expire_time", newExpireTime).Error; err1 != nil {
|
|
||||||
return err1
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
e.Log.Errorf("自动续期失败:%s", err.Error())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getExpiredPhones 获取即将到期的自动续费号码
|
||||||
|
func (e *SmsPhone) getExpiredPhones() ([]models.SmsPhone, error) {
|
||||||
|
var phones []models.SmsPhone
|
||||||
|
startTime := time.Now().Add(-24 * time.Hour)
|
||||||
|
endTime := time.Now().Add(24 * time.Hour)
|
||||||
|
|
||||||
|
err := e.Orm.Model(&models.SmsPhone{}).
|
||||||
|
Where("auto_renewal = 1 AND type = 1 AND actived = 2 AND expire_time >= ? AND expire_time < ?", startTime, endTime).
|
||||||
|
Find(&phones).Error
|
||||||
|
|
||||||
|
return phones, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRenewalConfigs 获取续费相关配置
|
||||||
|
func (e *SmsPhone) getRenewalConfigs() (map[string]models.SmsServices, map[string]dto.GetSysConfigByKEYForServiceResp, error) {
|
||||||
|
smsServices := SmsServices{Service: e.Service}
|
||||||
|
serviceMap := smsServices.GetMapAll()
|
||||||
|
|
||||||
|
configService := SysConfig{Service: e.Service}
|
||||||
|
configKeys := []string{"renew_number_premium_daisysms", "renew_number_premium_textverified"}
|
||||||
|
premiumMap, err := configService.GetMapByKeys(configKeys)
|
||||||
|
|
||||||
|
return serviceMap, premiumMap, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// processPhoneRenewal 处理单个号码的续费
|
||||||
|
func (e *SmsPhone) processPhoneRenewal(phone models.SmsPhone, serviceMap map[string]models.SmsServices, premiumMap map[string]dto.GetSysConfigByKEYForServiceResp) error {
|
||||||
|
// 获取服务价格
|
||||||
|
service, exists := serviceMap[phone.PlatformCode+"_"+phone.ServiceCode]
|
||||||
|
if !exists {
|
||||||
|
return errors.New("服务不存在")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算续费价格
|
||||||
|
renewalPrice := e.calculateRenewalPrice(service.LongPrice, phone.PlatformCode, premiumMap)
|
||||||
|
if renewalPrice.IsZero() {
|
||||||
|
return errors.New("续费价格计算失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建续费日志
|
||||||
|
renewLog := e.createRenewalLog(phone, renewalPrice)
|
||||||
|
|
||||||
|
// 执行续费事务
|
||||||
|
return e.executeRenewalTransaction(phone, renewalPrice, renewLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateRenewalPrice 计算续费价格
|
||||||
|
func (e *SmsPhone) calculateRenewalPrice(basePrice decimal.Decimal, platformCode string, premiumMap map[string]dto.GetSysConfigByKEYForServiceResp) decimal.Decimal {
|
||||||
|
percent := decimal.NewFromInt(1)
|
||||||
|
|
||||||
|
var configKey string
|
||||||
|
switch platformCode {
|
||||||
|
case global.SmsPlatformDaisysms:
|
||||||
|
configKey = "renew_number_premium_daisysms"
|
||||||
|
case global.SmsPlatformTextVerified:
|
||||||
|
configKey = "renew_number_premium_textverified"
|
||||||
|
default:
|
||||||
|
return basePrice
|
||||||
|
}
|
||||||
|
|
||||||
|
if config, exists := premiumMap[configKey]; exists {
|
||||||
|
if val, err := decimal.NewFromString(config.ConfigValue); err == nil && val.Cmp(decimal.Zero) > 0 {
|
||||||
|
percent = decimal.NewFromInt(100).Add(val).Div(decimal.NewFromInt(100))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return basePrice.Mul(percent).Truncate(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// createRenewalLog 创建续费日志
|
||||||
|
func (e *SmsPhone) createRenewalLog(phone models.SmsPhone, amount decimal.Decimal) models.SmsRenewalLog {
|
||||||
|
return models.SmsRenewalLog{
|
||||||
|
UserId: phone.UserId,
|
||||||
|
PhoneId: phone.Id,
|
||||||
|
Type: phone.Type,
|
||||||
|
Amount: amount,
|
||||||
|
BeforeTime: *phone.ExpireTime,
|
||||||
|
Period: 30,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// executeRenewalTransaction 执行续费事务
|
||||||
|
func (e *SmsPhone) executeRenewalTransaction(phone models.SmsPhone, price decimal.Decimal, renewLog models.SmsRenewalLog) error {
|
||||||
|
err := e.Orm.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 扣除余额
|
||||||
|
result := tx.Exec("UPDATE member_balance SET balance = balance - ? WHERE user_id = ? AND balance >= ?", price, phone.UserId, price)
|
||||||
|
if result.Error != nil {
|
||||||
|
return result.Error
|
||||||
|
}
|
||||||
|
if result.RowsAffected == 0 {
|
||||||
|
return errors.New("余额不足")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建续费日志
|
||||||
|
if err := tx.Create(&renewLog).Error; err != nil {
|
||||||
|
return errors.New("创建续费日志失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新到期时间
|
||||||
|
newExpireTime := phone.ExpireTime.AddDate(0, 0, 30)
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"expire_time": newExpireTime,
|
||||||
|
"remark": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Model(&models.SmsPhone{}).Where("id = ?", phone.Id).
|
||||||
|
Updates(params).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err.Error() == "余额不足" {
|
||||||
|
|
||||||
|
return e.handleInsufficientBalance(phone)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleInsufficientBalance 处理余额不足情况
|
||||||
|
func (e *SmsPhone) handleInsufficientBalance(phone models.SmsPhone) error {
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"auto_renewal": 2,
|
||||||
|
"remark": "余额不足,取消自动续费",
|
||||||
|
}
|
||||||
|
// 取消自动续费
|
||||||
|
if err := e.Orm.Model(&models.SmsPhone{}).
|
||||||
|
Where("id = ?", phone.Id).
|
||||||
|
Updates(params).Error; err != nil {
|
||||||
|
e.Log.Errorf("余额不足,取消自动续费失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用平台取消续费接口
|
||||||
|
code := e.ChangeAutoRenewManage(phone.PlatformCode, phone.ActivationId, false)
|
||||||
|
if code != statuscode.Success {
|
||||||
|
params["auto_renewal"] = 1
|
||||||
|
params["remark"] = ""
|
||||||
|
// 如果平台取消失败,恢复自动续费状态
|
||||||
|
if err := e.Orm.Model(&models.SmsPhone{}).
|
||||||
|
Where("id = ?", phone.Id).
|
||||||
|
Updates(params).Error; err != nil {
|
||||||
|
e.Log.Errorf("恢复自动续费状态失败: %v", err)
|
||||||
|
}
|
||||||
|
e.Log.Errorf("平台取消自动续费失败,状态码: %d", code)
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("余额不足")
|
||||||
|
}
|
||||||
|
|
||||||
// ChangeAutoRenew 修改自动续期
|
// ChangeAutoRenew 修改自动续期
|
||||||
func (e *SmsPhone) ChangeAutoRenew(req *dto.SmsPhoneChangeAutoRenewReq, userId int) int {
|
func (e *SmsPhone) ChangeAutoRenew(req *dto.SmsPhoneChangeAutoRenewReq, userId int) int {
|
||||||
var data models.SmsPhone
|
var data models.SmsPhone
|
||||||
|
|
||||||
|
if req.AutoRenew == 1 {
|
||||||
|
smsServices := SmsServices{Service: e.Service}
|
||||||
|
balanceService := MemberBalance{Service: e.Service}
|
||||||
|
balance := balanceService.GetBalance(userId)
|
||||||
|
|
||||||
|
if err := e.Orm.Model(data).Where("id =? or activation_id =?", req.Id, req.ActivationId).First(&data).Error; err != nil {
|
||||||
|
e.Log.Errorf("修改自动续期 数据不存在 id:%d err:%s", req.Id, err.Error())
|
||||||
|
return statuscode.SmsNotExisted
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.ExpireTime.Before(time.Now()) {
|
||||||
|
return statuscode.SmsRentalCantRenew
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceItem, err := smsServices.GetByCode(data.PlatformCode, data.ServiceCode)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("短信服务报错:%v", err)
|
||||||
|
return statuscode.ServerError
|
||||||
|
}
|
||||||
|
configService := SysConfig{Service: e.Service}
|
||||||
|
configKeys := []string{"renew_number_premium_daisysms", "renew_number_premium_textverified"}
|
||||||
|
premiumMap, _ := configService.GetMapByKeys(configKeys)
|
||||||
|
|
||||||
|
price := e.calculateRenewalPrice(serviceItem.LongPrice, serviceItem.PlatformCode, premiumMap)
|
||||||
|
|
||||||
|
if balance.Cmp(price) < 0 {
|
||||||
|
return statuscode.BalanceNotEnough
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if req.Id > 0 {
|
if req.Id > 0 {
|
||||||
if err := e.Orm.Model(data).Where("id =? and user_id =?", req.Id, userId).First(&data).Error; err != nil {
|
if err := e.Orm.Model(data).Where("id =? and user_id =?", req.Id, userId).First(&data).Error; err != nil {
|
||||||
e.Log.Errorf("修改自动续期 数据不存在 id:%d err:%s", req.Id, err.Error())
|
e.Log.Errorf("修改自动续期 数据不存在 id:%d err:%s", req.Id, err.Error())
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/go-admin-team/go-admin-core/sdk/service"
|
"github.com/go-admin-team/go-admin-core/sdk/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -38,7 +39,7 @@ func (e SmsReceiveLog) WebHook(req *dto.SmsReceiveWebHookReq) error {
|
|||||||
UserId: phoneLog.UserId,
|
UserId: phoneLog.UserId,
|
||||||
Service: phoneLog.Service,
|
Service: phoneLog.Service,
|
||||||
ServiceCode: phoneLog.ServiceCode,
|
ServiceCode: phoneLog.ServiceCode,
|
||||||
MessageId: req.MessageID,
|
MessageId: strconv.Itoa(req.MessageID),
|
||||||
Phone: phoneLog.Phone,
|
Phone: phoneLog.Phone,
|
||||||
Code: req.Code,
|
Code: req.Code,
|
||||||
Status: 2,
|
Status: 2,
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func initSetting() *gorm.DB {
|
func initSetting() *gorm.DB {
|
||||||
dsn := "root:123456@tcp(127.0.0.1:3306)/proxy_server?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
dsn := "root:123456@tcp(127.0.0.1:3306)/proxy-server-prod?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||||
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||||
sdk.Runtime.SetDb("default", db)
|
sdk.Runtime.SetDb("default", db)
|
||||||
config.ExtConfig.TrxGridUrl = "https://api.trongrid.io"
|
config.ExtConfig.TrxGridUrl = "https://api.trongrid.io"
|
||||||
|
|||||||
@ -32,7 +32,7 @@ type SmsTextVerified struct {
|
|||||||
// 获取收到的验证码
|
// 获取收到的验证码
|
||||||
// messageId 短效或长效号码的ID
|
// messageId 短效或长效号码的ID
|
||||||
// typ 0-短效 1-长效
|
// typ 0-短效 1-长效
|
||||||
func (e SmsTextVerified) GetCode(messageId string, typ int, unixTime int64) (string, int) {
|
func (e SmsTextVerified) GetCode(messageId string, typ int, userId int, service, serviceCode string) (string, int) {
|
||||||
reservationType := ""
|
reservationType := ""
|
||||||
|
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
@ -58,23 +58,84 @@ func (e SmsTextVerified) GetCode(messageId string, typ int, unixTime int64) (str
|
|||||||
return "", statuscode.ServerError
|
return "", statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
messageIds := []string{}
|
||||||
|
|
||||||
if len(resp.Data) > 0 {
|
if len(resp.Data) > 0 {
|
||||||
for _, v := range resp.Data {
|
for _, v := range resp.Data {
|
||||||
// 2. 解析时间字符串
|
messageIds = append(messageIds, v.Id)
|
||||||
// time.RFC3339Nano 是一个预定义的格式常量,
|
}
|
||||||
// 它能够解析包含纳秒和时区信息的 ISO 8601 字符串。
|
|
||||||
t, err := time.Parse(time.RFC3339Nano, v.CreatedAt)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("时间解析失败:", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 将解析后的 time.Time 对象转换为 Unix 时间戳
|
if len(messageIds) > 0 {
|
||||||
// t.Unix() 返回以秒为单位的整数时间戳
|
receiveLogs := make([]models.SmsReceiveLog, 0)
|
||||||
unixTimestamp := t.Unix()
|
receiveMaps := make(map[string]string, 0)
|
||||||
|
|
||||||
if unixTimestamp >= unixTime {
|
if err := e.Orm.Model(&models.SmsReceiveLog{}).
|
||||||
parsedCode = v.ParsedCode
|
Where("message_id in ?", messageIds).
|
||||||
break
|
Select("message_id").
|
||||||
|
Find(&receiveLogs).Error; err != nil {
|
||||||
|
e.Log.Errorf("获取短信接收记录失败, error: %v", err)
|
||||||
|
return "", statuscode.ServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range receiveLogs {
|
||||||
|
receiveMaps[v.MessageId] = v.MessageId
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找最新验证码并存储所有新验证码
|
||||||
|
var latestSms *dto.TextVerifiedSmsItemResp
|
||||||
|
var latestTime time.Time
|
||||||
|
var newSmsData []dto.TextVerifiedSmsItemResp
|
||||||
|
|
||||||
|
// 遍历所有验证码数据
|
||||||
|
for _, v := range resp.Data {
|
||||||
|
// 解析时间字符串
|
||||||
|
t, err := time.Parse(time.RFC3339Nano, v.CreatedAt)
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("时间解析失败: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否为新验证码(数据库中不存在)
|
||||||
|
if _, ok := receiveMaps[v.Id]; !ok {
|
||||||
|
newSmsData = append(newSmsData, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择最新的验证码(包括已存在的)
|
||||||
|
if latestSms == nil || t.After(latestTime) {
|
||||||
|
latestSms = &v
|
||||||
|
latestTime = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量保存所有新验证码到数据库
|
||||||
|
if len(newSmsData) > 0 {
|
||||||
|
var receiveLogs []models.SmsReceiveLog
|
||||||
|
for _, sms := range newSmsData {
|
||||||
|
receiveLog := models.SmsReceiveLog{
|
||||||
|
UserId: userId,
|
||||||
|
Service: service,
|
||||||
|
ServiceCode: serviceCode,
|
||||||
|
MessageId: sms.Id,
|
||||||
|
Phone: "1" + sms.To,
|
||||||
|
Code: sms.ParsedCode,
|
||||||
|
Status: 2,
|
||||||
|
}
|
||||||
|
receiveLogs = append(receiveLogs, receiveLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量插入数据库
|
||||||
|
if err := e.Orm.Create(&receiveLogs).Error; err != nil {
|
||||||
|
e.Log.Errorf("批量创建短信接收记录失败, error: %v", err)
|
||||||
|
return "", statuscode.ServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Log.Infof("成功存储 %d 条新验证码记录", len(newSmsData))
|
||||||
|
|
||||||
|
// 返回最新的验证码
|
||||||
|
if latestSms != nil {
|
||||||
|
parsedCode = latestSms.ParsedCode
|
||||||
|
e.Log.Infof("返回最新验证码: %s, messageId: %s, 时间: %s", parsedCode, latestSms.Id, latestSms.CreatedAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +158,7 @@ const (
|
|||||||
renewRental = "/api/pub/v2/reservations/rental/renewable/%s/renew" //长效续期
|
renewRental = "/api/pub/v2/reservations/rental/renewable/%s/renew" //长效续期
|
||||||
updateRentalRenewStatus = "/api/pub/v2/reservations/rental/renewable/%s" // 更改续租状态
|
updateRentalRenewStatus = "/api/pub/v2/reservations/rental/renewable/%s" // 更改续租状态
|
||||||
getSmsCode = "/api/pub/v2/sms?reservationId=%s&reservationType=%s" //获取短信验证码
|
getSmsCode = "/api/pub/v2/sms?reservationId=%s&reservationType=%s" //获取短信验证码
|
||||||
|
getNumbers = "/api/pub/v2/reservations/rental/renewable" //获取长效号码列表 Get
|
||||||
)
|
)
|
||||||
|
|
||||||
var idPattern = regexp.MustCompile(`^[a-zA-Z0-9_]{28}$`)
|
var idPattern = regexp.MustCompile(`^[a-zA-Z0-9_]{28}$`)
|
||||||
@ -284,12 +346,33 @@ func (e *SmsTextVerified) SyncPrices() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取号码并唤醒
|
||||||
|
func (e *SmsTextVerified) GetNumberAndWakeUp(tye int, serviceCode string, price decimal.Decimal, period int) (dto.SmsPhoneGetPhoneResp, int) {
|
||||||
|
resp, code := e.GetNumberForApi(tye, serviceCode, price, period)
|
||||||
|
|
||||||
|
if code != statuscode.Success {
|
||||||
|
return resp, code
|
||||||
|
}
|
||||||
|
|
||||||
|
wakeUpResp, code := e.getExtraActivation(resp.Id)
|
||||||
|
|
||||||
|
if code != statuscode.Success {
|
||||||
|
return resp, code
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.MessageId = wakeUpResp.Id
|
||||||
|
resp.StartTime = wakeUpResp.UsageWindowStart
|
||||||
|
resp.EndTime = wakeUpResp.UsageWindowEnd
|
||||||
|
|
||||||
|
return resp, code
|
||||||
|
}
|
||||||
|
|
||||||
// 号码租赁
|
// 号码租赁
|
||||||
// getType 0-短效 1-长效
|
// getType 0-短效 1-长效
|
||||||
// service 服务code
|
// service 服务code
|
||||||
// maxPrice 最大价格
|
// maxPrice 最大价格
|
||||||
// period 时长(月=30天)
|
// period 时长(月=30天)
|
||||||
func (e SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price decimal.Decimal, period int) (dto.SmsPhoneGetPhoneResp, int) {
|
func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price decimal.Decimal, period int) (dto.SmsPhoneGetPhoneResp, int) {
|
||||||
//这个平台的所有号码都是美国号码 默认国家代码都是 +1
|
//这个平台的所有号码都是美国号码 默认国家代码都是 +1
|
||||||
var err error
|
var err error
|
||||||
var createResp dto.TextVerifiedResp
|
var createResp dto.TextVerifiedResp
|
||||||
@ -477,12 +560,13 @@ func (e *SmsTextVerified) GetRentalDetail(id string) (dto.VerificationRentalDeta
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 唤醒号码
|
// 唤醒号码
|
||||||
// returns activationId,messageId, code
|
// returns activationId,messageId,startTime(可用开始时间),endTime(可用结束时间), code,
|
||||||
func (e SmsTextVerified) getExtraActivation(id string) (string, string, int) {
|
func (e SmsTextVerified) getExtraActivation(id string) (dto.TextVerifiedWakeUpResp, int) {
|
||||||
client, code := e.GetTextVerifiedAuthClient()
|
client, code := e.GetTextVerifiedAuthClient()
|
||||||
|
result := dto.TextVerifiedWakeUpResp{}
|
||||||
|
|
||||||
if code != statuscode.Success {
|
if code != statuscode.Success {
|
||||||
return "", "", code
|
return result, code
|
||||||
}
|
}
|
||||||
|
|
||||||
req := dto.TextVerifiedWakeUpReq{
|
req := dto.TextVerifiedWakeUpReq{
|
||||||
@ -497,31 +581,35 @@ func (e SmsTextVerified) getExtraActivation(id string) (string, string, int) {
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
||||||
return "", "", statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
} else if status == http.StatusCreated || status == http.StatusOK {
|
} else if status == http.StatusCreated || status == http.StatusOK {
|
||||||
if resp.Method != "" && resp.Href != "" {
|
if resp.Method != "" && resp.Href != "" {
|
||||||
bytes, err := e.doRequest(&resp)
|
bytes, err := e.doRequest(&resp)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
||||||
return "", "", statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
detailResp := dto.TextVerifiedWakeUpResp{}
|
detailResp := dto.TextVerifiedWakeUpResp{}
|
||||||
|
|
||||||
if err := sonic.Unmarshal(bytes, &detailResp); err != nil {
|
if err := sonic.Unmarshal(bytes, &detailResp); err != nil {
|
||||||
e.Log.Errorf("唤醒号码反序列化失败 id:%s error: %v", id, err)
|
e.Log.Errorf("唤醒号码反序列化失败 id:%s error: %v", id, err)
|
||||||
return "", "", statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
return detailResp.ReservationId, detailResp.Id, statuscode.Success
|
result.Id = detailResp.Id
|
||||||
|
result.ReservationId = detailResp.ReservationId
|
||||||
|
result.UsageWindowEnd = detailResp.UsageWindowEnd
|
||||||
|
result.UsageWindowStart = detailResp.UsageWindowStart
|
||||||
|
return result, statuscode.Success
|
||||||
} else {
|
} else {
|
||||||
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
e.Log.Errorf("唤醒号码失败 id:%s error: %v", id, err)
|
||||||
return "", "", statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", "", statuscode.ServerError
|
return result, statuscode.ServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取价格
|
// 获取价格
|
||||||
@ -826,7 +914,121 @@ func (e *SmsTextVerified) Renew(activationId string, status bool) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重新初始化短信记录
|
||||||
|
func (e *SmsTextVerified) InitSmsLogs() error {
|
||||||
|
// phones, err := e.GetNumbers()
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// e.Log.Errorf("获取长效号码列表失败 %v", err)
|
||||||
|
// return fmt.Errorf("获取长效号码列表失败 %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// numbers := make([]string, 0)
|
||||||
|
|
||||||
|
// for _, v := range phones {
|
||||||
|
// numbers = append(numbers, v.Number)
|
||||||
|
// }
|
||||||
|
|
||||||
|
phoneLogs, err := e.GetUserByNumber("textverified")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("获取系统内号码记录失败 %v", err)
|
||||||
|
return fmt.Errorf("获取系统内号码记录失败 %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(phoneLogs) > 0 {
|
||||||
|
for _, v := range phoneLogs {
|
||||||
|
e.GetCode(v.ActivationId, v.Type, v.UserId, v.Service, v.ServiceCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据电话号码获取系统内记录
|
||||||
|
func (e *SmsTextVerified) GetUserByNumber(platformCode string) ([]models.SmsPhone, error) {
|
||||||
|
var result []models.SmsPhone
|
||||||
|
|
||||||
|
if err := e.Orm.Model(&models.SmsPhone{}).Where("platform_code = ?", platformCode).Find(&result).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取号码
|
||||||
|
func (e *SmsTextVerified) GetNumbers() ([]dto.VerificationDTO, error) {
|
||||||
|
client, code := e.GetTextVerifiedAuthClient()
|
||||||
|
result := make([]dto.VerificationDTO, 0)
|
||||||
|
|
||||||
|
if code != statuscode.Success {
|
||||||
|
e.Log.Errorf("获取长效号码列表失败 %d", code)
|
||||||
|
return result, fmt.Errorf("获取长效号码列表失败 %d", code)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := dto.TextVerifiedGetNumbersResp{}
|
||||||
|
statusCode, err := client.Get(getNumbers, map[string]string{}, resp)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("获取长效号码列表失败 %v", err)
|
||||||
|
return result, fmt.Errorf("获取长效号码列表失败 %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusCode == http.StatusOK {
|
||||||
|
// 添加第一页数据
|
||||||
|
result = append(result, resp.Data...)
|
||||||
|
|
||||||
|
// 处理分页数据
|
||||||
|
if resp.HasNext {
|
||||||
|
paginatedData, err := e.fetchPaginatedData(resp.Links.Next)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
result = append(result, paginatedData...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
} else if statusCode == http.StatusUnauthorized {
|
||||||
|
return e.GetNumbers()
|
||||||
|
} else {
|
||||||
|
e.Log.Errorf("获取长效号码列表失败 %d", statusCode)
|
||||||
|
return result, fmt.Errorf("获取长效号码列表失败 %d", statusCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取授权header头
|
// 获取授权header头
|
||||||
|
// fetchPaginatedData 获取分页数据的通用方法
|
||||||
|
// 处理TextVerified API的分页响应,自动获取所有页面的数据
|
||||||
|
func (e *SmsTextVerified) fetchPaginatedData(nextLink *dto.TextVerifiedResp) ([]dto.VerificationDTO, error) {
|
||||||
|
var result []dto.VerificationDTO
|
||||||
|
|
||||||
|
for nextLink != nil {
|
||||||
|
nextData, err := e.doRequest(nextLink)
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("获取分页数据失败: %v", err)
|
||||||
|
return result, fmt.Errorf("获取分页数据失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nextResp := dto.TextVerifiedGetNumbersResp{}
|
||||||
|
err = sonic.Unmarshal(nextData, &nextResp)
|
||||||
|
if err != nil {
|
||||||
|
e.Log.Errorf("解析分页数据失败: %v", err)
|
||||||
|
return result, fmt.Errorf("解析分页数据失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result = append(result, nextResp.Data...)
|
||||||
|
|
||||||
|
// 检查是否还有下一页
|
||||||
|
if nextResp.HasNext {
|
||||||
|
nextLink = nextResp.Links.Next
|
||||||
|
} else {
|
||||||
|
nextLink = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *SmsTextVerified) GetAuthHeader() (map[string]string, error) {
|
func (e *SmsTextVerified) GetAuthHeader() (map[string]string, error) {
|
||||||
token, err := e.GetToken()
|
token, err := e.GetToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -51,3 +51,18 @@ func TestSyncTextVerifiedServices(t *testing.T) {
|
|||||||
t.Log("SyncTextVerifiedServices succeeded")
|
t.Log("SyncTextVerifiedServices succeeded")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInitSmsLogs(t *testing.T) {
|
||||||
|
db := initSetting()
|
||||||
|
|
||||||
|
s := SmsTextVerified{}
|
||||||
|
s.Orm = db
|
||||||
|
s.Log = logger.NewHelper(logger.DefaultLogger)
|
||||||
|
|
||||||
|
err := s.InitSmsLogs()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("InitSmsLogs failed: %v", err)
|
||||||
|
} else {
|
||||||
|
t.Log("InitSmsLogs succeeded")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -37,11 +37,11 @@ func (j RenewalJob) Exec(args interface{}) error {
|
|||||||
|
|
||||||
// 定时短信续期任务
|
// 定时短信续期任务
|
||||||
func (j SmsRenewalJob) Exec(args interface{}) error {
|
func (j SmsRenewalJob) Exec(args interface{}) error {
|
||||||
smsService := service.SmsServices{}
|
smsPhoneService := service.SmsPhone{}
|
||||||
smsService.Orm = GetDb()
|
smsPhoneService.Orm = GetDb()
|
||||||
smsService.Log = logger.NewHelper(logger.DefaultLogger)
|
smsPhoneService.Log = logger.NewHelper(logger.DefaultLogger)
|
||||||
|
|
||||||
return smsService.AutoRenewal()
|
return smsPhoneService.AutoRenewal()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过期任务
|
// 过期任务
|
||||||
|
|||||||
@ -41,6 +41,7 @@ var StatusCodeZh = map[int]string{
|
|||||||
SmsInvalidType: "短信验证码_无效类型",
|
SmsInvalidType: "短信验证码_无效类型",
|
||||||
SmsOutOfStockOrUnavailable: "短信验证码_缺货或服务不可用",
|
SmsOutOfStockOrUnavailable: "短信验证码_缺货或服务不可用",
|
||||||
SmsRentalRefundNotPermitted: "短信验证码_租赁退款不允许",
|
SmsRentalRefundNotPermitted: "短信验证码_租赁退款不允许",
|
||||||
|
SmsRentalCantRenew: "短信验证码_无法续期",
|
||||||
}
|
}
|
||||||
|
|
||||||
var StatusCodeEn = map[int]string{
|
var StatusCodeEn = map[int]string{
|
||||||
@ -74,6 +75,7 @@ var StatusCodeEn = map[int]string{
|
|||||||
SmsInvalidType: "sms type invalid",
|
SmsInvalidType: "sms type invalid",
|
||||||
SmsOutOfStockOrUnavailable: "sms out of stock or unavailable",
|
SmsOutOfStockOrUnavailable: "sms out of stock or unavailable",
|
||||||
SmsRentalRefundNotPermitted: "sms rental refund not permitted",
|
SmsRentalRefundNotPermitted: "sms rental refund not permitted",
|
||||||
|
SmsRentalCantRenew: "sms rental can not renewal",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMsg 获取状态码对应的消息
|
// GetMsg 获取状态码对应的消息
|
||||||
@ -161,4 +163,6 @@ const (
|
|||||||
SmsOutOfStockOrUnavailable = 20024
|
SmsOutOfStockOrUnavailable = 20024
|
||||||
// 短信-租赁退款不允许
|
// 短信-租赁退款不允许
|
||||||
SmsRentalRefundNotPermitted = 20025
|
SmsRentalRefundNotPermitted = 20025
|
||||||
|
// 短信-无法续期
|
||||||
|
SmsRentalCantRenew = 20026
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user