Files
kami_backend/internal/logic/camel_oil/account_login.go
danial 15e2426e85 feat(camel_oil): 新增骆驼加油账号管理模块
- 实现账号增删改查接口和逻辑
- 支持账号状态更新及状态历史记录功能
- 提供账号列表、历史和统计信息查询API
- 实现账号轮询机制,支持按使用时间轮询获取账号
- 增加账号登录流程及批量登录功能,集成接码平台和平台API
- 管理账号订单容量,支持容量检查与账号登录触发
- 提供账号池状态统计接口
- 账号历史记录查询支持多种变更类型文本展示
- 密码等敏感信息采用脱敏展示
- 完善日志记录和错误处理机制,保证业务稳定运行
2025-11-21 00:49:50 +08:00

137 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package camel_oil
import (
"context"
"fmt"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gtime"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model/do"
"kami/utility/config"
"kami/utility/integration/camel_oil_api"
"kami/utility/integration/pig"
)
// LoginAccount 执行账号登录流程
// 注意:当前使用假数据,实际应对接骆驼加油平台和接码平台
func (s *sCamelOil) LoginAccount(ctx context.Context) (err error) {
// 对接接码平台
phoneNumber, err := pig.NewClient().GetAccountInfo(ctx)
if err != nil {
return gerror.Wrap(err, "获取手机号失败")
}
accountId, err := s.CreateAccount(ctx, phoneNumber, "创建账号")
if err != nil {
return gerror.Wrap(err, "创建账号失败")
}
//发送验证码
isOk, err := camel_oil_api.NewClient().SendCaptcha(ctx, phoneNumber)
if err != nil {
_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusInvalid, consts.CamelOilAccountChangeTypeLoginFail, "获取验证码失败")
return gerror.Wrap(err, "发送验证码失败")
}
if !isOk {
_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusInvalid, consts.CamelOilAccountChangeTypeLoginFail, "获取验证码失败")
return gerror.New("获取验证码失败")
}
// 更新状态为登录中
_, err = dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1CamelOilAccount.Columns().Id, accountId).
Update(do.V1CamelOilAccount{
Status: consts.CamelOilAccountStatusSendCode,
UpdatedAt: gtime.Now(),
})
if err != nil {
_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusInvalid, consts.CamelOilAccountChangeTypeLoginFail, "获取验证码失败")
return gerror.Wrap(err, "更新账号状态为登录中失败")
}
_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusSendCode, consts.CamelOilAccountChangeTypeLogin, "获取验证码失败")
return nil
}
// BatchLoginAccounts 批量登录账号
func (s *sCamelOil) BatchLoginAccounts(ctx context.Context, count int) (successCount int, err error) {
if count <= 0 {
return 0, gerror.New("登录数量必须大于0")
}
// 逐个登录账号
successCount = 0
cycleCount := 0
for {
cycleCount++
if successCount >= count || cycleCount >= 100 {
break
}
loginErr := s.LoginAccount(ctx)
if loginErr != nil {
glog.Errorf(ctx, "账号登录失败ID: %d, 错误: %v", loginErr)
continue
}
successCount += 1
}
glog.Infof(ctx, "批量登录完成,成功: %d", successCount)
return successCount, nil
}
// markAccountInvalid 标记账号为已失效
func (s *sCamelOil) markAccountInvalid(ctx context.Context, accountId int64, reason string) error {
_, err := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1CamelOilAccount.Columns().Id, accountId).
Update(do.V1CamelOilAccount{
Status: consts.CamelOilAccountStatusInvalid,
FailureReason: reason,
UpdatedAt: gtime.Now(),
})
if err != nil {
return gerror.Wrap(err, "标记账号为已失效失败")
}
// 记录失效历史
_ = s.RecordAccountHistory(ctx, accountId, consts.CamelOilAccountChangeTypeInvalidate,
consts.CamelOilAccountStatusSendCode, consts.CamelOilAccountStatusInvalid,
fmt.Sprintf("账号失效: %s", reason))
glog.Warningf(ctx, "账号已标记为失效ID: %d, 原因: %s", accountId, reason)
return nil
}
// CheckAndLoginAccounts 检查容量并登录账号
// 根据当前可用订单容量,决定是否需要登录新账号
func (s *sCamelOil) CheckAndLoginAccounts(ctx context.Context) (err error) {
// 计算当前可用订单容量
capacity, err := s.GetAvailableOrderCapacity(ctx)
if err != nil {
return gerror.Wrap(err, "计算可用容量失败")
}
glog.Infof(ctx, "当前可用订单容量: %d", capacity)
// 容量充足,无需登录
if capacity >= 50 {
glog.Infof(ctx, "当前容量充足 (%d >= 50),无需登录新账号", capacity)
return nil
}
// 计算需要登录的账号数量
needCapacity := 50 - capacity
needAccounts := (needCapacity + 9) / 10 // 向上取整
glog.Infof(ctx, "当前容量不足 (%d < 50),需要登录 %d 个账号", capacity, needAccounts)
// 批量登录账号
successCount, err := s.BatchLoginAccounts(ctx, needAccounts)
if err != nil {
return gerror.Wrap(err, "批量登录账号失败")
}
glog.Infof(ctx, "登录账号完成,成功: %d 个", successCount)
return nil
}
// 注意RecordAccountHistory 方法已在 account.go 中定义,此处不重复定义