- 实现账号增删改查接口和逻辑 - 支持账号状态更新及状态历史记录功能 - 提供账号列表、历史和统计信息查询API - 实现账号轮询机制,支持按使用时间轮询获取账号 - 增加账号登录流程及批量登录功能,集成接码平台和平台API - 管理账号订单容量,支持容量检查与账号登录触发 - 提供账号池状态统计接口 - 账号历史记录查询支持多种变更类型文本展示 - 密码等敏感信息采用脱敏展示 - 完善日志记录和错误处理机制,保证业务稳定运行
129 lines
4.7 KiB
Go
129 lines
4.7 KiB
Go
package card_redeem_account
|
|
|
|
import (
|
|
"context"
|
|
"kami/internal/consts"
|
|
"kami/internal/model"
|
|
"kami/internal/model/entity"
|
|
"kami/internal/service"
|
|
"kami/utility/cache"
|
|
|
|
"github.com/duke-git/lancet/v2/pointer"
|
|
"github.com/duke-git/lancet/v2/slice"
|
|
"github.com/gogf/gf/v2/database/gdb"
|
|
)
|
|
|
|
// GetNextOneSortByAccount 轮换策略,按照充值账户来轮换
|
|
func (a *sCardRedeemAccount) getNextOneSortByAccount(ctx context.Context, category consts.CardRedeemAccountCategory, chargeAmount float64, tx gdb.TX) (output *entity.V1CardRedeemAccountInfo, err error) {
|
|
type storeInfo struct {
|
|
AccountId string
|
|
// 轮询账户的次数
|
|
AccountIndex int
|
|
UserId string
|
|
UserIndex int
|
|
}
|
|
targetAccountIdCache, _ := cache.NewCache().Get(ctx, cache.RedeemAccountTargetIDByCKAndUser.Key(category))
|
|
|
|
currentStoreInfo := storeInfo{}
|
|
if !pointer.IsNil(targetAccountIdCache) && !targetAccountIdCache.IsNil() {
|
|
_ = targetAccountIdCache.Scan(¤tStoreInfo)
|
|
}
|
|
|
|
//获取所有的账号
|
|
accountList, err := a.GetAllAvailableAccount(ctx, category, chargeAmount, tx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
//获取所有的用户
|
|
userList, _ := service.SysUser().GetAllNormalWithPaymentAndChannelCfg(ctx, chargeAmount, tx)
|
|
|
|
//获取当前用户的索引
|
|
currentUser, ok := slice.FindBy(userList, func(index int, item *model.UserSearchWithPaymentAndCfgOutput) bool {
|
|
return item.Id == currentStoreInfo.UserId
|
|
})
|
|
|
|
currentUserIndex := currentStoreInfo.UserIndex % len(userList)
|
|
if ok {
|
|
// 如果当前轮询用户存在,获取当前用户的索引
|
|
currentUserIndex = slice.IndexOf(userList, currentUser)
|
|
} else {
|
|
//如果当前轮询用户不存在,重置轮询账户
|
|
currentStoreInfo.AccountIndex = -1
|
|
}
|
|
|
|
//判断当前的账户是否存在
|
|
isTargetAccountExist := false
|
|
for i := -1; i < len(userList); i++ {
|
|
targetUser := userList[currentUserIndex%len(userList)]
|
|
currentAccountList := slice.Filter(accountList, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
|
|
return item.CreateUserId == targetUser.Id
|
|
})
|
|
// 获取指定账户配置
|
|
currentCfg, ok2 := slice.FindBy(targetUser.ChannelCfg, func(index int, item model.SysUserChannelCfg) bool {
|
|
return item.Name == category.String()
|
|
})
|
|
currentCfgNum := consts.DefaultExchangeConcurrentNum
|
|
if ok2 {
|
|
currentCfgNum = currentCfg.Num
|
|
}
|
|
//取当前用户下指定次数的账户
|
|
if len(currentAccountList) > currentCfgNum {
|
|
currentAccountList = currentAccountList[:currentCfgNum]
|
|
}
|
|
//取当前账户的下一个账户
|
|
if currentStoreInfo.AccountIndex+1 < len(currentAccountList) {
|
|
nextAccount := currentAccountList[(currentStoreInfo.AccountIndex+1)%len(currentAccountList)]
|
|
if service.Rate().Allow(ctx, model.LimiterTypeCardInfoRedeemAccountCookieSet, nextAccount.Id) {
|
|
currentStoreInfo = storeInfo{
|
|
UserId: userList[currentUserIndex%len(userList)].Id,
|
|
UserIndex: currentUserIndex % len(userList),
|
|
AccountIndex: (currentStoreInfo.AccountIndex + 1) % len(currentAccountList),
|
|
AccountId: nextAccount.Id,
|
|
}
|
|
output = nextAccount
|
|
isTargetAccountExist = true
|
|
break
|
|
}
|
|
}
|
|
currentUserIndex++
|
|
currentStoreInfo = storeInfo{
|
|
UserId: userList[currentUserIndex%len(userList)].Id,
|
|
UserIndex: currentUserIndex % len(userList),
|
|
AccountIndex: -1,
|
|
}
|
|
}
|
|
if isTargetAccountExist {
|
|
_ = cache.NewCache().Set(ctx, cache.RedeemAccountTargetIDByCKAndUser.Key(category), currentStoreInfo, 0)
|
|
} else {
|
|
_ = cache.NewCache().Set(ctx, cache.RedeemAccountTargetIDByCKAndUser.Key(category), storeInfo{}, 0)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (a *sCardRedeemAccount) getRandomAccount(ctx context.Context, category consts.CardRedeemAccountCategory, chargeAmount float64, tx gdb.TX) (output *entity.V1CardRedeemAccountInfo, err error) {
|
|
//获取所有的账号
|
|
accountList, err := a.GetAllAvailableAccount(ctx, category, chargeAmount, tx)
|
|
if err != nil {
|
|
return
|
|
}
|
|
//获取所有的用户
|
|
userList, _ := service.SysUser().GetAllNormalWithPaymentAndChannelCfg(ctx, chargeAmount, tx)
|
|
accountList = slice.Filter(accountList, func(index int, item *entity.V1CardRedeemAccountInfo) bool {
|
|
return slice.ContainBy(userList, func(item2 *model.UserSearchWithPaymentAndCfgOutput) bool {
|
|
return item.CreateUserId == item2.Id
|
|
})
|
|
})
|
|
output, _ = slice.Random(accountList)
|
|
return
|
|
}
|
|
|
|
func (a *sCardRedeemAccount) GetAvailableAccount(ctx context.Context, category consts.CardRedeemAccountCategory, chargeAmount float64, tx gdb.TX) (output *entity.V1CardRedeemAccountInfo, err error) {
|
|
strategy, _ := service.SysConfigDict().GetRedeemScheduleStrategy(ctx, category, tx)
|
|
switch strategy {
|
|
case consts.RedeemCardScheduleStrategyTypeRandom:
|
|
return a.getRandomAccount(ctx, category, chargeAmount, tx)
|
|
default:
|
|
return a.getNextOneSortByAccount(ctx, category, chargeAmount, tx)
|
|
}
|
|
}
|