Files
kami_backend/internal/logic/camel_oil/account_login.go
danial 8495c453f3 feat(camel_oil): 添加骆驼模块设置和预拉取订单日志功能
- 增加骆驼模块设置接口支持获取和更新配置
- 使用Redis缓存设置数据,实现模块配置的持久化管理
- 引入预拉取订单日志功能,支持日志的保存和按时间范围查询
- 预拉取订单请求响应数据记录到Redis,方便问题追踪
- 根据模块设置动态调整账号登录、预拉取订单并发数量
- 调整账号登录逻辑以支持配置的并发控制
- 优化预拉取订单补充流程,支持多面额库存管理
- 修正集成API请求函数名及调用,记录详细调用日志数据
- 调整定时任务调度频率,增加预拉取订单补充任务的执行频率
- 升级golang版本到1.25.5,保持开发环境最新状态
2025-12-03 21:17:56 +08:00

137 lines
3.9 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"
"kami/internal/consts"
"kami/internal/dao"
"kami/internal/model/do"
"kami/utility/config"
"kami/utility/integration/camel_oil_api"
"kami/utility/integration/pig"
"sync"
"sync/atomic"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/glog"
)
// LoginAccount 执行账号登录流程
// 注意:当前使用假数据,实际应对接骆驼加油平台和接码平台
func (s *sCamelOil) LoginAccount(ctx context.Context) (err error) {
// 获取设置
settings, err := GetCamelOilSettings(ctx)
if err != nil {
glog.Errorf(ctx, "获取骆驼模块设置失败: %v", err)
return err
}
// 如果不使用豪猪平台,直接返回错误
if !settings.UseHaozhuPlatform {
return gerror.New("未启用豪猪平台,无法获取手机号")
}
// 对接接码平台,获取手机号并检查是否已存在
var phoneNumber string
ticker := time.NewTicker(time.Second)
for range ticker.C {
phoneNumber, err = pig.NewClient().GetAccountInfo(ctx)
if err != nil {
return gerror.Wrap(err, "从豪猪平台获取手机号失败")
}
// 检查手机号是否已存在
existingAccount, checkErr := dao.V1CamelOilAccount.Ctx(ctx).DB(config.GetDatabaseV1()).
Where(dao.V1CamelOilAccount.Columns().Phone, phoneNumber).
One()
if checkErr != nil {
return gerror.Wrap(checkErr, "检查手机号是否存在失败")
}
// 如果手机号已存在,继续获取新的手机号
if existingAccount == nil {
// 手机号不存在,可以使用
break
}
glog.Infof(ctx, "手机号已存在,重新获取: %s", phoneNumber)
}
isOk, err := camel_oil_api.NewClient().SendCaptcha(ctx, phoneNumber)
if err != nil {
return gerror.Wrap(err, "发送验证码失败")
}
if !isOk {
return gerror.New("获取验证码失败")
}
accountId, err := s.CreateAccount(ctx, phoneNumber, "创建账号")
if err != nil {
return gerror.Wrap(err, "创建账号失败")
}
// 更新状态为登录中
_ = s.UpdateAccountStatus(ctx, accountId, consts.CamelOilAccountStatusSendCode, consts.CamelOilAccountChangeTypeLogin, "获取验证码成功")
return nil
}
// BatchLoginAccounts 批量登录账号
func (s *sCamelOil) BatchLoginAccounts(ctx context.Context, count int64) (successCount int64, err error) {
if count <= 0 {
return 0, gerror.New("登录数量必须大于0")
}
// 获取设置
settings, err := GetCamelOilSettings(ctx)
if err != nil {
glog.Errorf(ctx, "获取骆驼模块设置失败: %v", err)
return 0, err
}
// 使用设置中的并发数量控制登录
semaphore := make(chan struct{}, settings.SingleAccountConcurrency)
var wg sync.WaitGroup
var successCounter int64
for i := 0; i < int(count); i++ {
wg.Add(1)
go func() {
defer wg.Done()
semaphore <- struct{}{} // 获取信号量
defer func() { <-semaphore }() // 释放信号量
loginErr := s.LoginAccount(ctx)
if loginErr != nil {
glog.Errorf(ctx, "账号登录失败,错误: %v", loginErr)
return
}
atomic.AddInt64(&successCounter, 1)
}()
}
wg.Wait()
successCount = successCounter
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,
})
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
}