Compare commits
2 Commits
837900462a
...
da1b37a398
| Author | SHA1 | Date | |
|---|---|---|---|
| da1b37a398 | |||
| 38ec94254b |
@ -29,6 +29,7 @@ type SmsRenewalLog struct {
|
||||
ApiKey string `json:"apiKey" gorm:"->"`
|
||||
BillingCycleId string `json:"billingCycleId" gorm:"->"`
|
||||
ActivationId string `json:"activationId" gorm:"->"`
|
||||
PlatformState string `json:"platformState" gorm:"-"`
|
||||
models.ModelTime
|
||||
models.ControlBy
|
||||
}
|
||||
|
||||
@ -138,15 +138,16 @@ type ManualDeductReq struct {
|
||||
}
|
||||
|
||||
type ManualDeductResp struct {
|
||||
ActivationId string `json:"activationId" comment:"激活id"`
|
||||
TradeOrderNo string `json:"tradeOrderNo" comment:"交易订单号"`
|
||||
PayOrderNo string `json:"payOrderNo" comment:"支付订单号"`
|
||||
BeginTime time.Time `json:"beginTime" comment:"开始时间"`
|
||||
EndTime *time.Time `json:"endTime" comment:"结束时间"`
|
||||
Status int `json:"status" comment:"状态 1-预扣费 2-成功 3-失败"`
|
||||
ActivationId string `json:"activationId" comment:"激活id"`
|
||||
TradeOrderNo string `json:"tradeOrderNo" comment:"交易订单号"`
|
||||
PayOrderNo string `json:"payOrderNo" comment:"支付订单号"`
|
||||
BeginTime time.Time `json:"beginTime" comment:"开始时间"`
|
||||
EndTime *time.Time `json:"endTime" comment:"结束时间"`
|
||||
Status int `json:"status" comment:"状态 1-预扣费 2-成功 3-失败"`
|
||||
PlatformState string `json:"platformState" comment:"平台状态 verificationPending┃verificationCompleted┃verificationCanceled┃verificationTimedOut┃verificationReported┃verificationRefunded┃verificationReused┃verificationReactivated┃renewableActive┃renewableOverdue┃renewableExpired┃renewableRefunded┃nonrenewableActive┃nonrenewableExpired┃nonrenewableRefunded"`
|
||||
}
|
||||
|
||||
// 续费详情
|
||||
type ManualDeductDetailReq struct {
|
||||
TradeOrderNo string `json:"tradeOrderNo" comment:"交易订单号"`
|
||||
TradeOrderNo string `json:"tradeOrderNo" form:"tradeOrderNo" query:"tradeOrderNo" comment:"交易订单号"`
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-admin-team/go-admin-core/sdk/service"
|
||||
@ -712,9 +714,10 @@ func (e *SmsPhone) ChangeAutoRenewManage(platform, apiKey string, activationId s
|
||||
|
||||
return service.ChangeAutoRenewForApi(activationId, status, &apiInfo)
|
||||
case global.SmsPlatformTextVerified:
|
||||
service := SmsTextVerified{Service: e.Service}
|
||||
// service := SmsTextVerified{Service: e.Service}
|
||||
|
||||
return service.Renew(activationId, status, &apiInfo)
|
||||
// return service.Renew(activationId, status, &apiInfo)
|
||||
return statuscode.Success
|
||||
default:
|
||||
return statuscode.SmsPlatformUnavailable
|
||||
}
|
||||
@ -919,3 +922,116 @@ func (e *SmsPhone) syncLoop(nextUrl string, textVerifiedService SmsTextVerified,
|
||||
}
|
||||
return rentalList, nil
|
||||
}
|
||||
func (e *SmsPhone) GetPhoneActualEnd() error {
|
||||
var phones []models.SmsPhone
|
||||
|
||||
// 查询待处理的号码
|
||||
if err := e.Orm.Model(&models.SmsPhone{}).
|
||||
Joins("LEFT JOIN sms_phone_judge AS s ON sms_phone.id = s.phone_id").
|
||||
Where("sms_phone.platform_code = ? AND sms_phone.expire_time > ? AND s.id IS NULL",
|
||||
global.SmsPlatformTextVerified, "2025-11-17").
|
||||
Select("sms_phone.*").
|
||||
Find(&phones).Error; err != nil {
|
||||
e.Log.Errorf("查询手机号码失败 err:%v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(phones) == 0 {
|
||||
return nil
|
||||
}
|
||||
workerCount := 4 // 开 8 个并发 worker
|
||||
e.runWorkerPool(phones, workerCount)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *SmsPhone) runWorkerPool(phones []models.SmsPhone, workerCount int) {
|
||||
phoneChan := make(chan models.SmsPhone, workerCount*2)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(workerCount)
|
||||
|
||||
// 开 worker
|
||||
for i := 0; i < workerCount; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
e.workerProcess(phoneChan)
|
||||
}()
|
||||
}
|
||||
|
||||
// 投递任务
|
||||
for _, p := range phones {
|
||||
phoneChan <- p
|
||||
}
|
||||
close(phoneChan)
|
||||
|
||||
// 等待全部 worker 完成
|
||||
wg.Wait()
|
||||
}
|
||||
func (e *SmsPhone) workerProcess(ch <-chan models.SmsPhone) {
|
||||
service := SmsTextVerified{Service: e.Service}
|
||||
smsPlatformKeyRedis := NewSmsPlatformKeyRedis(e.Orm, e.Log)
|
||||
|
||||
for item := range ch {
|
||||
|
||||
// 获取 API info
|
||||
apiInfo, err := smsPlatformKeyRedis.GetApiInfo(item.PlatformCode, item.ApiKey)
|
||||
if err != nil {
|
||||
e.Log.Errorf("获取短信平台密钥失败 [PlatformCode: %s]: %v", item.PlatformCode, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 获取账单周期
|
||||
cycleInfo, err := service.GetBillingCycle(item.BillingCycleId, &apiInfo)
|
||||
if err != nil {
|
||||
e.Log.Errorf("获取账单周期失败 [Phone: %s]: %v", item.Phone, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 插入判断表
|
||||
if err := e.Orm.Exec(`
|
||||
INSERT INTO sms_phone_judge(phone_id, phone, expire_time, end_time)
|
||||
VALUES(@phone_id, @phone, @expire_time, @endTime)
|
||||
`,
|
||||
sql.Named("phone_id", item.Id),
|
||||
sql.Named("phone", item.Phone),
|
||||
sql.Named("expire_time", item.ExpireTime),
|
||||
sql.Named("endTime", cycleInfo.RenewedThrough),
|
||||
).Error; err != nil {
|
||||
|
||||
e.Log.Errorf("插入 sms_phone_judge 失败 [Phone: %s]: %v", item.Phone, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置为平台手动续费
|
||||
func (e *SmsPhone) SetManualRenewal() error {
|
||||
var phones []models.SmsPhone
|
||||
if err := e.Orm.Model(&models.SmsPhone{}).
|
||||
Where("platform_auto =1 and auto_renewal = 1 and platform_code = ?", global.SmsPlatformTextVerified).
|
||||
Find(&phones).Error; err != nil {
|
||||
e.Log.Errorf("查询手机号码失败 err:%v", err)
|
||||
return err
|
||||
}
|
||||
smsPlatformKeyRedis := NewSmsPlatformKeyRedis(e.Orm, e.Log)
|
||||
for _, item := range phones {
|
||||
apiInfo, err := smsPlatformKeyRedis.GetApiInfo(item.PlatformCode, item.ApiKey)
|
||||
if err != nil {
|
||||
e.Log.Errorf("获取短信平台密钥失败 [PlatformCode: %s]: %v", item.PlatformCode, err)
|
||||
continue
|
||||
}
|
||||
service := SmsTextVerified{Service: e.Service}
|
||||
if err := service.Renew(item.ActivationId, false, &apiInfo); err != statuscode.Success {
|
||||
e.Log.Errorf("设置为平台手动续费失败 [ActivationId: %s]: %v", item.ActivationId, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := e.Orm.Model(&item).
|
||||
Where("activation_id = ?", item.ActivationId).
|
||||
Update("platform_auto", 2).Error; err != nil {
|
||||
e.Log.Errorf("更新手动续费id失败 err:%v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ func TestManualRenewal(t *testing.T) {
|
||||
service := SmsRenewalLog{}
|
||||
service.Orm = db
|
||||
service.Log = logger.NewHelper(logger.DefaultLogger)
|
||||
activationId := "lr_01K5DP71G06SFX84S7W99D61F9"
|
||||
activationId := "lr_01KA8J2AKDN480QE5HGTQGEXEW"
|
||||
|
||||
if _, err := service.ManualDeduct(&dto.ManualDeductReq{
|
||||
ActivationId: activationId,
|
||||
@ -92,3 +92,32 @@ func TestManualRenewal(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPhoneActualEnd(t *testing.T) {
|
||||
db := initSetting()
|
||||
|
||||
service := SmsPhone{}
|
||||
service.Orm = db
|
||||
service.Log = logger.NewHelper(logger.DefaultLogger)
|
||||
|
||||
// if err := service.Orm.Exec("truncate table sms_phone_judge").Error; err != nil {
|
||||
// t.Error(err)
|
||||
// }
|
||||
|
||||
if err := service.GetPhoneActualEnd(); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 测试修改为手动续期
|
||||
func TestSetManualRenewal(t *testing.T) {
|
||||
db := initSetting()
|
||||
|
||||
service := SmsPhone{}
|
||||
service.Orm = db
|
||||
service.Log = logger.NewHelper(logger.DefaultLogger)
|
||||
|
||||
if err := service.SetManualRenewal(); err != nil {
|
||||
t.Fatalf("SetManualRenewal failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func initSetting() *gorm.DB {
|
||||
dsn := "root:123456@tcp(127.0.0.1:3306)/proxy_server_prod?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||
dsn := "root:123456@tcp(127.0.0.1:3306)/proxy_server?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"
|
||||
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
sdk.Runtime.SetDb("default", db)
|
||||
// config.ExtConfig.
|
||||
|
||||
@ -182,6 +182,7 @@ func (e *SmsRenewalLog) ManualDeduct(req *dto.ManualDeductReq, userId int) (dto.
|
||||
result.PayOrderNo = renewLog.PayOrderNo
|
||||
result.BeginTime = req.BeginTime
|
||||
result.EndTime = renewLog.TargetTime
|
||||
result.PlatformState = renewLog.PlatformState
|
||||
}
|
||||
|
||||
return result, statuscode.Success
|
||||
@ -192,6 +193,10 @@ func (e *SmsRenewalLog) GetRenewalDetailByTradeOrderNo(req *dto.ManualDeductDeta
|
||||
var entity models.SmsRenewalLog
|
||||
result := dto.ManualDeductResp{}
|
||||
|
||||
if req.TradeOrderNo == "" {
|
||||
return result, statuscode.InvalidParams
|
||||
}
|
||||
|
||||
if err := e.Orm.Model(entity).
|
||||
Joins("LEFT JOIN sms_phone s on s.id = sms_renewal_log.phone_id").
|
||||
Where("sms_renewal_log.trade_order_no =? and sms_renewal_log.user_id =?", req.TradeOrderNo, userId).
|
||||
@ -206,6 +211,7 @@ func (e *SmsRenewalLog) GetRenewalDetailByTradeOrderNo(req *dto.ManualDeductDeta
|
||||
result.PayOrderNo = entity.PayOrderNo
|
||||
result.BeginTime = entity.BeforeTime
|
||||
result.EndTime = entity.TargetTime
|
||||
result.Status = entity.Status
|
||||
|
||||
return result, statuscode.Success
|
||||
}
|
||||
@ -386,18 +392,20 @@ func (e *SmsPhone) getRenewalConfigs() (map[string]models.SmsServices, map[strin
|
||||
func (e *SmsRenewalLog) processPhoneRenewal(phone models.SmsPhone, serviceMap map[string]models.SmsServices,
|
||||
premiumMap map[string]dto.GetSysConfigByKEYForServiceResp, tradeOrderNo string, admin bool) (models.SmsRenewalLog, error) {
|
||||
var renewLog models.SmsRenewalLog
|
||||
var platformState string
|
||||
smsPlatformKeyRedis := NewSmsPlatformKeyRedis(e.Orm, e.Log)
|
||||
apiInfo, err := smsPlatformKeyRedis.GetApiInfo(phone.PlatformCode, phone.ApiKey)
|
||||
if err != nil {
|
||||
return renewLog, fmt.Errorf("获取短信平台密钥失败 [PlatformCode: %s]: %v", phone.PlatformCode, err)
|
||||
}
|
||||
|
||||
//续期id为空 重新获取
|
||||
if phone.BillingCycleId == "" {
|
||||
switch phone.PlatformCode {
|
||||
case global.SmsPlatformTextVerified:
|
||||
switch phone.PlatformCode {
|
||||
case global.SmsPlatformTextVerified:
|
||||
textVerifiedService := SmsTextVerified{Service: e.Service}
|
||||
|
||||
//续期id为空 重新获取
|
||||
if phone.BillingCycleId == "" {
|
||||
//可以手动续费
|
||||
textVerifiedService := SmsTextVerified{Service: e.Service}
|
||||
detail, code := textVerifiedService.GetRentalDetail(phone.ActivationId, &apiInfo)
|
||||
|
||||
if code != statuscode.Success {
|
||||
@ -406,9 +414,57 @@ func (e *SmsRenewalLog) processPhoneRenewal(phone models.SmsPhone, serviceMap ma
|
||||
}
|
||||
|
||||
phone.BillingCycleId = detail.BillingCycleId
|
||||
case global.SmsPlatformDaisysms:
|
||||
//只有自动续费的 用定时服务查询状态
|
||||
platformState = detail.State
|
||||
} else {
|
||||
var billingCycle dto.VerificationRentalDetailResp
|
||||
|
||||
if err := utility.Retry(4, time.Millisecond*150, func() error {
|
||||
var newErr int
|
||||
billingCycle, newErr = textVerifiedService.GetRentalDetail(phone.ActivationId, &apiInfo)
|
||||
|
||||
if newErr != statuscode.Success {
|
||||
return fmt.Errorf("错误code:%d", newErr)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}); err != nil {
|
||||
logger.Errorf("获取短信验证码续费详情失败 [BillingCycleID: %s]: %v", phone.BillingCycleId, err)
|
||||
return renewLog, fmt.Errorf("获取短信验证码续费详情失败 [BillingCycleID: %s]: %v", phone.BillingCycleId, err)
|
||||
}
|
||||
|
||||
renewLog.ActivationId = billingCycle.ID
|
||||
platformState = billingCycle.State
|
||||
}
|
||||
|
||||
case global.SmsPlatformDaisysms:
|
||||
//只有自动续费的 用定时服务查询状态
|
||||
}
|
||||
|
||||
// 已取消、已过期、已逾期 都视为续费失败
|
||||
if platformState == "renewableRefunded" ||
|
||||
platformState == "renewableExpired" ||
|
||||
platformState == "renewableOverdue" {
|
||||
var remark string
|
||||
if platformState == "renewableRefunded" {
|
||||
remark = "已取消"
|
||||
} else if platformState == "renewableExpired" {
|
||||
remark = "已过期"
|
||||
} else if platformState == "renewableOverdue" {
|
||||
remark = "已逾期"
|
||||
}
|
||||
|
||||
if err := e.Orm.Model(&phone).Where("id =?", phone.Id).
|
||||
Updates(map[string]interface{}{
|
||||
"auto_renewal": 2,
|
||||
"remark": remark,
|
||||
}).Error; err != nil {
|
||||
logger.Errorf("更新短信验证码续费状态失败 [PhoneID: %d]: %v", phone.Id, err)
|
||||
} else {
|
||||
logger.Errorf("短信验证码续费状态为 %s,续费失败", platformState)
|
||||
}
|
||||
|
||||
renewLog.PlatformState = platformState
|
||||
return renewLog, nil
|
||||
}
|
||||
|
||||
// 获取服务价格
|
||||
@ -425,6 +481,7 @@ func (e *SmsRenewalLog) processPhoneRenewal(phone models.SmsPhone, serviceMap ma
|
||||
|
||||
// 创建续费日志
|
||||
renewLog = e.createRenewalLog(phone, renewalPrice, tradeOrderNo)
|
||||
renewLog.PlatformState = platformState
|
||||
|
||||
// 执行续费事务
|
||||
if err := e.executeRenewalTransaction(phone, renewalPrice, &renewLog, &apiInfo, admin); err != nil {
|
||||
@ -521,6 +578,13 @@ func (e *SmsRenewalLog) executeRenewalTransaction(phone models.SmsPhone, price d
|
||||
if code == statuscode.NothingToRenew {
|
||||
if renewCode := textVerifiedService.Renew(phone.ActivationId, true, apiInfo); renewCode == statuscode.Success {
|
||||
code = textVerifiedService.ManualRenewal(phone.BillingCycleId, apiInfo)
|
||||
|
||||
if code == statuscode.Success {
|
||||
//再取消自动续费
|
||||
if renewCode := textVerifiedService.Renew(phone.ActivationId, false, apiInfo); renewCode != statuscode.Success {
|
||||
logger.Errorf("取消自动续费失败 [ActivationID: %s]: %v", phone.ActivationId, renewCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -403,6 +403,7 @@ func (e *SmsTextVerified) GetNumberAndWakeUp(tye int, serviceCode string, price
|
||||
// period 时长(月=30天)
|
||||
func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price decimal.Decimal, period int, apiInfo *dto.SmsPlatformKeyQueueDto) (dto.SmsPhoneGetPhoneResp, int) {
|
||||
//这个平台的所有号码都是美国号码 默认国家代码都是 +1
|
||||
var bytes []byte
|
||||
var err error
|
||||
var createResp dto.TextVerifiedResp
|
||||
var result dto.SmsPhoneGetPhoneResp
|
||||
@ -412,7 +413,7 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
createResp, code = e.CreateVerification(serviceCode, apiInfo)
|
||||
|
||||
if code == statuscode.Success && createResp.Href != "" {
|
||||
bytes, err := e.doRequest(&createResp, apiInfo)
|
||||
bytes, err = e.doRequest(&createResp, apiInfo)
|
||||
|
||||
if err != nil {
|
||||
e.Log.Errorf("短效号码 获取号码失败:%v", e)
|
||||
@ -421,7 +422,7 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
|
||||
resp := dto.VerificationDTO{}
|
||||
|
||||
if err := sonic.Unmarshal(bytes, &resp); err != nil {
|
||||
if err = sonic.Unmarshal(bytes, &resp); err != nil {
|
||||
e.Log.Errorf("短效号码 获取号码失败:%v", e)
|
||||
return result, 0
|
||||
}
|
||||
@ -443,15 +444,28 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
|
||||
if err == nil && createResp.Href != "" {
|
||||
saleId := getIdByUrl(createResp.Href)
|
||||
bytes, err := e.doRequest(&createResp, apiInfo)
|
||||
|
||||
if err != nil {
|
||||
if err = utility.Retry(6, time.Millisecond*150, func() error {
|
||||
newBytes, newErr := e.doRequest(&createResp, apiInfo)
|
||||
|
||||
if newErr != nil {
|
||||
return fmt.Errorf("获取长效号码失败:%v", newErr)
|
||||
}
|
||||
|
||||
bytes = newBytes
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
e.Log.Errorf("通过销售id [%s] 获取号码失败:%v", saleId, err)
|
||||
}
|
||||
|
||||
if len(bytes) == 0 {
|
||||
e.Log.Errorf("获取长效号码失败,没有返回值")
|
||||
return result, statuscode.ServerError
|
||||
}
|
||||
|
||||
resp := dto.SaleResponse{}
|
||||
if err := sonic.Unmarshal(bytes, &resp); err != nil {
|
||||
if err = sonic.Unmarshal(bytes, &resp); err != nil {
|
||||
e.Log.Errorf("反序列化失败:%v", err)
|
||||
|
||||
return result, statuscode.ServerError
|
||||
@ -461,7 +475,7 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
for _, v := range resp.Reservations {
|
||||
if v.ID != "" {
|
||||
result.Id = v.ID
|
||||
continue
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -470,20 +484,36 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
return result, statuscode.ServerError
|
||||
}
|
||||
|
||||
detail, code := e.GetRentalDetail(result.Id, apiInfo)
|
||||
var detail dto.VerificationRentalDetailResp
|
||||
|
||||
if code != statuscode.Success {
|
||||
return result, code
|
||||
//带重试的获取详情
|
||||
if err = utility.Retry(6, time.Millisecond*150, func() error {
|
||||
dDetail, dCode := e.GetRentalDetail(result.Id, apiInfo)
|
||||
|
||||
if dCode != statuscode.Success {
|
||||
return fmt.Errorf("code :%d", dCode)
|
||||
}
|
||||
|
||||
detail = dDetail
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
e.Log.Errorf("获取长效号码失败:%v", err)
|
||||
return result, statuscode.ServerError
|
||||
}
|
||||
|
||||
result.Phone = "1" + detail.Number
|
||||
result.BillingCycleId = detail.BillingCycleId
|
||||
endTime := resp.UpdatedAt.AddDate(0, 0, 30)
|
||||
result.EndAt = &(endTime) // 30天后过期
|
||||
if detail.ID == "" {
|
||||
e.Log.Errorf("获取长效号码失败,没有返回值")
|
||||
return result, statuscode.ServerError
|
||||
} else {
|
||||
result.Phone = "1" + detail.Number
|
||||
result.BillingCycleId = detail.BillingCycleId
|
||||
endTime := resp.UpdatedAt.AddDate(0, 0, 30)
|
||||
result.EndAt = &(endTime) // 30天后过期
|
||||
}
|
||||
|
||||
return result, statuscode.Success
|
||||
}
|
||||
|
||||
} else if err == nil && createResp.Href == "" {
|
||||
e.Log.Errorf("获取长效号码失败,没有返回值")
|
||||
return result, statuscode.ServerError
|
||||
@ -499,10 +529,6 @@ func (e *SmsTextVerified) GetNumberForApi(typ int, serviceCode string, price dec
|
||||
return result, statuscode.SmsPlatformUnavailable
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return result, statuscode.ServerError
|
||||
}
|
||||
|
||||
return result, statuscode.Success
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"go-admin/common/global"
|
||||
"go-admin/common/statuscode"
|
||||
"testing"
|
||||
|
||||
"github.com/go-admin-team/go-admin-core/logger"
|
||||
@ -82,3 +83,100 @@ func TestInitSmsLogs(t *testing.T) {
|
||||
t.Log("InitSmsLogs succeeded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRentalDetail(t *testing.T) {
|
||||
db := initSetting()
|
||||
|
||||
s := SmsTextVerified{}
|
||||
s.Orm = db
|
||||
s.Log = logger.NewHelper(logger.DefaultLogger)
|
||||
ids := []string{
|
||||
"lr_01K5YP0KD77813BGHEVNBHFSV4",
|
||||
"lr_01K7SKT1X3DM8VW4C131KFJKKP",
|
||||
"lr_01K7SRS4JZEWK7K479YG74WSMW",
|
||||
"lr_01K7SSPHC13ZY6DPD8M3X2M47H",
|
||||
"lr_01K7SV8DP7DMBVTH599DA3AE61",
|
||||
"lr_01K7W84KPA3M31KWZ06GXE1YGN",
|
||||
"lr_01K7W8VXEA15GBPXNWQ7EP3MTN",
|
||||
"lr_01K7WBYG9G25VAX7GJQHG8AXV2",
|
||||
"lr_01K7X5ZGRE9YMWGPTA9EEXNY6F",
|
||||
"lr_01K7YG5FVJM03WPRNA8R1RYDHQ",
|
||||
"lr_01K81MR0DJXF4QAQKR03APT1MR",
|
||||
"lr_01K81Q1BZ05EW7VECPB4016CJH",
|
||||
"lr_01K81YRE55T41J8CNT8SYPVRQB",
|
||||
"lr_01K849VP722Q67CTS69WNPF3CV",
|
||||
"lr_01K849W7N74ATK14DFBGPRPFT5",
|
||||
"lr_01K86KYAPFRM776K9H63HC142M",
|
||||
"lr_01K5YP0KD77813BGHEVNBHFSV4",
|
||||
"lr_01K88R5F04HXDM3T7TA6Y101FV",
|
||||
"lr_01K88S2SQ9R0AKM37NX6N9Q3K4",
|
||||
"lr_01K88S3XBP3VWTBCQ51R1NPPXM",
|
||||
"lr_01K88SG5FGYCQSH2K0CDRGGXJV",
|
||||
"lr_01K88SR36PQ20SDCAZT45HZXH6",
|
||||
"lr_01K88SVWPP1AQDYG8MJNEG12WQ",
|
||||
"lr_01K8BM8W13TF487G1QR0N3DPXQ",
|
||||
"lr_01K8BQV5V7HD38NBBMYNQ46ATE",
|
||||
"lr_01K8BR1TAMPNJ2NZ8A5YN4XRP7",
|
||||
"lr_01K8BRB8TX1NTQ8F99Q8VJEWQY",
|
||||
"lr_01K8BSNK4PB5DT4E5BRQP9FT89",
|
||||
"lr_01K8BT9W2HGVJHB09WN5Q8ZAFW",
|
||||
"lr_01K8CKGF1SBPJNHQR11Q8TKG34",
|
||||
"lr_01K8CMMW8EGHD8GZTYARMZ15YC",
|
||||
"lr_01K8E4CVMPMVF61NZ7J0PN92VF",
|
||||
"lr_01K8E6Z10C463TMGZ5WNQE151B",
|
||||
"lr_01K8EJAH4BKTAF6DGSEHWB658S",
|
||||
"lr_01K8EJGRHVJBTCR4FT5QVD01BK",
|
||||
"lr_01K8EPKWZDAW6C9BFKXZJ9ZXXS",
|
||||
"lr_01K8EPMNRY3DKAWNT5AHCQV5FP",
|
||||
"lr_01K8KZMPDE39S2AKKKY215PPQC",
|
||||
"lr_01K8MAPDCNMR2WVR8QKQ1DBN8Z",
|
||||
"lr_01K8RBQJYEGS28AMW57PTKD2RQ",
|
||||
"lr_01K8RPCC5GAQ6YD5WK8P0FVEN6",
|
||||
"lr_01K8RR7F4H4RRZE5TSES6RXD08",
|
||||
"lr_01K8RRQ7WBTY4AC4Q1WP1KAFNN",
|
||||
"lr_01K8S5F3HPHTXV17W68P4M5CK0",
|
||||
"lr_01K8S5G5JV9A69WH4SNM79AEYJ",
|
||||
"lr_01K907JVTN6C9QC17AN97RM8TC",
|
||||
"lr_01K907Z508W78B2PYZZ8E3PWJX",
|
||||
"lr_01K909WET271Z8JEYRKGEJJBXG",
|
||||
"lr_01K90C2V8RQ06914J6VBEV9MV6",
|
||||
"lr_01K90G3WCFB8RS8SWNS73KW189",
|
||||
"lr_01K90PJTX2GRXZMTZ1ZTN7SEEB",
|
||||
"lr_01K92FTF3WJRC3YVYEK62Y0PV2",
|
||||
"lr_01K95G9WHTX8ASMT1N6RVJAW0Z",
|
||||
"lr_01K95GK2762Z6V9WFM43VVMRE8",
|
||||
"lr_01K98WR5PGNYVDYWYK8RMHXM1D",
|
||||
"lr_01K9ANC9ANW2TM54J4EM9TM7H0",
|
||||
"lr_01K9AW71BGJAV6VQP7REC023K4",
|
||||
"lr_01K9B0MA8A7E3KD75DA2JQZ8MA",
|
||||
"lr_01K9B0YX9MBB22XY7NAQHJ6W68",
|
||||
"lr_01K9DABMP1XJP82HHE114B0C5H",
|
||||
"lr_01K9DCY25FRM0V85XRW7QJ5MVQ",
|
||||
"lr_01K9QJD4RQ5DK95WV55PVMWYRK",
|
||||
"lr_01K9SQVZ0QBXAT4MKZG0ZFV8NQ",
|
||||
"lr_01K9TQ9GYP29X2Q7YPN5BH79ZY",
|
||||
"lr_01K9X7ABQZ1QGVXYXMY00PNP4F",
|
||||
"lr_01K9Z50GG4E50CV6X7HFF6H671",
|
||||
"lr_01K9Z5GZEF8Q5Z3TWMFMKT8ME1",
|
||||
"lr_01K9ZBADB7AASXZF0FARN94FAN",
|
||||
"lr_01K9ZBPTVAER3EHC20YJ3BWJBB",
|
||||
"lr_01K9ZC5V6E29R2W798FJTCHQZG",
|
||||
}
|
||||
|
||||
smsPlatformKeyRedis := NewSmsPlatformKeyRedis(s.Orm, s.Log)
|
||||
apiInfo, err := smsPlatformKeyRedis.GetApiInfo(global.SmsPlatformTextVerified, "ZQ0swXnsaPpeGdwa3c7gT9U9I1Oh9WoDHx0amuYovvaHuqd5u6B4NBBUSUBjR")
|
||||
|
||||
if err != nil {
|
||||
s.Log.Errorf("获取API信息失败: %v", err)
|
||||
t.Error("获取API信息失败", err)
|
||||
}
|
||||
|
||||
for _, item := range ids {
|
||||
rentalDetail, errCode := s.GetRentalDetail(item, &apiInfo)
|
||||
if errCode != statuscode.Success {
|
||||
t.Errorf("GetRentalDetail failed: %v", errCode)
|
||||
} else {
|
||||
t.Logf("activationId:%s 状态:%s", rentalDetail.ID, rentalDetail.State)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,16 +10,17 @@ import (
|
||||
// 字典 key 可以配置到 自动任务 调用目标 中;
|
||||
func InitJob() {
|
||||
jobList = map[string]JobExec{
|
||||
"ExamplesOne": ExamplesOne{},
|
||||
"TrxPaymentJob": TrxPaymentJob{},
|
||||
"CliProxyTrafficsJob": CliProxyJob{},
|
||||
"RenewalJob": RenewalJob{}, //长效ip定时续期
|
||||
"ExpireProxyJob": ExpireProxyJob{}, //定时过期代理
|
||||
"CleanExpiredOrderJob": CleanExpiredOrderJob{}, //清理过期订单
|
||||
"SmsJob": SmsJob{}, //短信定时查询验证码
|
||||
"SmsRenewalJob": SmsRenewalJob{}, //短信定时自动续期
|
||||
"AutoDeleteJob": AutoDeleteJob{}, //定时删除任务
|
||||
"SmsPriceJob": SmsPriceJob{}, // 短信价格定时同步
|
||||
"ExamplesOne": ExamplesOne{},
|
||||
"TrxPaymentJob": TrxPaymentJob{},
|
||||
"CliProxyTrafficsJob": CliProxyJob{},
|
||||
"RenewalJob": RenewalJob{}, //长效ip定时续期
|
||||
"ExpireProxyJob": ExpireProxyJob{}, //定时过期代理
|
||||
"CleanExpiredOrderJob": CleanExpiredOrderJob{}, //清理过期订单
|
||||
"SmsJob": SmsJob{}, //短信定时查询验证码
|
||||
"SmsRenewalJob": SmsRenewalJob{}, //短信定时自动续期
|
||||
"AutoDeleteJob": AutoDeleteJob{}, //定时删除任务
|
||||
"SmsPriceJob": SmsPriceJob{}, // 短信价格定时同步
|
||||
"SmsCancelPlatformAuto": SmsCancelPlatformAuto{}, // 短信定时取消自动续期
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
|
||||
type SmsJob struct{}
|
||||
type SmsPriceJob struct{}
|
||||
type SmsCancelPlatformAuto struct{}
|
||||
|
||||
// 定时查询结果
|
||||
func (j SmsJob) Exec(args interface{}) error {
|
||||
@ -31,3 +32,11 @@ func (j SmsPriceJob) Exec(args interface{}) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j SmsCancelPlatformAuto) Exec(args interface{}) error {
|
||||
phoneService := service.SmsPhone{}
|
||||
phoneService.Orm = GetDb()
|
||||
phoneService.Log = logger.NewHelper(logger.DefaultLogger)
|
||||
|
||||
return phoneService.SetManualRenewal()
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ settings:
|
||||
# sqlserver: sqlserver://用户名:密码@地址?database=数据库名
|
||||
driver: mysql
|
||||
# 数据库连接字符串 mysql 缺省信息 charset=utf8&parseTime=True&loc=Local&timeout=1000ms
|
||||
source: root:123456@tcp(127.0.0.1:3306)/proxy_server?charset=utf8&parseTime=True&loc=Local&timeout=1000ms
|
||||
source: root:123456@tcp(127.0.0.1:3306)/proxy_server_prod?charset=utf8&parseTime=True&loc=Local&timeout=1000ms
|
||||
# databases:
|
||||
# 'locaohost:8000':
|
||||
# driver: mysql
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-admin-team/go-admin-core/logger"
|
||||
)
|
||||
@ -42,3 +43,16 @@ func SafeGoParam[T any](fn func(T), param T) {
|
||||
fn(param) // 执行传入的函数
|
||||
}()
|
||||
}
|
||||
|
||||
// Retry 重试执行函数,直到成功或达到最大重试次数
|
||||
func Retry(max int, delay time.Duration, fn func() error) error {
|
||||
var err error
|
||||
for i := 0; i < max; i++ {
|
||||
err = fn()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(delay * time.Duration(i+1))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user